<commit_before>'use strict';

var controllerModule = angular.module('uchiwa.controllers', []);

/**
* Init
*/
controllerModule.controller('init', ['$rootScope', '$scope', 'notification', 'pollingFactory', 'Page', 'uchiwaBackend',
  function ($rootScope, $scope, notification, pollingFactory, Page, uchiwaBackend) {
    $scope.Page = Page;
    $rootScope.skipRefresh = false;
    $rootScope.alerts = [];
    $rootScope.events = [];

    uchiwaBackend.getConfig()
      .success(function (data) {
        pollingFactory.callFnOnInterval(function () { $rootScope.getSensu(); }, data.Uchiwa.Refresh);
      })
      .error(function () {
        pollingFactory.callFnOnInterval(function () { $rootScope.getSensu(); }, 10);
      });

    $rootScope.getSensu = function () {
      if ($rootScope.skipRefresh) {
        $rootScope.skipRefresh = false;
        return;
      }
      uchiwaBackend.getHealth()
        .success(function (data) {
          $rootScope.health = data;
        });
      uchiwaBackend.getSensu()
        .success(function (data) {
          angular.forEach(data, function(value, key) { // initialize null elements
            if (!value || value === null) {
              data[key] = [];
            }
          });
          $rootScope.checks = data.Checks;
          $rootScope.dc = data.Dc;

          $rootScope.clients = _.map(data.Clients, function(client) {
            var existingClient = _.findWhere($rootScope.clients, {name: client.name});
            if (existingClient !== undefined) {
              client = angular.extend(existingClient, client);
            }
            return existingClient || client;
          });

          $rootScope.events = _.map(data.Events, function(event) {
            event._id = event.dc + '/' + event.client.name + '/' + event.check.name;
            var existingEvent = _.findWhere($rootScope.events, {_id: event._id});
            if (existingEvent !== undefined) {
              event = angular.extend(existingEvent, event);
            }
            return existingEvent || event;
          });

          $rootScope.stashes = data.Stashes;
          $rootScope.subscriptions = data.Subscriptions;
          $scope.$broadcast('sensu');

        })
        .error(function (error) {
          notification('error', 'Could not fetch Sensu data. Is Uchiwa running?');
          console.error('Error: '+ JSON.stringify(error));
        });
    };

    $scope.$on('$routeChangeSuccess', function () {
      $rootScope.getSensu();
    });

    $scope.$on('notification', function (type, message) {
      notification(type, message);
    });
  }
]);

/**
* Checks
*/
controllerModule.controller('checks', ['$scope', '$routeParams', 'routingService', 'Page',
  function ($scope, $routeParams, routingService, Page) {
    Page.setTitle('Checks');
    $scope.pageHeaderText = 'Checks';
    $scope.predicate = 'name';

    // Helpers
    $scope.subscribersSummary = function(subscribers){
      return subscribers.join(' ');
    };

    // Routing
    $scope.filters = {};
    routingService.initFilters($routeParams, $scope.filters, ['dc', 'limit', 'q']);
    $scope.$on('$locationChangeSuccess', function(){
      routingService.updateFilters($routeParams, $scope.filters);
    });

    // Services
    $scope.permalink = routingService.permalink;

  }
]);

/**
* Client
*/
controllerModule.controller('client', ['$scope', '$routeParams', 'clientsService', 'notification', 'Page', 'routingService', 'stashesService', 'uchiwaBackend',
  function ($scope, $routeParams, clientsService, notification, Page, routingService, stashesService, uchiwaBackend) {

    $scope.predicate = '-last_status';

    // Retrieve client
    $scope.clientId = decodeURI($routeParams.clientId);
    $scope.dcId = decodeURI($routeParams.dcId);
    $scope.pull = function() {
      uchiwaBackend.getClient($scope.clientId, $scope.dcId)
        .success(function (data) {
          $scope.$emit('client', data);
        })
        .error(function (error) {
          notification('error', 'Could not retrieve the client '+ $scope.clientId +'. Is Sensu API running on '+ $scope.dcId +'?');
          console.error('Error: '+ JSON.stringify(error));
        });
    };

    $scope.pull();
    var timer = setInterval($scope.pull, 10000);

    $scope.$on('client', function (event, data) {
      $scope.client = data;
      $scope.pageHeaderText = $scope.client.name;

      // Retrieve check & event
      $scope.requestedCheck = decodeURI($routeParams.check);
      $scope.selectedCheck = getCheck($scope.requestedCheck, $scope.client.history);
      $scope.selectedEvent = getEvent($scope.client.name, $scope.requestedCheck, $scope.events);

      // Set page title
      if(angular.isDefined($scope.selectedCheck)) {
        Page.setTitle($scope.requestedCheck + ' - ' + $scope.client.name);
      }
      else {
        Page.setTitle($scope.client.name);
      }
    });

    // Routing
    $scope.$on('$routeUpdate', function(){
      // Retrieve check & event
      $scope.requestedCheck = decodeURI($routeParams.check);
      $scope.selectedCheck = getCheck($scope.requestedCheck, $scope.client.history);
      $scope.selectedEvent = getEvent($scope.client.name, $scope.requestedCheck, $scope.events);

      if(angular.isDefined($scope.selectedCheck)) {
        Page.setTitle($scope.requestedCheck + ' - ' + $scope.client.name);
      }
      else {
        Page.setTitle($scope.client.name);
      }
    });

    $scope.$on('$destroy', function() {
      clearInterval(timer);
    });

    // Sanitize - only display useful information 'acknowledged', 'dc', 'events', 'eventsSummary', 'history', 'status', 'timestamp'
    /* jshint ignore:start */
    var clientWhitelist = [ 'acknowledged', 'dc', 'events', 'eventsSummary', 'history', 'output', 'status', 'timestamp' ];
    var checkWhitelist = [ 'dc', 'hasSubscribers', 'name'];
    $scope.sanitizeObject = function(type, key){
      return eval(type + 'Whitelist').indexOf(key) === -1;
    };
    /* jshint ignore:end */

    // Services
    $scope.deleteClient = clientsService.deleteClient;
    $scope.resolveEvent = clientsService.resolveEvent;
    $scope.permalink = routingService.permalink;
    $scope.stash = stashesService.stash;
    var getCheck = clientsService.getCheck;
    var getEvent = clientsService.getEvent;
  }
]);

/**
* Clients
*/
controllerModule.controller('clients', ['$scope', '$routeParams', 'routingService', 'stashesService', 'clientsService', 'Page',
  function ($scope, $routeParams, routingService, stashesService, clientsService, Page) {
    Page.setTitle('Clients');
    $scope.pageHeaderText = 'Clients';
    $scope.predicate = '-status';

    // Routing
    $scope.filters = {};
    routingService.initFilters($routeParams, $scope.filters, ['dc', 'subscription', 'limit', 'q']);
    $scope.$on('$locationChangeSuccess', function(){
      routingService.updateFilters($routeParams, $scope.filters);
    });

    // Services
    $scope.go = routingService.go;
    $scope.permalink = routingService.permalink;
    $scope.stash = stashesService.stash;
    $scope.deleteClient = clientsService.deleteClient;

    // Helpers
    $scope.selectedClients = function(clients) {
      return _.filter(clients, function(client) {
        return client.selected === true;
      });
    };

    $scope.selectClients = function(selectModel) {
      _.each($scope.clients, function(client) {
        client.selected = selectModel.selected;
      });
    };

    $scope.deleteClients = function(clients) {
      _.each(clients, function(client) {
        $scope.deleteClient(client.dc, client.name);
      });
    };
  }
]);

/**
* Events
*/
controllerModule.controller('events', ['$cookieStore', '$scope', '$routeParams','routingService', 'settings', 'stashesService', 'clientsService', 'Page',
  function ($cookieStore, $scope, $routeParams, routingService, settings, stashesService, clientsService, Page) {
    Page.setTitle('Events');
    $scope.pageHeaderText = 'Events';
    $scope.predicate = '-check.status';
    $scope.filters = {};

    // Routing
    routingService.initFilters($routeParams, $scope.filters, ['dc', 'limit', 'q']);
    $scope.$on('$locationChangeSuccess', function(){
      routingService.updateFilters($routeParams, $scope.filters);
    });

    // Services
    $scope.go = routingService.go;
    $scope.permalink = routingService.permalink;
    $scope.stash = stashesService.stash;
    $scope.resolveEvent = clientsService.resolveEvent;

    // Hide silenced
    $scope.filters.silenced = $cookieStore.get('hideSilenced') || settings.hideSilenced;
    $scope.$watch('filters.silenced', function () {
      $cookieStore.put('hideSilenced', $scope.filters.silenced);
    });

    // Helpers
    $scope.selectedEvents = function(events) {
      return _.filter(events, function(event) {
        return event.selected === true;
      });
    };

    $scope.selectEvents = function(selectModel) {
      _.each($scope.events, function(event) {
        event.selected = selectModel.selected;
      });
    };

    $scope.resolveEvents = function(events) {
      _.each(events, function(event) {
        $scope.resolveEvent(event.dc, event.client, event.check);
      });
    };
  }
]);

/**
* Info
*/
controllerModule.controller('info', ['$scope', 'notification', 'Page', 'version', 'uchiwaBackend',
  function ($scope, notification, Page, version, uchiwaBackend) {
    $scope.pageHeaderText = 'Info';
    $scope.uchiwa = {};
    Page.setTitle('Info');
    $scope.uchiwa.version = version.uchiwa;

    uchiwaBackend.getConfig()
      .success(function (data) {
        $scope.uchiwa.config = JSON.stringify(data, null, 2);
      })
      .error(function (error) {
        notification('error', 'Could not fetch Uchiwa config. Is Uchiwa running?');
        console.error('Error: '+ JSON.stringify(error));
      });
  }
]);

/**
* Navbar
*/
controllerModule.controller('navbar', ['$rootScope', '$scope', 'navbarServices', 'routingService',
  function ($rootScope, $scope, navbarServices, routingService) {

    // Services
    $scope.go = routingService.go;

    $scope.$on('sensu', function () {
      // Update badges
      navbarServices.countStatuses($rootScope.clients, function (item) {
        return item.status;
      });
      navbarServices.countStatuses($rootScope.events, function (item) {
        return item.check.status;
      });

      // Update alert badge
      navbarServices.health();
    });
  }
]);

/**
* Settings
*/
controllerModule.controller('settings', ['$cookies', '$scope', 'Page',
  function ($cookies, $scope, Page) {
    $scope.pageHeaderText = 'Settings';
    Page.setTitle('Settings');
    $scope.$watch('currentTheme', function (theme) {
      $scope.$emit('theme:changed', theme);
    });
  }
]);

/**
* Sidebar
*/
controllerModule.controller('sidebar', ['$scope', '$location',
  function ($scope, $location) {
    $scope.getClass = function(path) {
      if ($location.path().substr(0, path.length) === path) {
        return 'selected';
      } else {
        return '';
      }
    };
  }
]);

/**
* Stashes
*/
controllerModule.controller('stashes', ['$scope', '$routeParams', 'routingService', 'stashesService', 'Page',
  function ($scope, $routeParams, routingService, stashesService, Page) {
    Page.setTitle('Stashes');
    $scope.pageHeaderText = 'Stashes';
    $scope.predicate = 'client';

    // Helpers
    //$scope.deleteStash = function (dcName, stash, index) {
    //  stashesService.deleteStash(stash);
      //$scope.stashes.splice(index, 1);
    //};
    $scope.deleteStash = stashesService.deleteStash;

    // Routing
    $scope.filters = {};
    routingService.initFilters($routeParams, $scope.filters, ['dc', 'limit', 'q']);
    $scope.$on('$locationChangeSuccess', function(){
      routingService.updateFilters($routeParams, $scope.filters);
    });

    // Services
    $scope.permalink = routingService.permalink;

  }
]);

/**
* Stash Modal
*/
controllerModule.controller('StashModalCtrl', ['$scope', '$filter', '$modalInstance', 'items', 'stashesService',
  function ($scope, $filter, $modalInstance, items, stashesService) {
    $scope.items = items;
    $scope.acknowledged = $filter('filter')(items, {acknowledged: true}).length;
    $scope.itemType = items[0].hasOwnProperty('client') ? 'check' : 'client';
    $scope.stash = {};
    $scope.stash.expirations = {
      '900': 900,
      '3600': 3600,
      '86400': 86400,
      'none': -1
    };
    $scope.stash.reason = '';
    $scope.stash.expiration = 900;

    $scope.stashForItem = function(stashes, item) {
      var path = 'silence/';

      if ($scope.itemType === 'client') {
        path = path + item.name;
      } else if ($scope.itemType === 'check') {
        path = path + item.client.name + '/' + item.check.name;
      }

      return _.findWhere(stashes, {
        dc: item.dc,
        path: path
      });
    };

    $scope.ok = function () {
      _.each(items, function(item) {
        stashesService.submit(item, $scope.stash);
      });
      $modalInstance.close();
    };
    $scope.cancel = function () {
      $modalInstance.dismiss('cancel');
    };
  }
]);
<commit_msg>[bulk_actions] include dc when searching for existing clients<commit_after>'use strict';

var controllerModule = angular.module('uchiwa.controllers', []);

/**
* Init
*/
controllerModule.controller('init', ['$rootScope', '$scope', 'notification', 'pollingFactory', 'Page', 'uchiwaBackend',
  function ($rootScope, $scope, notification, pollingFactory, Page, uchiwaBackend) {
    $scope.Page = Page;
    $rootScope.skipRefresh = false;
    $rootScope.alerts = [];
    $rootScope.events = [];

    uchiwaBackend.getConfig()
      .success(function (data) {
        pollingFactory.callFnOnInterval(function () { $rootScope.getSensu(); }, data.Uchiwa.Refresh);
      })
      .error(function () {
        pollingFactory.callFnOnInterval(function () { $rootScope.getSensu(); }, 10);
      });

    $rootScope.getSensu = function () {
      if ($rootScope.skipRefresh) {
        $rootScope.skipRefresh = false;
        return;
      }
      uchiwaBackend.getHealth()
        .success(function (data) {
          $rootScope.health = data;
        });
      uchiwaBackend.getSensu()
        .success(function (data) {
          angular.forEach(data, function(value, key) { // initialize null elements
            if (!value || value === null) {
              data[key] = [];
            }
          });
          $rootScope.checks = data.Checks;
          $rootScope.dc = data.Dc;

          $rootScope.clients = _.map(data.Clients, function(client) {
            var existingClient = _.findWhere($rootScope.clients, {name: client.name, dc: client.dc});
            if (existingClient !== undefined) {
              client = angular.extend(existingClient, client);
            }
            return existingClient || client;
          });

          $rootScope.events = _.map(data.Events, function(event) {
            event._id = event.dc + '/' + event.client.name + '/' + event.check.name;
            var existingEvent = _.findWhere($rootScope.events, {_id: event._id});
            if (existingEvent !== undefined) {
              event = angular.extend(existingEvent, event);
            }
            return existingEvent || event;
          });

          $rootScope.stashes = data.Stashes;
          $rootScope.subscriptions = data.Subscriptions;
          $scope.$broadcast('sensu');

        })
        .error(function (error) {
          notification('error', 'Could not fetch Sensu data. Is Uchiwa running?');
          console.error('Error: '+ JSON.stringify(error));
        });
    };

    $scope.$on('$routeChangeSuccess', function () {
      $rootScope.getSensu();
    });

    $scope.$on('notification', function (type, message) {
      notification(type, message);
    });
  }
]);

/**
* Checks
*/
controllerModule.controller('checks', ['$scope', '$routeParams', 'routingService', 'Page',
  function ($scope, $routeParams, routingService, Page) {
    Page.setTitle('Checks');
    $scope.pageHeaderText = 'Checks';
    $scope.predicate = 'name';

    // Helpers
    $scope.subscribersSummary = function(subscribers){
      return subscribers.join(' ');
    };

    // Routing
    $scope.filters = {};
    routingService.initFilters($routeParams, $scope.filters, ['dc', 'limit', 'q']);
    $scope.$on('$locationChangeSuccess', function(){
      routingService.updateFilters($routeParams, $scope.filters);
    });

    // Services
    $scope.permalink = routingService.permalink;

  }
]);

/**
* Client
*/
controllerModule.controller('client', ['$scope', '$routeParams', 'clientsService', 'notification', 'Page', 'routingService', 'stashesService', 'uchiwaBackend',
  function ($scope, $routeParams, clientsService, notification, Page, routingService, stashesService, uchiwaBackend) {

    $scope.predicate = '-last_status';

    // Retrieve client
    $scope.clientId = decodeURI($routeParams.clientId);
    $scope.dcId = decodeURI($routeParams.dcId);
    $scope.pull = function() {
      uchiwaBackend.getClient($scope.clientId, $scope.dcId)
        .success(function (data) {
          $scope.$emit('client', data);
        })
        .error(function (error) {
          notification('error', 'Could not retrieve the client '+ $scope.clientId +'. Is Sensu API running on '+ $scope.dcId +'?');
          console.error('Error: '+ JSON.stringify(error));
        });
    };

    $scope.pull();
    var timer = setInterval($scope.pull, 10000);

    $scope.$on('client', function (event, data) {
      $scope.client = data;
      $scope.pageHeaderText = $scope.client.name;

      // Retrieve check & event
      $scope.requestedCheck = decodeURI($routeParams.check);
      $scope.selectedCheck = getCheck($scope.requestedCheck, $scope.client.history);
      $scope.selectedEvent = getEvent($scope.client.name, $scope.requestedCheck, $scope.events);

      // Set page title
      if(angular.isDefined($scope.selectedCheck)) {
        Page.setTitle($scope.requestedCheck + ' - ' + $scope.client.name);
      }
      else {
        Page.setTitle($scope.client.name);
      }
    });

    // Routing
    $scope.$on('$routeUpdate', function(){
      // Retrieve check & event
      $scope.requestedCheck = decodeURI($routeParams.check);
      $scope.selectedCheck = getCheck($scope.requestedCheck, $scope.client.history);
      $scope.selectedEvent = getEvent($scope.client.name, $scope.requestedCheck, $scope.events);

      if(angular.isDefined($scope.selectedCheck)) {
        Page.setTitle($scope.requestedCheck + ' - ' + $scope.client.name);
      }
      else {
        Page.setTitle($scope.client.name);
      }
    });

    $scope.$on('$destroy', function() {
      clearInterval(timer);
    });

    // Sanitize - only display useful information 'acknowledged', 'dc', 'events', 'eventsSummary', 'history', 'status', 'timestamp'
    /* jshint ignore:start */
    var clientWhitelist = [ 'acknowledged', 'dc', 'events', 'eventsSummary', 'history', 'output', 'status', 'timestamp' ];
    var checkWhitelist = [ 'dc', 'hasSubscribers', 'name'];
    $scope.sanitizeObject = function(type, key){
      return eval(type + 'Whitelist').indexOf(key) === -1;
    };
    /* jshint ignore:end */

    // Services
    $scope.deleteClient = clientsService.deleteClient;
    $scope.resolveEvent = clientsService.resolveEvent;
    $scope.permalink = routingService.permalink;
    $scope.stash = stashesService.stash;
    var getCheck = clientsService.getCheck;
    var getEvent = clientsService.getEvent;
  }
]);

/**
* Clients
*/
controllerModule.controller('clients', ['$scope', '$routeParams', 'routingService', 'stashesService', 'clientsService', 'Page',
  function ($scope, $routeParams, routingService, stashesService, clientsService, Page) {
    Page.setTitle('Clients');
    $scope.pageHeaderText = 'Clients';
    $scope.predicate = '-status';

    // Routing
    $scope.filters = {};
    routingService.initFilters($routeParams, $scope.filters, ['dc', 'subscription', 'limit', 'q']);
    $scope.$on('$locationChangeSuccess', function(){
      routingService.updateFilters($routeParams, $scope.filters);
    });

    // Services
    $scope.go = routingService.go;
    $scope.permalink = routingService.permalink;
    $scope.stash = stashesService.stash;
    $scope.deleteClient = clientsService.deleteClient;

    // Helpers
    $scope.selectedClients = function(clients) {
      return _.filter(clients, function(client) {
        return client.selected === true;
      });
    };

    $scope.selectClients = function(selectModel) {
      _.each($scope.clients, function(client) {
        client.selected = selectModel.selected;
      });
    };

    $scope.deleteClients = function(clients) {
      _.each(clients, function(client) {
        $scope.deleteClient(client.dc, client.name);
      });
    };
  }
]);

/**
* Events
*/
controllerModule.controller('events', ['$cookieStore', '$scope', '$routeParams','routingService', 'settings', 'stashesService', 'clientsService', 'Page',
  function ($cookieStore, $scope, $routeParams, routingService, settings, stashesService, clientsService, Page) {
    Page.setTitle('Events');
    $scope.pageHeaderText = 'Events';
    $scope.predicate = '-check.status';
    $scope.filters = {};

    // Routing
    routingService.initFilters($routeParams, $scope.filters, ['dc', 'limit', 'q']);
    $scope.$on('$locationChangeSuccess', function(){
      routingService.updateFilters($routeParams, $scope.filters);
    });

    // Services
    $scope.go = routingService.go;
    $scope.permalink = routingService.permalink;
    $scope.stash = stashesService.stash;
    $scope.resolveEvent = clientsService.resolveEvent;

    // Hide silenced
    $scope.filters.silenced = $cookieStore.get('hideSilenced') || settings.hideSilenced;
    $scope.$watch('filters.silenced', function () {
      $cookieStore.put('hideSilenced', $scope.filters.silenced);
    });

    // Helpers
    $scope.selectedEvents = function(events) {
      return _.filter(events, function(event) {
        return event.selected === true;
      });
    };

    $scope.selectEvents = function(selectModel) {
      _.each($scope.events, function(event) {
        event.selected = selectModel.selected;
      });
    };

    $scope.resolveEvents = function(events) {
      _.each(events, function(event) {
        $scope.resolveEvent(event.dc, event.client, event.check);
      });
    };
  }
]);

/**
* Info
*/
controllerModule.controller('info', ['$scope', 'notification', 'Page', 'version', 'uchiwaBackend',
  function ($scope, notification, Page, version, uchiwaBackend) {
    $scope.pageHeaderText = 'Info';
    $scope.uchiwa = {};
    Page.setTitle('Info');
    $scope.uchiwa.version = version.uchiwa;

    uchiwaBackend.getConfig()
      .success(function (data) {
        $scope.uchiwa.config = JSON.stringify(data, null, 2);
      })
      .error(function (error) {
        notification('error', 'Could not fetch Uchiwa config. Is Uchiwa running?');
        console.error('Error: '+ JSON.stringify(error));
      });
  }
]);

/**
* Navbar
*/
controllerModule.controller('navbar', ['$rootScope', '$scope', 'navbarServices', 'routingService',
  function ($rootScope, $scope, navbarServices, routingService) {

    // Services
    $scope.go = routingService.go;

    $scope.$on('sensu', function () {
      // Update badges
      navbarServices.countStatuses($rootScope.clients, function (item) {
        return item.status;
      });
      navbarServices.countStatuses($rootScope.events, function (item) {
        return item.check.status;
      });

      // Update alert badge
      navbarServices.health();
    });
  }
]);

/**
* Settings
*/
controllerModule.controller('settings', ['$cookies', '$scope', 'Page',
  function ($cookies, $scope, Page) {
    $scope.pageHeaderText = 'Settings';
    Page.setTitle('Settings');
    $scope.$watch('currentTheme', function (theme) {
      $scope.$emit('theme:changed', theme);
    });
  }
]);

/**
* Sidebar
*/
controllerModule.controller('sidebar', ['$scope', '$location',
  function ($scope, $location) {
    $scope.getClass = function(path) {
      if ($location.path().substr(0, path.length) === path) {
        return 'selected';
      } else {
        return '';
      }
    };
  }
]);

/**
* Stashes
*/
controllerModule.controller('stashes', ['$scope', '$routeParams', 'routingService', 'stashesService', 'Page',
  function ($scope, $routeParams, routingService, stashesService, Page) {
    Page.setTitle('Stashes');
    $scope.pageHeaderText = 'Stashes';
    $scope.predicate = 'client';

    // Helpers
    //$scope.deleteStash = function (dcName, stash, index) {
    //  stashesService.deleteStash(stash);
      //$scope.stashes.splice(index, 1);
    //};
    $scope.deleteStash = stashesService.deleteStash;

    // Routing
    $scope.filters = {};
    routingService.initFilters($routeParams, $scope.filters, ['dc', 'limit', 'q']);
    $scope.$on('$locationChangeSuccess', function(){
      routingService.updateFilters($routeParams, $scope.filters);
    });

    // Services
    $scope.permalink = routingService.permalink;

  }
]);

/**
* Stash Modal
*/
controllerModule.controller('StashModalCtrl', ['$scope', '$filter', '$modalInstance', 'items', 'stashesService',
  function ($scope, $filter, $modalInstance, items, stashesService) {
    $scope.items = items;
    $scope.acknowledged = $filter('filter')(items, {acknowledged: true}).length;
    $scope.itemType = items[0].hasOwnProperty('client') ? 'check' : 'client';
    $scope.stash = {};
    $scope.stash.expirations = {
      '900': 900,
      '3600': 3600,
      '86400': 86400,
      'none': -1
    };
    $scope.stash.reason = '';
    $scope.stash.expiration = 900;

    $scope.stashForItem = function(stashes, item) {
      var path = 'silence/';

      if ($scope.itemType === 'client') {
        path = path + item.name;
      } else if ($scope.itemType === 'check') {
        path = path + item.client.name + '/' + item.check.name;
      }

      return _.findWhere(stashes, {
        dc: item.dc,
        path: path
      });
    };

    $scope.ok = function () {
      _.each(items, function(item) {
        stashesService.submit(item, $scope.stash);
      });
      $modalInstance.close();
    };
    $scope.cancel = function () {
      $modalInstance.dismiss('cancel');
    };
  }
]);
<|endoftext|>


<commit_before>var app = angular.module('evewt', ['ui-notification']);
app.controller('wt-list',[ '$scope','$http','$location','$interval','$window','API','EveIGB','Notification',function ($scope,$http,$location,$interval,$window,API,EveIGB,Notification) {

    //=== Vars
    $scope.waitlistVO = null;
    $scope.waitlists = {waitlists:[]};
    $scope.shipDNA = '';
    $scope.apiKey = '';
    $scope.apiVCode = '';
    $scope.remeberMe = true;

    $scope.authenticated = false;
    $scope.isIGB = (typeof CCPEVE !== 'undefined');
    console.log('You are' + ($scope.isIGB ? '' : ' not') + ' in IGB')
    $scope.window = $window;

    $scope.waitlistTxt = '';

    $scope.getWaitlistId = function () {
        console.log("ID: " + $location.search())
        return $location.search().waitlistId;
    }

    $scope.forwardMe = function(){

    }
    $scope.postFit = function(){
        API.postFit($scope.waitlistVO.waitlistId,$scope.shipDNA)
            .then(function (data) {
                $scope.refreshWL();
                Notification.success("Successfully x-ed up")
            }, function () {
                Notification.error("Cannot x up, logged in? on waitlist?")
            })
    };

    $scope.newWaitlist = function () {
        return API.newWaitlist()
            .then(function (waitlist) {
                waitlist.waitlistId;
                $scope.updateWL(waitlist);
                Notification.success("Successfully created waitlist")
            }, function () {
                Notification.error("Cannot create waitlist, logged in?")
            })
    };

    //=== Functions
    $scope.updateWL = function(waitlistVO){
      $scope.waitlistVO = waitlistVO;
      //$location.hash(waitlistVO.waitlistId);
    };

    $scope.refreshWL = function(){
        API.getWaitlist($scope.waitlistVO.waitlistId)
            .then(function (data) {
                $scope.updateWL(data);
            })
        API.getWaitlistTxt($scope.waitlistVO.waitlistId)
            .then(function (waitlistTxt) {
                $scope.waitlistTxt = waitlistTxt;
            })
    };

    $scope.showCharInfo = function(item){
        EveIGB.showInfo(1377, item.characterId);
    };

    $scope.showFitting = function(item){
        EveIGB.showFitting(item.shipDNA);
    };

    $scope.showCorporation = function(item){
        EveIGB.showInfo(2,item.corporationId);
    };
    $scope.showAlliance = function(item){
        EveIGB.showInfo(16159,item.allianceId);
    };

    $scope.fleetInvite = function(item){
        EveIGB.inviteToFleet(item.characterId)
        Notification.success("Invited " + item.characterName + " to fleet")
    };

    $scope.removeItem = function(item){
        API.removeItem($scope.waitlistVO.waitlistId,item.itemId)
            .then(function () {
                $scope.refreshWL();
                Notification.success("Removed " + item.characterName + " from the waitlist")
            })
            .then(null,function () {
                Notification.error('failed to remove item :(');
            })
    };

    $scope.logout = function () {
        API.logout()
            .then(function () {
                Notification.success("Logged out")
            })
            .then(null,function () {
                Notification.error('failed to logout :(');
            })
    }

    //=== Fetch data

    API.getMe()
        .then(function (data) {
            $scope.me = data;
            var waitlistId = $scope.getWaitlistId(); //$location.hash();
            $scope.authenticated = true;
            if(waitlistId && waitlistId.length>0){
                return API.getWaitlist(waitlistId)
                    .then(function (waitlist) {
                        $scope.updateWL(waitlist);
                        Notification.success('Joined waitlist');
                    })
                    .then(null,function () {
                        $location.hash('');
                        Notification.error('Failed to fetch waitlist :(');
                    })
            }else{
                alert('Please either create a new waitlist or join an existing waitlist');
            }
        })
        .then(null,function (status) {
            if(status==401){
                $scope.authenticated = false;
                Notification.error('Please login first');
            }
        })

    API.getWaitlists()
        .then(function (waitlists) {
            $scope.waitlists = waitlists;
        })

    //update every 10s, veeery inefficient
    $interval(function(){
        $scope.refreshWL();
    }, 10000);
    //
}]);<commit_msg>changed wl id storage<commit_after>var app = angular.module('evewt', ['ui-notification']);
app.controller('wt-list',[ '$scope','$http','$location','$interval','$window','API','EveIGB','Notification',function ($scope,$http,$location,$interval,$window,API,EveIGB,Notification) {

    //=== Vars
    $scope.waitlistVO = null;
    $scope.waitlists = {waitlists:[]};
    $scope.shipDNA = '';
    $scope.apiKey = '';
    $scope.apiVCode = '';
    $scope.remeberMe = true;

    $scope.authenticated = false;
    $scope.isIGB = (typeof CCPEVE !== 'undefined');
    console.log('You are' + ($scope.isIGB ? '' : ' not') + ' in IGB')
    $scope.window = $window;

    $scope.waitlistTxt = '';

    $scope.getWaitlistId = function () {
        console.log("ID: " + JSON.stringify($location.search()));
        return $location.search().waitlistId;
    }

    $scope.forwardMe = function(){

    }
    $scope.postFit = function(){
        API.postFit($scope.waitlistVO.waitlistId,$scope.shipDNA)
            .then(function (data) {
                $scope.refreshWL();
                Notification.success("Successfully x-ed up")
            }, function () {
                Notification.error("Cannot x up, logged in? on waitlist?")
            })
    };

    $scope.newWaitlist = function () {
        return API.newWaitlist()
            .then(function (waitlist) {
                waitlist.waitlistId;
                $scope.updateWL(waitlist);
                Notification.success("Successfully created waitlist")
            }, function () {
                Notification.error("Cannot create waitlist, logged in?")
            })
    };

    //=== Functions
    $scope.updateWL = function(waitlistVO){
      $scope.waitlistVO = waitlistVO;
      //$location.hash(waitlistVO.waitlistId);
    };

    $scope.refreshWL = function(){
        API.getWaitlist($scope.waitlistVO.waitlistId)
            .then(function (data) {
                $scope.updateWL(data);
            })
        API.getWaitlistTxt($scope.waitlistVO.waitlistId)
            .then(function (waitlistTxt) {
                $scope.waitlistTxt = waitlistTxt;
            })
    };

    $scope.showCharInfo = function(item){
        EveIGB.showInfo(1377, item.characterId);
    };

    $scope.showFitting = function(item){
        EveIGB.showFitting(item.shipDNA);
    };

    $scope.showCorporation = function(item){
        EveIGB.showInfo(2,item.corporationId);
    };
    $scope.showAlliance = function(item){
        EveIGB.showInfo(16159,item.allianceId);
    };

    $scope.fleetInvite = function(item){
        EveIGB.inviteToFleet(item.characterId)
        Notification.success("Invited " + item.characterName + " to fleet")
    };

    $scope.removeItem = function(item){
        API.removeItem($scope.waitlistVO.waitlistId,item.itemId)
            .then(function () {
                $scope.refreshWL();
                Notification.success("Removed " + item.characterName + " from the waitlist")
            })
            .then(null,function () {
                Notification.error('failed to remove item :(');
            })
    };

    $scope.logout = function () {
        API.logout()
            .then(function () {
                Notification.success("Logged out")
            })
            .then(null,function () {
                Notification.error('failed to logout :(');
            })
    }

    //=== Fetch data

    API.getMe()
        .then(function (data) {
            $scope.me = data;
            var waitlistId = $scope.getWaitlistId(); //$location.hash();
            $scope.authenticated = true;
            if(waitlistId && waitlistId.length>0){
                return API.getWaitlist(waitlistId)
                    .then(function (waitlist) {
                        $scope.updateWL(waitlist);
                        Notification.success('Joined waitlist');
                    })
                    .then(null,function () {
                        $location.hash('');
                        Notification.error('Failed to fetch waitlist :(');
                    })
            }else{
                alert('Please either create a new waitlist or join an existing waitlist');
            }
        })
        .then(null,function (status) {
            if(status==401){
                $scope.authenticated = false;
                Notification.error('Please login first');
            }
        })

    API.getWaitlists()
        .then(function (waitlists) {
            $scope.waitlists = waitlists;
        })

    //update every 10s, veeery inefficient
    $interval(function(){
        $scope.refreshWL();
    }, 10000);
    //
}]);<|endoftext|>


<commit_before>angular.module('monitorApp.controllers',['ui.bootstrap', 'angularUtils.directives.dirPagination']
).controller('MonitorController',function($scope,$interval, $http){
  $scope.data = [];
  $scope.temps = [[]];

  $scope.lastData = {};

  $http.get("/data")
    .then(function(response) {
        $scope.data = response.data.data;
        $scope.lastData = $scope.data[0];
        for(var i = 0; i<$scope.data.length; i++){
          $scope.temps[0].push($scope.data[i].value);
          $scope.labels.push($scope.data[i].timestamp);
        }

    });
    $scope.labels = [];
     $scope.series = ['Temperatura'];

     $scope.onClick = function (points, evt) {
       console.log(points, evt);
     };
     $scope.datasetOverride = [{ yAxisID: 'y-axis-1' }];
     $scope.options = {
       scales: {
         yAxes: [
           {
             id: 'y-axis-1',
             type: 'linear',
             display: true,
             position: 'left'
           }
         ]
       }
     };

});
<commit_msg>Reversed the data<commit_after>angular.module('monitorApp.controllers',['ui.bootstrap', 'angularUtils.directives.dirPagination']
).controller('MonitorController',function($scope,$interval, $http){
  $scope.data = [];
  $scope.temps = [[]];

  $scope.lastData = {};

  $http.get("/data")
    .then(function(response) {
        $scope.data = response.data.data;
        $scope.lastData = $scope.data[0];
        for(var i = 0; i<$scope.data.length; i++){
          $scope.temps[0].push($scope.data[i].value);
          $scope.labels.push($scope.data[i].timestamp);
        }
        console.log($scope.labels);
        $scope.temps[0].reverse();
        $scope.labels.reverse();
        console.log($scope.labels);

    });
    $scope.labels = [];
     $scope.series = ['Temperatura'];

     $scope.onClick = function (points, evt) {
       console.log(points, evt);
     };
     $scope.datasetOverride = [{ yAxisID: 'y-axis-1' }];
     $scope.options = {
       scales: {
         yAxes: [
           {
             id: 'y-axis-1',
             type: 'linear',
             display: true,
             position: 'left'
           }
         ]
       }
     };

});
<|endoftext|>


<commit_before>define(['jquery', 'base/ui', 'base/gallery'],
  function ($, UI, Gallery) {
  'use strict';

  var gallery = new Gallery({
    banner: '#banner-teach',
    makeView: 'make-teach.html',
    stickyPrefix: 'webmaker:teach-',
    defaultSearch: { tags: [ 'webmaker:recommended', 'guide' ] }
  });

});
<commit_msg>[bug 886150] Standardizing /teach tagging rules<commit_after>define(['jquery', 'base/ui', 'base/gallery'],
  function ($, UI, Gallery) {
  'use strict';

  var gallery = new Gallery({
    banner: '#banner-teach',
    makeView: 'make-teach.html',
    stickyPrefix: 'webmaker:teach-',
    defaultSearch: { tags: [ 'webmaker:teach' ] }
  });

});
<|endoftext|>


<commit_before>jQuery(document).ready(function() {
    $('abbr.timeago').timeago();
	socket.on('newPost', function(post) {
		if(post.topic.forum == $('#forumid').val())
		{
			var thisTopic = $('div#topic-'+ post.topic.slug);
			thisTopic.find('.topic-replies').html(post.topic.replies.length);
			thisTopic.find('.topic-last-post-author').html(post.author.username);
            thisTopic.find('.topic-last-post-time').untimeago();
            thisTopic.find('.topic-last-post-time').attr('title', post.postedOn).text(post.postedOn).timeago();
			thisTopic.find('.topic-status').html('');
            $('.forum-topics').prepend(thisTopic);

            thisTopic.effect('highlight', {}, 1000);
            setTimeout(function(){
                $('.forum-topics-jpages').jPages('destroy');
                $('.forum-topics-jpages').jPages(jPagesOptions);
            }, 1100);
		}
	});

    socket.on('deletedPost', function(post) {
        if(post.topic.forum == $('#forumid').val())
        {
            var thisTopic = $('div#topic-'+ post.topic.slug);
            thisTopic.find('.topic-replies').html(post.topic.replies.length).effect('highlight', {}, 1000);
        }
    });
    var pageUrl = document.location.pathname;
    var curPage = 1;
    var matches = pageUrl.match(/\/page\/(.*)\/$/);
    if (matches) {
        curPage = matches[1];
    }

    pageUrl = pageUrl.replace(/\/page\/(.*)\/$/, '/');

    var jPagesOptions = {
        containerID: 'forum-topics-paginate',
        perPage : 5,
        startPage: curPage,
        first: '«',
        last: '»',
        previous : '‹',
        next : '›',
        minHeight: 'true',
        callback    : function( pages, items ){
            $('html').animate({scrollTop:0}, 'slow');//IE, FF
            $('body').animate({scrollTop:0}, 'slow');//WebKit
            curPage = pages.current;
            $('#forum-topics-paginate').css('min-height', '');
            window.history.pushState(null, 'Page', pageUrl +'page/'+ pages.current+'/');
        }
    };

	$('.forum-topics-jpages').jPages(jPagesOptions);

	socket.on('newTopic', function(topic) {

		if(topic.forum == $('#forumid').val())
		{
			$('section.forum-topics').prepend("

"+ topic.title +"
"+ topic.desc +"

0

0

 Slashman X

").find("div#topic-" + topic.slug).effect('highlight', {}, 1000);

			$('li.category-nav').after("
 "+ topic.title +"
");
			$('ul.bs-docs-sidenav').find('li#nav-topic-'+ topic.slug).effect('highlight', {}, 1000);

            $('.forum-topics-jpages').jPages('destroy');
            $('.forum-topics-jpages').jPages(jPagesOptions);
		}
	})
});<commit_msg>#35 - Forum-view sockets functionality added. Topic fades to red -> removed<commit_after>jQuery(document).ready(function() {
    $('abbr.timeago').timeago();
	socket.on('newPost', function(post) {
		if(post.topic.forum == $('#forumid').val())
		{
			var thisTopic = $('div#topic-'+ post.topic.slug);
			thisTopic.find('.topic-replies').html(post.topic.replies.length);
			thisTopic.find('.topic-last-post-author').html(post.author.username);
            thisTopic.find('.topic-last-post-time').untimeago();
            thisTopic.find('.topic-last-post-time').attr('title', post.postedOn).text(post.postedOn).timeago();
			thisTopic.find('.topic-status').html('');
            $('.forum-topics').prepend(thisTopic);

            thisTopic.effect('highlight', {}, 1000);
            setTimeout(function(){
                $('.forum-topics-jpages').jPages('destroy');
                $('.forum-topics-jpages').jPages(jPagesOptions);
            }, 1100);
		}
	});

    socket.on('deletedPost', function(post) {
        if(post.topic.forum == $('#forumid').val())
        {
            var thisTopic = $('div#topic-'+ post.topic.slug);
            thisTopic.find('.topic-replies').html(post.topic.replies.length).effect('highlight', {}, 1000);
        }
    });
    var pageUrl = document.location.pathname;
    var curPage = 1;
    var matches = pageUrl.match(/\/page\/(.*)\/$/);
    if (matches) {
        curPage = matches[1];
    }

    pageUrl = pageUrl.replace(/\/page\/(.*)\/$/, '/');

    var jPagesOptions = {
        containerID: 'forum-topics-paginate',
        perPage : 5,
        startPage: curPage,
        first: '«',
        last: '»',
        previous : '‹',
        next : '›',
        minHeight: 'true',
        callback    : function( pages, items ){
            $('html').animate({scrollTop:0}, 'slow');//IE, FF
            $('body').animate({scrollTop:0}, 'slow');//WebKit
            curPage = pages.current;
            $('#forum-topics-paginate').css('min-height', '');
            window.history.pushState(null, 'Page', pageUrl +'page/'+ pages.current+'/');
        }
    };

	$('.forum-topics-jpages').jPages(jPagesOptions);

    socket.on('deletedTopic', function(deletedTopic){
        console.log(deletedTopic);
        $('div#topic-'+ deletedTopic.slug).effect('highlight', {mode: 'hide', color: "#CC0033"}, 1000);
        setTimeout(function() {
            $('div#topic-'+ deletedTopic.slug).remove();
            $('.forum-topics-jpages').jPages('destroy');
            $('.forum-topics-jpages').jPages(jPagesOptions);
            $('#forum-topics-paginate').css('min-height', '');
        }, 1000);
    });

	socket.on('newTopic', function(topic) {

		if(topic.forum == $('#forumid').val())
		{
			$('section.forum-topics').prepend("

"+ topic.title +"
"+ topic.desc +"

0

0

 Slashman X

").find("div#topic-" + topic.slug).effect('highlight', {}, 1000);

			$('li.category-nav').after("
 "+ topic.title +"
");
			$('ul.bs-docs-sidenav').find('li#nav-topic-'+ topic.slug).effect('highlight', {}, 1000);

            $('.forum-topics-jpages').jPages('destroy');
            $('.forum-topics-jpages').jPages(jPagesOptions);
		}
	})
});<|endoftext|>


<commit_before>define(['jquery', 'inheritance', 'ajaxify', 'bind', 'jquery.fileupload', 'domReady!'], function($, inheritance, ajaxify) {

    var instance = null;

    var Upload = Class.extend({
        init: function () {
            if (instance !== null) {
                throw Error('Only one instance of Upload allowed!');
            }

            var that = this;

            this.files = [];

            this.initialized = false;

            $('#content').bind('ajaxifyInit', function (event) {
                if (!that.initialized) {
                    that.internalInit();
                }
            });
        },
        internalInit: function () {
            var that = this;

            this.initialized = true;

            $('#fileupload').fileupload({
                multipart: false,
                add: function (event, data) {
                    $.each(data.files, function () {

                        var fileDom = $("#fileupload .files .tmpl").clone().removeClass("tmpl");
                        fileDom.find('.filename').text(this.name);

                        $("#fileupload .files").append(fileDom);

                        that.files.push({
                            file: this,
                            dom: fileDom
                        });
                    });
                },
                progressall: function (event, data) {
                    var progress = parseInt((data.loaded / data.total) * 100, 10);

                    $('#fileupload .files tr:visible .progress').addClass('active').find('.bar').eq(0).css(
                        'width',
                        progress + '%'
                    );
                }
            });

            $('#fileupload .start').click(function (event) {
                $("#upload .uploaded .tracks .track").remove();
                $("#upload .uploaded .messages .message").remove();
                that.send();
                return false;
            });
        },
        send: function () {
            var that = this;

            if (that.files.length > 0) {
                var file = that.files[0];

                $('#fileupload').fileupload('send', { files: file.file })
                    .success(function (result, textStatus, jqXHR) {
                        $(file.dom).remove();

                        var resultDom = $(result);

                        that.files.splice(0, 1);

                        ajaxify.load(resultDom);

                        $("#upload .uploaded .tracks").append(
                            resultDom.find('.track')
                        );

                        $("#upload .uploaded .messages").append(
                            resultDom.find('.message')
                        );

                        that.send();
                    });
            }
        }
    });

    return (function() {
        if (instance === null) {
            instance = new Upload();
        }

        return instance;
    })();
});
<commit_msg>fixed initialization check for upload<commit_after>define(['jquery', 'inheritance', 'ajaxify', 'bind', 'jquery.fileupload', 'domReady!'], function($, inheritance, ajaxify) {

    var instance = null;

    var Upload = Class.extend({
        init: function () {
            if (instance !== null) {
                throw Error('Only one instance of Upload allowed!');
            }

            var that = this;

            this.files = [];

            $('#content').bind('ajaxifyInit', function (event) {
                if (!$('#fileupload').data('initialized')) {
                    that.internalInit();
                }
            });
        },
        internalInit: function () {
            var that = this;

            $('#fileupload').data('initialized', true);

            $('#fileupload').fileupload({
                multipart: false,
                add: function (event, data) {
                    $.each(data.files, function () {

                        var fileDom = $("#fileupload .files .tmpl").clone().removeClass("tmpl");
                        fileDom.find('.filename').text(this.name);

                        $("#fileupload .files").append(fileDom);

                        that.files.push({
                            file: this,
                            dom: fileDom
                        });
                    });
                },
                progressall: function (event, data) {
                    var progress = parseInt((data.loaded / data.total) * 100, 10);

                    $('#fileupload .files tr:visible .progress').addClass('active').find('.bar').eq(0).css(
                        'width',
                        progress + '%'
                    );
                }
            });

            $('#fileupload .start').click(function (event) {
                $("#upload .uploaded .tracks .track").remove();
                $("#upload .uploaded .messages .message").remove();
                that.send();
                return false;
            });
        },
        send: function () {
            var that = this;

            if (that.files.length > 0) {
                var file = that.files[0];

                $('#fileupload').fileupload('send', { files: file.file })
                    .success(function (result, textStatus, jqXHR) {
                        $(file.dom).remove();

                        var resultDom = $(result);

                        that.files.splice(0, 1);

                        ajaxify.load(resultDom);

                        $("#upload .uploaded .tracks").append(
                            resultDom.find('.track')
                        );

                        $("#upload .uploaded .messages").append(
                            resultDom.find('.message')
                        );

                        that.send();
                    });
            }
        }
    });

    return (function() {
        if (instance === null) {
            instance = new Upload();
        }

        return instance;
    })();
});
<|endoftext|>


<commit_before>export default {

  langName: 'English',
  langCode: 'en',

  header: {},

  footer: {
    header:    'Cliff Effects Tool',
    cfbCredit: [
      'Made with ',
      { name: '__heartIcon__' },
      ' by Code for Boston',
    ],
  },

  homePage: {
    appName:          'Cliff Effects Tool',
    prototypeNote:    'GUIDANCE PROTOYPE*',
    cautionaryNote:   '*This is a prototype and should not be used to make financial decisions',
    toFirstInputPage: 'Get Started',
    toAboutPage:      'Learn More',
  },

  aboutPage: {
    aboutPageHeader: 'About the Cliff Effects Tool',

    whatForHeader:        'What is this tool for?',
    whatForImportantNote: [
      {
        name: '__importantNote__',
        text: 'Important Note:',
      },
      ' This application is a minimum viable product. It should not be used as the sole tool' +
      ' to understand a client\'s SNAP or Section 8 financial situation,' +
      ' or for any other public assistance program.',
    ],
    whatFor: [
      'This tool can help show how a change in income affects how much someone receives in public assistance' +
      ' from SNAP and Section 8 Housing Voucher benefits. It was designed for the case managers at ',
      { name: '__projectHope__' },
      ' with the aim of helping to predict changes in their clients\' benefits.',
    ],

    whyHeader: 'Why is this tool important?',
    why1:      'A cliff effect occurs when a slight change in a household’s circumstances' +
      ' - say, a slight pay raise - disproportionately lowers their benefits.' +
      ' The household is working to increase what they earn, but they end up with a net loss' +
      ' that actually puts them further behind. These cliff effects prevent many families' +
      ' from actually getting off of public assistance programs.',
    why2: 'Cliff effects are also difficult to predict. The interactions between income,' +
      ' household size, many other criteria, as well as the effects of the programs themselves' +
      ' impact each other in unexpected ways. We\'re exploring ways to deal with this issue of' +
      ' complexity and help families better understand and predict their situation.',

    videoLinkText:    'Two-minute video describing cliff effects',
    quantLinkText:    'Quantitative scenarios demonstrating cliff effects',
    benefitsLinkText: 'Breakdown of different benefits offered in MA',

    howToUseHeader: 'How do I use this tool?',
    howtoUse:       'Go step-by-step to add information about a client\'s current benefits,' +
      ' household, income, and other relevant information. This information will be used to' +
      ' predict the client\'s approximate benefit amount. When you reach the end, change the' +
      ' \'Future Income\' amount to see how a change in earned income will cause a change in' +
      ' benefit amount. Currently, the SNAP and Section 8 Housing Voucher programs are both available.' +
      ' Note that predictions may not directly match up with a client’s current benefit amount.' +
      ' The app’s focus is the amount of change that occurs in benefits when there are changes in earned income.',
    howToUseNote: [
      'Please note that this app does not store user data, so ',
      {
        name: '__refreshWarning__',
        text: 'if you refresh the page the data you\'ve entered will be lost.',
      },
      ' Each time you go through the app, it\'s a clean slate.',
    ],

    whoMadeThisHeader: 'Who is behind this?',
    whoMadeThis1:      [
      'This application is part of a project made possible by a Boston Foundation' +
      ' Open Door Grant to the University of Massachusetts Boston\'s ',
      { name: '__centerForSocialPolicy__' },
      ', in close partnership with ',
      { name: '__projectHope__' },
      ' and ',
      { name: '__codeForBoston__' },
      '. The Center for Social Policy is the lead partner for the ',
      { name: '__onSolidGroundCoalition__' },
      '.',
    ],
    whoMadeThis2: [
      'The code base is being maintained on ',
      { name: '__github__' },
      ' by ',
      { name: '__codeForBoston__' },
      ' volunteers.' +
      ' For more information or to report a bug, please contact ',
      { name: '__contactEmail__' },
      '.',
    ],
    whoMadeThis3: [
      'Here\'s a special thank you to all the Code for Boston volunteers who' +
      ' brought you this application, especially ',
      { name: '__namesExceptLast__' },
      ', and ',
      { name: '__lastName__' },
      '.',
    ],
  },

  visitPage: {
    stepBar: {
      currentBenefits: 'Current Benefits',
      household:       'Household',
      currentIncome:   'Income',
      currentExpenses: 'Expenses',
      predictions:     'Predictions',
    },

    currentBenefits: {
      hasSection8: {
        label: 'Do you have Section 8 Housing?',
        hint:  'Section 8 provides rental housing assistance.',
      },
      hasSnap: {
        label: 'Do you have SNAP?',
        hint:  'SNAP provides assistance with buying food',
      },
    },

    household: {
      householdHeader: 'Household',
      householdIntro:  'Information about the members of your household.',
      role:            'Role',
      age:             'Age',
      disabled:        'Disabled',
      headOfHousehold: 'Head of Household',
      addMember:       'Add a member',
      spouse:          'Spouse of Head of Household',
      childOther:      'Child/Other Household Member',
      previous:        'Previous',
      next:            'Next',
    },

    currentIncome: {
      earnedIncome: {
        label: 'Earned income',
        hint:  'Earned income is how much you and your family get paid from working',
      },
      TAFDC: {
        label: 'TAFDC',
        hint:  'Transitional Aid to Families with Dependent Children provides short-term financial assistance to families with children',
      },
      SSI: {
        label: 'SSI',
        hint:  'Supplemental Security Income is a federal program that provides financial and health care assistance to people 65 and over, or people who are blind or disabled',
      },
      SSDI: {
        label: 'SSDI',
        hint:  'Social Security Disability Income is a federal program to help people with disabilities',
      },
      childSupport: {
        label: 'Child support recieved',
        hint:  'Child support is money paid to you by a former spouse to help your child',
      },
      unemployment: {
        label: 'Unemployment',
        hint:  'Unemployment benefits provide income to people who have been laid off',
      },
      workersComp: {
        label: 'Worker\'s compensation',
        hint:  'Worker\'s Compensation provides assistance for people who have been injured on the job',
      },
      pension: {
        label: 'Pension',
        hint:  'A pension provides income to retirees, usually from their former employers',
      },
      socialSecurity: {
        label: 'Social security',
        hint:  'Social Security is a federal program that provides assistance to retirees',
      },
      alimony: {
        label: 'Alimony',
        hint:  'Alimony is money paid by one spouse to the other after a divorce',
      },
      otherIncome: {
        label: 'Other income',
        hint:  'Please note income you may have from sources that are not listed above',
      },
    },

    currentExpenses: {},

    predictions: {},
  },
};
<commit_msg>Adds text strings for Current Benefits page in en.js<commit_after>export default {

  langName: 'English',
  langCode: 'en',

  header: {},

  footer: {
    header:    'Cliff Effects Tool',
    cfbCredit: [
      'Made with ',
      { name: '__heartIcon__' },
      ' by Code for Boston',
    ],
  },

  homePage: {
    appName:          'Cliff Effects Tool',
    prototypeNote:    'GUIDANCE PROTOYPE*',
    cautionaryNote:   '*This is a prototype and should not be used to make financial decisions',
    toFirstInputPage: 'Get Started',
    toAboutPage:      'Learn More',
  },

  aboutPage: {
    aboutPageHeader: 'About the Cliff Effects Tool',

    whatForHeader:        'What is this tool for?',
    whatForImportantNote: [
      {
        name: '__importantNote__',
        text: 'Important Note:',
      },
      ' This application is a minimum viable product. It should not be used as the sole tool' +
      ' to understand a client\'s SNAP or Section 8 financial situation,' +
      ' or for any other public assistance program.',
    ],
    whatFor: [
      'This tool can help show how a change in income affects how much someone receives in public assistance' +
      ' from SNAP and Section 8 Housing Voucher benefits. It was designed for the case managers at ',
      { name: '__projectHope__' },
      ' with the aim of helping to predict changes in their clients\' benefits.',
    ],

    whyHeader: 'Why is this tool important?',
    why1:      'A cliff effect occurs when a slight change in a household’s circumstances' +
      ' - say, a slight pay raise - disproportionately lowers their benefits.' +
      ' The household is working to increase what they earn, but they end up with a net loss' +
      ' that actually puts them further behind. These cliff effects prevent many families' +
      ' from actually getting off of public assistance programs.',
    why2: 'Cliff effects are also difficult to predict. The interactions between income,' +
      ' household size, many other criteria, as well as the effects of the programs themselves' +
      ' impact each other in unexpected ways. We\'re exploring ways to deal with this issue of' +
      ' complexity and help families better understand and predict their situation.',

    videoLinkText:    'Two-minute video describing cliff effects',
    quantLinkText:    'Quantitative scenarios demonstrating cliff effects',
    benefitsLinkText: 'Breakdown of different benefits offered in MA',

    howToUseHeader: 'How do I use this tool?',
    howtoUse:       'Go step-by-step to add information about a client\'s current benefits,' +
      ' household, income, and other relevant information. This information will be used to' +
      ' predict the client\'s approximate benefit amount. When you reach the end, change the' +
      ' \'Future Income\' amount to see how a change in earned income will cause a change in' +
      ' benefit amount. Currently, the SNAP and Section 8 Housing Voucher programs are both available.' +
      ' Note that predictions may not directly match up with a client’s current benefit amount.' +
      ' The app’s focus is the amount of change that occurs in benefits when there are changes in earned income.',
    howToUseNote: [
      'Please note that this app does not store user data, so ',
      {
        name: '__refreshWarning__',
        text: 'if you refresh the page the data you\'ve entered will be lost.',
      },
      ' Each time you go through the app, it\'s a clean slate.',
    ],

    whoMadeThisHeader: 'Who is behind this?',
    whoMadeThis1:      [
      'This application is part of a project made possible by a Boston Foundation' +
      ' Open Door Grant to the University of Massachusetts Boston\'s ',
      { name: '__centerForSocialPolicy__' },
      ', in close partnership with ',
      { name: '__projectHope__' },
      ' and ',
      { name: '__codeForBoston__' },
      '. The Center for Social Policy is the lead partner for the ',
      { name: '__onSolidGroundCoalition__' },
      '.',
    ],
    whoMadeThis2: [
      'The code base is being maintained on ',
      { name: '__github__' },
      ' by ',
      { name: '__codeForBoston__' },
      ' volunteers.' +
      ' For more information or to report a bug, please contact ',
      { name: '__contactEmail__' },
      '.',
    ],
    whoMadeThis3: [
      'Here\'s a special thank you to all the Code for Boston volunteers who' +
      ' brought you this application, especially ',
      { name: '__namesExceptLast__' },
      ', and ',
      { name: '__lastName__' },
      '.',
    ],
  },

  visitPage: {
    stepBar: {
      currentBenefits: 'Current Benefits',
      household:       'Household',
      currentIncome:   'Income',
      currentExpenses: 'Expenses',
      predictions:     'Predictions',
    },

    currentBenefits: {
      currentBenefits: 'Current Benefits',
      selectBenefits:  'Select the benefits you currently receive',
      yes:             'Yes',
      no:              'No',
      hasSection8:     {
        label: 'Do you have Section 8 Housing?',
        hint:  'Section 8 provides rental housing assistance.',
      },
      hasSnap: {
        label: 'Do you have SNAP?',
        hint:  'SNAP provides assistance with buying food',
      },
      next: 'Next',
    },

    household: {
      householdHeader: 'Household',
      householdIntro:  'Information about the members of your household.',
      role:            'Role',
      age:             'Age',
      disabled:        'Disabled',
      headOfHousehold: 'Head of Household',
      addMember:       'Add a member',
      spouse:          'Spouse of Head of Household',
      childOther:      'Child/Other Household Member',
      previous:        'Previous',
      next:            'Next',
    },

    currentIncome: {
      earnedIncome: {
        label: 'Earned income',
        hint:  'Earned income is how much you and your family get paid from working',
      },
      TAFDC: {
        label: 'TAFDC',
        hint:  'Transitional Aid to Families with Dependent Children provides short-term financial assistance to families with children',
      },
      SSI: {
        label: 'SSI',
        hint:  'Supplemental Security Income is a federal program that provides financial and health care assistance to people 65 and over, or people who are blind or disabled',
      },
      SSDI: {
        label: 'SSDI',
        hint:  'Social Security Disability Income is a federal program to help people with disabilities',
      },
      childSupport: {
        label: 'Child support recieved',
        hint:  'Child support is money paid to you by a former spouse to help your child',
      },
      unemployment: {
        label: 'Unemployment',
        hint:  'Unemployment benefits provide income to people who have been laid off',
      },
      workersComp: {
        label: 'Worker\'s compensation',
        hint:  'Worker\'s Compensation provides assistance for people who have been injured on the job',
      },
      pension: {
        label: 'Pension',
        hint:  'A pension provides income to retirees, usually from their former employers',
      },
      socialSecurity: {
        label: 'Social security',
        hint:  'Social Security is a federal program that provides assistance to retirees',
      },
      alimony: {
        label: 'Alimony',
        hint:  'Alimony is money paid by one spouse to the other after a divorce',
      },
      otherIncome: {
        label: 'Other income',
        hint:  'Please note income you may have from sources that are not listed above',
      },
    },

    currentExpenses: {},

    predictions: {},
  },
};
<|endoftext|>


<commit_before>const remote = window.nativeRequire('remote')
const electron = window.nativeRequire('electron')
const Tray = remote.require('tray')
const app = remote.require('app')
const Menu = remote.Menu
const ipc = electron.ipcRenderer
const NativeImage = remote.nativeImage
const React = require('react')
const shallowCompare = require('react-addons-shallow-compare')

module.exports = React.createClass({
  displayName: 'Tray',

  propTypes: {
    unreadCount: React.PropTypes.number.isRequired,
    showUnreadCount: React.PropTypes.bool.isRequired,
    unreadColor: React.PropTypes.string,
    readColor: React.PropTypes.string
  },

  /* **************************************************************************/
  // Lifecycle
  /* **************************************************************************/

  componentDidMount: function () {
    const loader = new window.Image()
    loader.src = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4gICAgPHBhdGggZD0iTTAgMGgyNHYyNEgweiIgZmlsbD0ibm9uZSIvPiAgICA8cGF0aCBkPSJNMjAgNEg0Yy0xLjEgMC0xLjk5LjktMS45OSAyTDIgMThjMCAxLjEuOSAyIDIgMmgxNmMxLjEgMCAyLS45IDItMlY2YzAtMS4xLS45LTItMi0yem0wIDE0SDRWOGw4IDUgOC01djEwem0tOC03TDQgNmgxNmwtOCA1eiIvPjwvc3ZnPg=='
    loader.onload = (e) => {
      this.setState({ icon: loader })
    }
  },

  componentWillUnmount: function () {
    if (this.state.appTray) {
      this.state.appTray.destroy()
    }
  },

  /* **************************************************************************/
  // Data lifecycle
  /* **************************************************************************/

  getDefaultReadColor: function () { return app.isDarkMode() ? '#FFFFFF' : '#000000' },
  getDefaultUnreadColor: function () { return '#C82018' },

  getInitialState: function () {
    return { appTray: new Tray(null) }
  },

  shouldComponentUpdate: function (nextProps, nextState) {
    return shallowCompare(this, nextProps, nextState)
  },

  /* **************************************************************************/
  // Rendering
  /* **************************************************************************/

  /**
  * @return the nativeImage for the tray
  */
  renderImage: function () {
    const SIZE = 22 * window.devicePixelRatio
    const PADDING = SIZE * 0.15
    const CENTER = SIZE / 2
    const COLOR = this.props.unreadCount ? (this.props.unreadColor || this.getDefaultUnreadColor()) : (this.props.readColor || this.getDefaultReadColor())

    const canvas = document.createElement('canvas')
    canvas.width = SIZE
    canvas.height = SIZE

    const ctx = canvas.getContext('2d')

    // Count
    if (this.props.showUnreadCount && this.props.unreadCount && this.props.unreadCount < 99) {
      ctx.fillStyle = COLOR
      ctx.textAlign = 'center'
      if (this.props.unreadCount < 10) {
        ctx.font = (SIZE * 0.5) + 'px Helvetica'
        ctx.fillText(this.props.unreadCount, CENTER, CENTER + (SIZE * 0.20))
      } else {
        ctx.font = (SIZE * 0.4) + 'px Helvetica'
        ctx.fillText(this.props.unreadCount, CENTER, CENTER + (SIZE * 0.15))
      }
    } else {
      const ICON_SIZE = SIZE * 0.5
      const POS = (SIZE - ICON_SIZE) / 2
      ctx.fillStyle = COLOR
      ctx.fillRect(0, 0, SIZE, SIZE)
      ctx.globalCompositeOperation = 'destination-atop'
      ctx.drawImage(this.state.icon, POS, POS, ICON_SIZE, ICON_SIZE)
    }

    // Outer circle
    ctx.globalCompositeOperation = 'source-over'
    ctx.beginPath()
    ctx.arc(CENTER, CENTER, (SIZE / 2) - PADDING, 0, 2 * Math.PI, false)
    ctx.lineWidth = window.devicePixelRatio * 1.1
    ctx.strokeStyle = COLOR
    ctx.stroke()

    const pngData = NativeImage.createFromDataURL(canvas.toDataURL('image/png')).toPng()
    return NativeImage.createFromBuffer(pngData, window.devicePixelRatio)
  },

  /**
  * @return the tooltip string for the tray icon
  */
  renderTooltip: function () {
    return this.props.unreadCount ? this.props.unreadCount + ' unread mail' : 'No unread mail'
  },

  /**
  * @return the context menu for the tray icon
  */
  renderContextMenu: function () {
    const contextMenu = Menu.buildFromTemplate([
      { label: this.renderTooltip(), enabled: false },
      { type: 'separator' },
      { label: 'Focus Windows', click: (e) => ipc.send('focus-app') },
      { type: 'separator' },
      { label: 'Quit', click: (e) => ipc.send('quit-app') }
    ])
    return contextMenu
  },

  render: function () {
    if (!this.state.appTray || !this.state.icon) { return false }
    this.state.appTray.setImage(this.renderImage())
    this.state.appTray.setToolTip(this.renderTooltip())
    this.state.appTray.setContextMenu(this.renderContextMenu())

    return

  }
})
<commit_msg>Patch to fix #138<commit_after>const remote = window.nativeRequire('remote')
const electron = window.nativeRequire('electron')
const Tray = remote.require('tray')
const app = remote.require('app')
const Menu = remote.Menu
const ipc = electron.ipcRenderer
const NativeImage = remote.nativeImage
const React = require('react')
const shallowCompare = require('react-addons-shallow-compare')

module.exports = React.createClass({
  displayName: 'Tray',

  propTypes: {
    unreadCount: React.PropTypes.number.isRequired,
    showUnreadCount: React.PropTypes.bool.isRequired,
    unreadColor: React.PropTypes.string,
    readColor: React.PropTypes.string
  },

  /* **************************************************************************/
  // Lifecycle
  /* **************************************************************************/

  componentDidMount: function () {
    const loader = new window.Image()
    loader.src = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4gICAgPHBhdGggZD0iTTAgMGgyNHYyNEgweiIgZmlsbD0ibm9uZSIvPiAgICA8cGF0aCBkPSJNMjAgNEg0Yy0xLjEgMC0xLjk5LjktMS45OSAyTDIgMThjMCAxLjEuOSAyIDIgMmgxNmMxLjEgMCAyLS45IDItMlY2YzAtMS4xLS45LTItMi0yem0wIDE0SDRWOGw4IDUgOC01djEwem0tOC03TDQgNmgxNmwtOCA1eiIvPjwvc3ZnPg=='
    loader.onload = (e) => {
      this.setState({ icon: loader })
    }
  },

  componentWillUnmount: function () {
    if (this.state.appTray) {
      this.state.appTray.destroy()
    }
  },

  /* **************************************************************************/
  // Data lifecycle
  /* **************************************************************************/

  getDefaultReadColor: function () { return process.platform === 'darwin' && app.isDarkMode() ? '#FFFFFF' : '#000000' },
  getDefaultUnreadColor: function () { return '#C82018' },

  getInitialState: function () {
    return { appTray: new Tray(null) }
  },

  shouldComponentUpdate: function (nextProps, nextState) {
    return shallowCompare(this, nextProps, nextState)
  },

  /* **************************************************************************/
  // Rendering
  /* **************************************************************************/

  /**
  * @return the nativeImage for the tray
  */
  renderImage: function () {
    const SIZE = 22 * window.devicePixelRatio
    const PADDING = SIZE * 0.15
    const CENTER = SIZE / 2
    const COLOR = this.props.unreadCount ? (this.props.unreadColor || this.getDefaultUnreadColor()) : (this.props.readColor || this.getDefaultReadColor())

    const canvas = document.createElement('canvas')
    canvas.width = SIZE
    canvas.height = SIZE

    const ctx = canvas.getContext('2d')

    // Count
    if (this.props.showUnreadCount && this.props.unreadCount && this.props.unreadCount < 99) {
      ctx.fillStyle = COLOR
      ctx.textAlign = 'center'
      if (this.props.unreadCount < 10) {
        ctx.font = (SIZE * 0.5) + 'px Helvetica'
        ctx.fillText(this.props.unreadCount, CENTER, CENTER + (SIZE * 0.20))
      } else {
        ctx.font = (SIZE * 0.4) + 'px Helvetica'
        ctx.fillText(this.props.unreadCount, CENTER, CENTER + (SIZE * 0.15))
      }
    } else {
      const ICON_SIZE = SIZE * 0.5
      const POS = (SIZE - ICON_SIZE) / 2
      ctx.fillStyle = COLOR
      ctx.fillRect(0, 0, SIZE, SIZE)
      ctx.globalCompositeOperation = 'destination-atop'
      ctx.drawImage(this.state.icon, POS, POS, ICON_SIZE, ICON_SIZE)
    }

    // Outer circle
    ctx.globalCompositeOperation = 'source-over'
    ctx.beginPath()
    ctx.arc(CENTER, CENTER, (SIZE / 2) - PADDING, 0, 2 * Math.PI, false)
    ctx.lineWidth = window.devicePixelRatio * 1.1
    ctx.strokeStyle = COLOR
    ctx.stroke()

    const pngData = NativeImage.createFromDataURL(canvas.toDataURL('image/png')).toPng()
    return NativeImage.createFromBuffer(pngData, window.devicePixelRatio)
  },

  /**
  * @return the tooltip string for the tray icon
  */
  renderTooltip: function () {
    return this.props.unreadCount ? this.props.unreadCount + ' unread mail' : 'No unread mail'
  },

  /**
  * @return the context menu for the tray icon
  */
  renderContextMenu: function () {
    const contextMenu = Menu.buildFromTemplate([
      { label: this.renderTooltip(), enabled: false },
      { type: 'separator' },
      { label: 'Focus Windows', click: (e) => ipc.send('focus-app') },
      { type: 'separator' },
      { label: 'Quit', click: (e) => ipc.send('quit-app') }
    ])
    return contextMenu
  },

  render: function () {
    if (!this.state.appTray || !this.state.icon) { return false }
    this.state.appTray.setImage(this.renderImage())
    this.state.appTray.setToolTip(this.renderTooltip())
    this.state.appTray.setContextMenu(this.renderContextMenu())

    return

  }
})
<|endoftext|>


<commit_before>import { getServicePrefix, getServiceCapitalization, capitalizeFirst } from './utils'

export default function makeFindMixin (options) {
  const { service, params, fetchQuery, queryWhen = () => true, local = false, qid = 'default', items, debug } = options
  let { name, watch = [] } = options

  if (typeof watch === 'string') {
    watch = [watch]
  } else if (typeof watch === 'boolean' && watch) {
    watch = ['params']
  }

  if (!service || (typeof service !== 'string' && typeof service !== 'function')) {
    throw new Error(`The 'service' option is required in the FeathersVuex make-find-mixin and must be a string.`)
  }
  if (typeof service === 'function' && !name) {
    name = 'service'
  }

  const nameToUse = (name || service).replace('-', '_')
  const prefix = getServicePrefix(nameToUse)
  const capitalized = getServiceCapitalization(nameToUse)
  const SERVICE_NAME = `${prefix}ServiceName`
  let ITEMS = items || prefix
  if (typeof service === 'function' && name === 'service' && !items) {
    ITEMS = 'items'
  }
  const ITEMS_FETCHED = `${ITEMS}Fetched`
  const IS_FIND_PENDING = `isFind${capitalized}Pending`
  const PARAMS = `${prefix}Params`
  const FETCH_PARAMS = `${prefix}FetchParams`
  const WATCH = `${prefix}Watch`
  const QUERY_WHEN = `${prefix}QueryWhen`
  const FIND_ACTION = `find${capitalized}`
  const PAGINATION = `${prefix}PaginationData`
  const LOCAL = `${prefix}Local`
  const QID = `${prefix}Qid`
  const data = {
    [IS_FIND_PENDING]: false,
    [WATCH]: watch,
    [QID]: qid
  }

  const mixin = {
    data () {
      return data
    },
    computed: {
      [ITEMS] () {
        return this[PARAMS] ? this.$store.getters[`${this[SERVICE_NAME]}/find`](this[PARAMS]).data : []
      },
      [ITEMS_FETCHED] () {
        if (this[FETCH_PARAMS]) {
          return this.$store.getters[`${this[SERVICE_NAME]}/find`](this[FETCH_PARAMS]).data
        } else {
          return this[ITEMS]
        }
      }
    },
    methods: {
      [FIND_ACTION] (params) {
        const paramsToUse = params || this[FETCH_PARAMS] || this[PARAMS]

        if (!this[LOCAL]) {
          if (typeof this[QUERY_WHEN] === 'function' ? this[QUERY_WHEN](paramsToUse) : this[QUERY_WHEN]) {
            this[IS_FIND_PENDING] = true

            if (paramsToUse) {
              paramsToUse.query = paramsToUse.query || {}

              if (qid) {
                paramsToUse.qid = qid
              }

              return this.$store.dispatch(`${this[SERVICE_NAME]}/find`, paramsToUse)
                .then(() => {
                  this[IS_FIND_PENDING] = false
                })
            }
          }
        }
      }
    },
    created () {
      debug && console.log(`running 'created' hook in makeFindMixin for service "${service}" (using name ${nameToUse}")`)
      debug && console.log(PARAMS, this[PARAMS])
      debug && console.log(FETCH_PARAMS, this[FETCH_PARAMS])

      const pType = Object.getPrototypeOf(this)

      if (pType.hasOwnProperty(PARAMS) || pType.hasOwnProperty(FETCH_PARAMS)) {
        watch.forEach(prop => {
          if (typeof prop !== 'string') {
            throw new Error(`Values in the 'watch' array must be strings.`)
          }
          prop = prop.replace('params', PARAMS)

          if (pType.hasOwnProperty(FETCH_PARAMS)) {
            if (prop.startsWith(PARAMS)) {
              prop = prop.replace(PARAMS, FETCH_PARAMS)
            }
          }
          this.$watch(prop, this[FIND_ACTION])
        })

        return this[FIND_ACTION]()
      } else {
        if (!local) {
          // TODO: Add this message to the logging:
          //       "Pass { local: true } to disable this warning and only do local queries."
          console.log(`No "${PARAMS}" or "${FETCH_PARAMS}" attribute was found in the makeFindMixin for the "${service}" service (using name "${nameToUse}").  No queries will be made.`)
        }
      }
    }
  }

  if (qid) {
    mixin.computed[PAGINATION] = function () {
      return this.$store.state[this[SERVICE_NAME]].pagination[qid]
    }
  }

  setupAttribute(SERVICE_NAME, service, 'computed', true)
  setupAttribute(PARAMS, params)
  setupAttribute(FETCH_PARAMS, fetchQuery)
  setupAttribute(QUERY_WHEN, queryWhen, 'methods')
  setupAttribute(LOCAL, local)

  function setupAttribute (NAME, value, computedOrMethods = 'computed', returnTheValue = false) {
    if (typeof value === 'boolean') {
      data[NAME] = !!value
    } else if (typeof value === 'string') {
      mixin.computed[NAME] = function () {
        // If the specified computed prop wasn't found, display an error.
        if (returnTheValue) {

        } else {
          if (!hasSomeAttribute(this, value, NAME)) {
            throw new Error(`Value for ${NAME} was not found on the component at '${value}'.`)
          }
        }
        return returnTheValue ? value : this[value]
      }
    } else if (typeof value === 'function') {
      mixin[computedOrMethods][NAME] = value
    }
  }

  function hasSomeAttribute (vm, ...attributes) {
    return attributes.some(a => {
      return vm.hasOwnProperty(a) || Object.getPrototypeOf(vm).hasOwnProperty(a)
    })
  }

  return mixin
}
<commit_msg>Fix nonexistent import<commit_after>import { getServicePrefix, getServiceCapitalization } from './utils'

export default function makeFindMixin (options) {
  const { service, params, fetchQuery, queryWhen = () => true, local = false, qid = 'default', items, debug } = options
  let { name, watch = [] } = options

  if (typeof watch === 'string') {
    watch = [watch]
  } else if (typeof watch === 'boolean' && watch) {
    watch = ['params']
  }

  if (!service || (typeof service !== 'string' && typeof service !== 'function')) {
    throw new Error(`The 'service' option is required in the FeathersVuex make-find-mixin and must be a string.`)
  }
  if (typeof service === 'function' && !name) {
    name = 'service'
  }

  const nameToUse = (name || service).replace('-', '_')
  const prefix = getServicePrefix(nameToUse)
  const capitalized = getServiceCapitalization(nameToUse)
  const SERVICE_NAME = `${prefix}ServiceName`
  let ITEMS = items || prefix
  if (typeof service === 'function' && name === 'service' && !items) {
    ITEMS = 'items'
  }
  const ITEMS_FETCHED = `${ITEMS}Fetched`
  const IS_FIND_PENDING = `isFind${capitalized}Pending`
  const PARAMS = `${prefix}Params`
  const FETCH_PARAMS = `${prefix}FetchParams`
  const WATCH = `${prefix}Watch`
  const QUERY_WHEN = `${prefix}QueryWhen`
  const FIND_ACTION = `find${capitalized}`
  const PAGINATION = `${prefix}PaginationData`
  const LOCAL = `${prefix}Local`
  const QID = `${prefix}Qid`
  const data = {
    [IS_FIND_PENDING]: false,
    [WATCH]: watch,
    [QID]: qid
  }

  const mixin = {
    data () {
      return data
    },
    computed: {
      [ITEMS] () {
        return this[PARAMS] ? this.$store.getters[`${this[SERVICE_NAME]}/find`](this[PARAMS]).data : []
      },
      [ITEMS_FETCHED] () {
        if (this[FETCH_PARAMS]) {
          return this.$store.getters[`${this[SERVICE_NAME]}/find`](this[FETCH_PARAMS]).data
        } else {
          return this[ITEMS]
        }
      }
    },
    methods: {
      [FIND_ACTION] (params) {
        const paramsToUse = params || this[FETCH_PARAMS] || this[PARAMS]

        if (!this[LOCAL]) {
          if (typeof this[QUERY_WHEN] === 'function' ? this[QUERY_WHEN](paramsToUse) : this[QUERY_WHEN]) {
            this[IS_FIND_PENDING] = true

            if (paramsToUse) {
              paramsToUse.query = paramsToUse.query || {}

              if (qid) {
                paramsToUse.qid = qid
              }

              return this.$store.dispatch(`${this[SERVICE_NAME]}/find`, paramsToUse)
                .then(() => {
                  this[IS_FIND_PENDING] = false
                })
            }
          }
        }
      }
    },
    created () {
      debug && console.log(`running 'created' hook in makeFindMixin for service "${service}" (using name ${nameToUse}")`)
      debug && console.log(PARAMS, this[PARAMS])
      debug && console.log(FETCH_PARAMS, this[FETCH_PARAMS])

      const pType = Object.getPrototypeOf(this)

      if (pType.hasOwnProperty(PARAMS) || pType.hasOwnProperty(FETCH_PARAMS)) {
        watch.forEach(prop => {
          if (typeof prop !== 'string') {
            throw new Error(`Values in the 'watch' array must be strings.`)
          }
          prop = prop.replace('params', PARAMS)

          if (pType.hasOwnProperty(FETCH_PARAMS)) {
            if (prop.startsWith(PARAMS)) {
              prop = prop.replace(PARAMS, FETCH_PARAMS)
            }
          }
          this.$watch(prop, this[FIND_ACTION])
        })

        return this[FIND_ACTION]()
      } else {
        if (!local) {
          // TODO: Add this message to the logging:
          //       "Pass { local: true } to disable this warning and only do local queries."
          console.log(`No "${PARAMS}" or "${FETCH_PARAMS}" attribute was found in the makeFindMixin for the "${service}" service (using name "${nameToUse}").  No queries will be made.`)
        }
      }
    }
  }

  if (qid) {
    mixin.computed[PAGINATION] = function () {
      return this.$store.state[this[SERVICE_NAME]].pagination[qid]
    }
  }

  setupAttribute(SERVICE_NAME, service, 'computed', true)
  setupAttribute(PARAMS, params)
  setupAttribute(FETCH_PARAMS, fetchQuery)
  setupAttribute(QUERY_WHEN, queryWhen, 'methods')
  setupAttribute(LOCAL, local)

  function setupAttribute (NAME, value, computedOrMethods = 'computed', returnTheValue = false) {
    if (typeof value === 'boolean') {
      data[NAME] = !!value
    } else if (typeof value === 'string') {
      mixin.computed[NAME] = function () {
        // If the specified computed prop wasn't found, display an error.
        if (returnTheValue) {

        } else {
          if (!hasSomeAttribute(this, value, NAME)) {
            throw new Error(`Value for ${NAME} was not found on the component at '${value}'.`)
          }
        }
        return returnTheValue ? value : this[value]
      }
    } else if (typeof value === 'function') {
      mixin[computedOrMethods][NAME] = value
    }
  }

  function hasSomeAttribute (vm, ...attributes) {
    return attributes.some(a => {
      return vm.hasOwnProperty(a) || Object.getPrototypeOf(vm).hasOwnProperty(a)
    })
  }

  return mixin
}
<|endoftext|>


<commit_before>import Sound from '../Sound'
import Display from '../Display'

class Manager {
  constructor({sound=[], display=[]}){
    this.currentAct = null

    this.sound = new Sound(...sound)
    this.display = new Display(...display)
  }

  connect(act){
    if(this.currentAct) this.disconnect(this.currentAct)

    const outputs = {
      display: this.display,
      sound: this.sound
    }

    act.start(outputs, next => (next ? this.connect(next) : this.disconnect(act)))

    this.currentAct = act
  }

  disconnect(act){
    if(act === this.currentAct){
      this.currentAct.end(true)

      if(this.sound.running) this.sound.pause()
      this.sound.removeAllListeners()
      this.display.reset()

      this.currentView = null
    }
  }
}

export default Manager
<commit_msg>🗑 Redundant Code<commit_after>import Sound from '../Sound'
import Display from '../Display'

class Manager {
  constructor({sound=[], display=[]}){
    this.currentAct = null

    this.sound = new Sound(...sound)
    this.display = new Display(...display)
  }

  connect(act){
    if(this.currentAct) this.disconnect(this.currentAct)

    const outputs = {
      display: this.display,
      sound: this.sound
    }

    act.start(outputs, next => (next ? this.connect(next) : this.disconnect(act)))

    this.currentAct = act
  }

  disconnect(act){
    if(act === this.currentAct){
      this.currentAct.end(true)

      this.sound.removeAllListeners()
      this.display.reset()

      this.currentView = null
    }
  }
}

export default Manager
<|endoftext|>


<commit_before>const fs      = require('fs');

function loadMappings(config, mappings) {
    let count = 0;

    let storageConfig = config.storage;

	let mappingsDir;
	if(storageConfig.engine == 'fs') {
		mappingsDir = storageConfig.mappings;
		if(Array.isArray(mappingsDir)){
			mappingsDir.forEach(function(value, index){
				var dir = process.cwd() + '/' + value;

				var mappingFiles = fs.readdirSync(dir);

				// Read js file only.
				var dataFiles = mappingFiles.filter((f)=>{
				    return f.endsWith('.js');
				});

				for (var file of dataFiles) {
					let data = require(dir + '/' + file);
					if(data.mappings) {
						data.mappings.forEach(function(value, index){
							for(let url in value) {
								mappings[url] = value[url];
                                if(!(mappings[url].state)) {
                                    mappings[url].state = 'success';
                                }
                                if(mappings[url].count == undefined) {
                                    mappings[url].count = 1;
                                }
                                count++;
							}
						});
					}
				}
			});
		}
	}

    return count;
}

module.exports = {
    "loadMappings" : loadMappings
}
<commit_msg>Refact mappings loader. (Unfinished)<commit_after>const fs      = require('fs');

function loadMappings(config, mappings) {
    let count = 0;

    let storageConfig = config.storage;

	let mappingsDir;
	if(storageConfig.engine == 'fs') {
		mappingsDir = storageConfig.mappings;
		if(Array.isArray(mappingsDir)){
			mappingsDir.forEach(function(value, index){
				var dir = process.cwd() + '/' + value;

				var mappingFiles = fs.readdirSync(dir);

				// Read js file only.
				var dataFiles = mappingFiles.filter((f)=>{
				    return f.endsWith('.js');
				});

				for (var file of dataFiles) {
					let data = require(dir + '/' + file);
					if(data.mappings) {
						data.mappings.forEach(function(value, index){
							for(let url in value) {
								mappings[url] = value[url];
                                if(!(mappings[url].state)) {
                                    mappings[url].state = 'success';
                                }
                                if(mappings[url].count == undefined) {
                                    mappings[url].count = 1;
                                }
                                count++;
							}
						});
					}
				}
			});
		}
	}

    return count;
}

function parseMapping(filepath, mappings) {
    let data = require(filepath);
    if(data.mappings) {
        let count = 0;
        data.mappings.forEach(function(value, index){
            for(let url in value) {
                mappings[url] = value[url];
                if(!(mappings[url].state)) {
                    mappings[url].state = 'success';
                }
                if(mappings[url].count == undefined) {
                    mappings[url].count = 1;
                }
                count++;
            }
        });
    }
    return count;
}

module.exports = {
    "loadMappings" : loadMappings
}
<|endoftext|>


<commit_before>import { MatrixError } from './matrix';

function identity(size) {
    if (size && size >= 0) {
        var matrix = [];
        for (var i = 0; i < size; i++) {
            matrix.push([]);
            for (var j = 0; j < size; j++) {
                matrix[i][j] = i === j ? 1 : 0;
            }
        }
        return matrix;
    }
    throw new MatrixError('Invalid matrix dimensions given.');
}

/* eslint no-extend-native: "off" */
Array.prototype.identity = function matrixIdentity() {
    return identity(this);
};

module.exports = identity;
<commit_msg>fix conditional bug in identity function<commit_after>import { MatrixError } from './matrix';

function identity(size) {
    if (size !== undefined && size >= 0) {
        var matrix = [];
        for (var i = 0; i < size; i++) {
            matrix.push([]);
            for (var j = 0; j < size; j++) {
                matrix[i][j] = i === j ? 1 : 0;
            }
        }
        return matrix;
    }
    throw new MatrixError('Invalid matrix dimensions given.');
}

/* eslint no-extend-native: "off" */
Array.prototype.identity = function matrixIdentity() {
    return identity(this);
};

module.exports = identity;
<|endoftext|>


<commit_before>// Calculate Restack BB codes
if (location.href.indexOf('type=there') > -1) {
    $("#defRestack").click(function () {
        trackClickEvent("BBCodeOutput");
        $("#calculateStack").click();

        var request = "";
        $("#units_table").find(overviewMenuRowFilter).each(function () {
            var total = parseInt($("td:eq(1)", $(this)).text().replace(/\./, ''), 10);
            if (user_data.restack.to - total > user_data.restack.requiredDifference) {
                var villageCoord = getVillageFromCoords($(this).find("td:first span[id*='label_']").text());
                request += "[village]" + villageCoord.coord + "[/village] (" + parseInt((user_data.restack.to - total) / 1000, 10) + "k)\n";
            }
        });

        if ($("#textsArea").size() == 0) {
            $(this).parent().parent().parent().append("

");
        } else {
            $("#textsArea").html("");
        }

        var title = trans.sp.troopOverview.restackTitle
            .replace("{to}", parseInt(user_data.restack.to / 1000, 10))
            .replace("{requiredDiff}", parseInt(user_data.restack.requiredDifference / 1000, 10));
        $("#textsArea").append(title + "
<textarea cols=35 rows=10 id=defRestackArea>" + request + "</textarea>");

        $("#textsArea").append("
<input type=button value='" + trans.sp.all.close + "' id=closeTextsArea>");
        $("#closeTextsArea").click(function() {
            $("#textsArea").parent().remove();
        });
    });
}<commit_msg>fix for bb code generation in troops overview - in the village<commit_after>// Calculate Restack BB codes
if (location.href.indexOf('type=there') > -1) {
    $("#defRestack").click(function () {
        trackClickEvent("BBCodeOutput");
        $("#calculateStack").click();

        var request = "";
        $("#units_table").find(overviewMenuRowFilter).each(function () {
            var total = parseInt($("td:eq(1)", $(this)).text().replace(/\./, ''), 10);
            if (user_data.restack.to - total > user_data.restack.requiredDifference) {
                var villageDesc = $(this).find("td:first span[data-text]").text(),
                    villageCoord = getVillageFromCoords(villageDesc);

                request += "[village]" + villageCoord.coord + "[/village] (" + parseInt((user_data.restack.to - total) / 1000, 10) + "k)\n";
            }
        });

        if ($("#textsArea").size() == 0) {
            $(this).parent().parent().parent().append("

");
        } else {
            $("#textsArea").html("");
        }

        var title = trans.sp.troopOverview.restackTitle
            .replace("{to}", parseInt(user_data.restack.to / 1000, 10))
            .replace("{requiredDiff}", parseInt(user_data.restack.requiredDifference / 1000, 10));
        $("#textsArea").append(title + "
<textarea cols=35 rows=10 id=defRestackArea>" + request + "</textarea>");

        $("#textsArea").append("
<input type=button value='" + trans.sp.all.close + "' id=closeTextsArea>");
        $("#closeTextsArea").click(function() {
            $("#textsArea").parent().remove();
        });
    });
}<|endoftext|>


<commit_before>/* eslint-disable func-names, prefer-arrow-callback */

import { SimpleSchema } from './SimpleSchema';
import expect from 'expect';

describe('SimpleSchema', function () {
  describe('oneOf', function () {
    it('allows either type', function () {
      const schema = new SimpleSchema({
        foo: SimpleSchema.oneOf(String, Number),
      });

      expect(function () {
        schema.validate({ foo: 1 });
      }).toNotThrow();

      expect(function () {
        schema.validate({ foo: 'bar' });
      }).toNotThrow();

      expect(function () {
        schema.validate({ foo: false });
      }).toThrow();
    });

    it('is valid as long as one min value is met', function () {
      const schema = new SimpleSchema({
        foo: SimpleSchema.oneOf({
          type: SimpleSchema.Integer,
          min: 5,
        }, {
          type: SimpleSchema.Integer,
          min: 10,
        }),
      });

      expect(function () {
        schema.validate({ foo: 7 });
      }).toNotThrow();
    });

    it('is invalid if neither min value is met', function () {
      const schema = new SimpleSchema({
        foo: SimpleSchema.oneOf({
          type: SimpleSchema.Integer,
          min: 5,
        }, {
          type: SimpleSchema.Integer,
          min: 10,
        }),
      });

      expect(function () {
        schema.validate({ foo: 3 });
      }).toThrow();
    });
  });
});
<commit_msg>Add test for 112<commit_after>/* eslint-disable func-names, prefer-arrow-callback */

import { SimpleSchema } from './SimpleSchema';
import expect from 'expect';

describe('SimpleSchema', function () {
  describe('oneOf', function () {
    it('allows either type', function () {
      const schema = new SimpleSchema({
        foo: SimpleSchema.oneOf(String, Number),
      });

      expect(function () {
        schema.validate({ foo: 1 });
      }).toNotThrow();

      expect(function () {
        schema.validate({ foo: 'bar' });
      }).toNotThrow();

      expect(function () {
        schema.validate({ foo: false });
      }).toThrow();
    });

    it.skip('allows either type including schemas', function () {
      const schemaOne = new SimpleSchema({
        itemRef: String,
        partNo: String,
      });

      const schemaTwo = new SimpleSchema({
        anotherIdentifier: String,
        partNo: String,
      });

      const combinedSchema = new SimpleSchema({
        item: SimpleSchema.oneOf(String, schemaOne, schemaTwo),
      });

      let isValid = combinedSchema.namedContext().validate({
        item: 'foo',
      });
      console.log(combinedSchema.namedContext().validationErrors());
      expect(isValid).toBe(true);

      isValid = combinedSchema.namedContext().validate({
        item: {
          anotherIdentifier: 'hhh',
          partNo: 'ttt',
        },
      });
      console.log(combinedSchema.namedContext().validationErrors());
      expect(isValid).toBe(true);

      isValid = combinedSchema.namedContext().validate({
        item: {
          itemRef: 'hhh',
          partNo: 'ttt',
        },
      });
      console.log(combinedSchema.namedContext().validationErrors());
      expect(isValid).toBe(true);
    });

    it('is valid as long as one min value is met', function () {
      const schema = new SimpleSchema({
        foo: SimpleSchema.oneOf({
          type: SimpleSchema.Integer,
          min: 5,
        }, {
          type: SimpleSchema.Integer,
          min: 10,
        }),
      });

      expect(function () {
        schema.validate({ foo: 7 });
      }).toNotThrow();
    });

    it('is invalid if neither min value is met', function () {
      const schema = new SimpleSchema({
        foo: SimpleSchema.oneOf({
          type: SimpleSchema.Integer,
          min: 5,
        }, {
          type: SimpleSchema.Integer,
          min: 10,
        }),
      });

      expect(function () {
        schema.validate({ foo: 3 });
      }).toThrow();
    });
  });
});
<|endoftext|>