<commit_before>Template.boardMenuPopup.events({
  'click .js-rename-board': Popup.open('boardChangeTitle'),
  'click .js-open-archives': function() {
    Sidebar.setView('archives');
    Popup.close();
  },
  'click .js-change-board-color': Popup.open('boardChangeColor'),
  'click .js-change-language': Popup.open('setLanguage')
});

Template.boardChangeTitlePopup.events({
  submit: function(evt, t) {
    var title = t.$('.js-board-name').val().trim();
    if (title) {
      Boards.update(this._id, {
        $set: {
          title: title
        }
      });
      Popup.close();
    }
    evt.preventDefault();
  }
});

BlazeComponent.extendComponent({
  template: function() {
    return 'headerBoard';
  },

  isStarred: function() {
    var currentBoard  = this.currentData();
    var user = Meteor.user();
    return currentBoard && user && user.hasStarred(currentBoard._id);
  },

  // Only show the star counter if the number of star is greater than 2
  showStarCounter: function() {
    var currentBoard = this.currentData();
    return currentBoard && currentBoard.stars >= 2;
  },

  events: function() {
    return [{
      'click .js-edit-board-title': Popup.open('boardChangeTitle'),
      'click .js-star-board': function() {
        Meteor.user().toggleBoardStar(Session.get('currentBoard'));
      },
      'click .js-open-board-menu': Popup.open('boardMenu'),
      'click .js-change-visibility': Popup.open('boardChangeVisibility'),
      'click .js-open-filter-view': function() {
        Sidebar.setView('filter');
      },
      'click .js-filter-reset': function(evt) {
        evt.stopPropagation();
        Sidebar.setView();
        Filter.reset();
      },
      'click .js-multiselection-activate': function() {
        var currentCard = Session.get('currentCard');
        MultiSelection.activate();
        if (currentCard) {
          MultiSelection.add(currentCard);
        }
      },
      'click .js-multiselection-reset': function(evt) {
        evt.stopPropagation();
        MultiSelection.disable();
      }
    }];
  }
}).register('headerBoard');

BlazeComponent.extendComponent({
  template: function() {
    return 'boardChangeColorPopup';
  },

  backgroundColors: function() {
    return Boards.simpleSchema()._schema.color.allowedValues;
  },

  isSelected: function() {
    var currentBoard = Boards.findOne(Session.get('currentBoard'));
    return currentBoard.color === this.currentData().toString();
  },

  events: function() {
    return [{
      'click .js-select-background': function(evt) {
        var currentBoardId = Session.get('currentBoard');
        Boards.update(currentBoardId, {
          $set: {
            color: this.currentData().toString()
          }
        });
        evt.preventDefault();
      }
    }];
  }
}).register('boardChangeColorPopup');

BlazeComponent.extendComponent({
  template: function() {
    return 'createBoardPopup';
  },

  onCreated: function() {
    this.visibilityMenuIsOpen = new ReactiveVar(false);
    this.visibility = new ReactiveVar('private');
  },

  visibilityCheck: function() {
    return this.currentData() === this.visibility.get();
  },

  setVisibility: function(visibility) {
    this.visibility.set(visibility);
    this.visibilityMenuIsOpen.set(false);
  },

  toogleVisibilityMenu: function() {
    this.visibilityMenuIsOpen.set(! this.visibilityMenuIsOpen.get());
  },

  onSubmit: function(evt) {
    evt.preventDefault();
    var title = this.find('.js-new-board-title').value;
    var visibility = this.visibility.get();

    var boardId = Boards.insert({
      title: title,
      permission: visibility
    });

    Utils.goBoardId(boardId);
  },

  events: function() {
    return [{
      'click .js-select-visibility': function() {
        this.setVisibility(this.currentData());
      },
      'click .js-change-visibility': this.toogleVisibilityMenu,
      submit: this.onSubmit
    }];
  }
}).register('createBoardPopup');

BlazeComponent.extendComponent({
  template: function() {
    return 'boardChangeVisibilityPopup';
  },

  visibilityCheck: function() {
    var currentBoard = Boards.findOne(Session.get('currentBoard'));
    return this.currentData() === currentBoard.permission;
  },

  selectBoardVisibility: function() {
    Boards.update(Session.get('currentBoard'), {
      $set: {
        permission: this.currentData()
      }
    });
    Popup.close();
  },

  events: function() {
    return [{
      'click .js-select-visibility': this.selectBoardVisibility
    }];
  }
}).register('boardChangeVisibilityPopup');
<commit_msg>Automatically star new boards created with the header shortcut<commit_after>Template.boardMenuPopup.events({
  'click .js-rename-board': Popup.open('boardChangeTitle'),
  'click .js-open-archives': function() {
    Sidebar.setView('archives');
    Popup.close();
  },
  'click .js-change-board-color': Popup.open('boardChangeColor'),
  'click .js-change-language': Popup.open('setLanguage')
});

Template.boardChangeTitlePopup.events({
  submit: function(evt, t) {
    var title = t.$('.js-board-name').val().trim();
    if (title) {
      Boards.update(this._id, {
        $set: {
          title: title
        }
      });
      Popup.close();
    }
    evt.preventDefault();
  }
});

BlazeComponent.extendComponent({
  template: function() {
    return 'headerBoard';
  },

  isStarred: function() {
    var currentBoard  = this.currentData();
    var user = Meteor.user();
    return currentBoard && user && user.hasStarred(currentBoard._id);
  },

  // Only show the star counter if the number of star is greater than 2
  showStarCounter: function() {
    var currentBoard = this.currentData();
    return currentBoard && currentBoard.stars >= 2;
  },

  events: function() {
    return [{
      'click .js-edit-board-title': Popup.open('boardChangeTitle'),
      'click .js-star-board': function() {
        Meteor.user().toggleBoardStar(Session.get('currentBoard'));
      },
      'click .js-open-board-menu': Popup.open('boardMenu'),
      'click .js-change-visibility': Popup.open('boardChangeVisibility'),
      'click .js-open-filter-view': function() {
        Sidebar.setView('filter');
      },
      'click .js-filter-reset': function(evt) {
        evt.stopPropagation();
        Sidebar.setView();
        Filter.reset();
      },
      'click .js-multiselection-activate': function() {
        var currentCard = Session.get('currentCard');
        MultiSelection.activate();
        if (currentCard) {
          MultiSelection.add(currentCard);
        }
      },
      'click .js-multiselection-reset': function(evt) {
        evt.stopPropagation();
        MultiSelection.disable();
      }
    }];
  }
}).register('headerBoard');

BlazeComponent.extendComponent({
  template: function() {
    return 'boardChangeColorPopup';
  },

  backgroundColors: function() {
    return Boards.simpleSchema()._schema.color.allowedValues;
  },

  isSelected: function() {
    var currentBoard = Boards.findOne(Session.get('currentBoard'));
    return currentBoard.color === this.currentData().toString();
  },

  events: function() {
    return [{
      'click .js-select-background': function(evt) {
        var currentBoardId = Session.get('currentBoard');
        Boards.update(currentBoardId, {
          $set: {
            color: this.currentData().toString()
          }
        });
        evt.preventDefault();
      }
    }];
  }
}).register('boardChangeColorPopup');

BlazeComponent.extendComponent({
  template: function() {
    return 'createBoardPopup';
  },

  onCreated: function() {
    this.visibilityMenuIsOpen = new ReactiveVar(false);
    this.visibility = new ReactiveVar('private');
  },

  visibilityCheck: function() {
    return this.currentData() === this.visibility.get();
  },

  setVisibility: function(visibility) {
    this.visibility.set(visibility);
    this.visibilityMenuIsOpen.set(false);
  },

  toogleVisibilityMenu: function() {
    this.visibilityMenuIsOpen.set(! this.visibilityMenuIsOpen.get());
  },

  onSubmit: function(evt) {
    evt.preventDefault();
    var title = this.find('.js-new-board-title').value;
    var visibility = this.visibility.get();

    var boardId = Boards.insert({
      title: title,
      permission: visibility
    });

    Utils.goBoardId(boardId);

    // Immediately star boards crated with the headerbar popup.
    Meteor.user().toggleBoardStar(boardId);
  },

  events: function() {
    return [{
      'click .js-select-visibility': function() {
        this.setVisibility(this.currentData());
      },
      'click .js-change-visibility': this.toogleVisibilityMenu,
      submit: this.onSubmit
    }];
  }
}).register('createBoardPopup');

BlazeComponent.extendComponent({
  template: function() {
    return 'boardChangeVisibilityPopup';
  },

  visibilityCheck: function() {
    var currentBoard = Boards.findOne(Session.get('currentBoard'));
    return this.currentData() === currentBoard.permission;
  },

  selectBoardVisibility: function() {
    Boards.update(Session.get('currentBoard'), {
      $set: {
        permission: this.currentData()
      }
    });
    Popup.close();
  },

  events: function() {
    return [{
      'click .js-select-visibility': this.selectBoardVisibility
    }];
  }
}).register('boardChangeVisibilityPopup');
<|endoftext|>


<commit_before>// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.<commit_msg>Add new functions for display 2 charts on a page and create pagination<commit_after>// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Sets the page to always display the first two elements when loading the page.
var secondChart = 2;
var firstChart = 0;

google.charts.load('current', {'packages':['bar', 'table']});

// Retrieves a list of avaliable keyword campaigns the user has stored and is used in
// dropdown menu.
function getKeywordCampaigns() {
	const keywordCampaignList = document.getElementById('keyword-campaigns');
    keywordCampaignList.innerHTML = '<option value=0>Select a keyword campaign</option>';

    fetch('/keyword-campaigns').then(response => response.json()).then(keywordCampaigns => {
        keywordCampaigns.forEach(keywordCampaign => {
            keywordCampaignList.innerHTML += '<option value=' + keywordCampaign.keywordCampaignId + '>' + keywordCampaign.name  + '</option>';
        });
    });
}

// Checks if user has selected a keyword campaign. If the user has selected a keyword
// then the for loop draws 2 graphs and creates pagination to explore other charts.
function getDSACampaigns() {
    const DSACampaignsList = document.getElementById('DSA-campaigns');
    DSACampaignsList.innerHTML = '
First select a keyword campaign.
';
    var keywordCampaignId = document.getElementById("keyword-campaigns").value;

    if (keywordCampaignId != 0) {
        DSACampaignsList.innerHTML = '';

        fetch('/DSA-campaigns?keywordCampaignId=' + keywordCampaignId).then(response => response.json()).then(DSACampaigns => {

            for(var i = firstChart; i < secondChart; i++ ){
                drawNewBarGraph(DSACampaigns[i], secondChart-i);
            }
            if (firstChart == 0)
                makePagination((DSACampaigns.length / 2) + (DSACampaigns.length % 2), (Math.log(firstChart + 1)/Math.log(2)));
            else
                makePagination((DSACampaigns.length / 2) + (DSACampaigns.length % 2), (Math.log(firstChart)/Math.log(2)));

        });
    }
}

// Creates pagination html for the user to see other charts by taking the existing number of pages
// and the active page the user is on.
function makePagination(numberOfPages,activeNumber) {
    const pagination = document.getElementById("pagination");
    var paginationString = "";
    paginationString += "<input type=\"button\" id=\"previous\" onclick=\"previousPage()\" value=\"previous\" />";
    paginationString += "  " + (activeNumber + 1)  +"  ";
    paginationString += "<input type=\"button\" id=\"next\" onclick=\"nextPage(" + numberOfPages + ")\" value=\"next\" />";
    pagination.innerHTML = paginationString;
}

// Increases the page forward by increasing the active page by one and letting the display
// charts increase to the next two and rerunning getDSACampaigns to retrieve the charts.
function nextPage(numberOfPages) {
    const activePage = document.getElementById("activeNumber");
    var increasePage = parseInt(activePage.innerText);

    // The if statement checks if the user clicks nextpage but there is
    // no more charts to look at using numberOfPages.
    if(increasePage + 1 <= numberOfPages){
        increasePage++;
        secondChart += 2;
        firstChart += 2;
    }
    activePage.innerText = increasePage;
    getDSACampaigns();
}

// Decreases the page backward by decreasing the active page by one and letting the display
// charts decrease to the previous two and rerunning getDSACampaigns to retrieve the charts.
function previousPage() {
    const activePage = document.getElementById("activeNumber");
    var decreasePage = parseInt(activePage.innerText);

    // The if statement checks if the user clicks previousPage but there is
    // no more charts to look at using 0 because there are no negative pages.
    if(decreasePage - 1 > 0){
        decreasePage--;
        secondChart -= 2;
        firstChart -= 2;
    }
    activePage.innerText = decreasePage;
    getDSACampaigns();
}

function drawNewBarGraph(DSACampaign, chartNumber) {

    var data = new google.visualization.DataTable();
    data.addColumn('string', 'DSA Campaign');
    data.addColumn('number', 'Impressions');
    data.addColumn('number', 'Clicks');
    data.addColumn('number', 'Cost (USD)');

    data.addRow([DSACampaign.name, DSACampaign.impressions, DSACampaign.clicks, DSACampaign.cost]);

    var options = {
        chart: {
            title: 'Statistics',
            subtitle: 'Impressions, Clicks, and Cost',
        },
        bars: 'horizontal' // Required for Material Bar Charts.
    };

    var chart = new google.charts.Bar(document.getElementById('bar-chart' + chartNumber));
    chart.draw(data, google.charts.Bar.convertOptions(options));
    console.log("Drew bar graph.");

    drawNewTable(DSACampaign, chartNumber);
}

function drawNewTable(DSACampaign, chartNumber) {

    var data = new google.visualization.DataTable();
    data.addColumn('string', 'DSA Campaign');
    data.addColumn('string', 'Start Date');
    data.addColumn('string', 'End Date');
    data.addColumn('number', 'Daily Budget');
    data.addColumn('string', 'Location');
    data.addColumn('string', 'Domain');
    data.addColumn('string', 'Target');
    data.addColumn('number', 'Impressions');
    data.addColumn('number', 'Clicks');
    data.addColumn('number', 'Cost (USD)');

    data.addRow([DSACampaign.name, DSACampaign.fromDate, DSACampaign.toDate, DSACampaign.dailyBudget, DSACampaign.location,
    DSACampaign.domain, DSACampaign.target, DSACampaign.impressions, DSACampaign.clicks, DSACampaign.cost]);

    var table = new google.visualization.Table(document.getElementById('table' + chartNumber));
    table.draw(data, {showRowNumber: true, width: '100%', height: '100%'});

    console.log("Drew table.");
}<|endoftext|>


<commit_before>/*
 * Waltz - Enterprise Architecture
 * Copyright (C) 2016  Khartec Ltd.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

function store($http,
                 BaseApiUrl) {
    const BASE = `${BaseApiUrl}/person`;

    const getByEmployeeId = (empId) => $http
        .get(`${BASE}/employee-id/${empId}`)
        .then(result => result.data);

    const findByUserId = (userId) => $http
        .get(`${BASE}/user-id/${userId}`)
        .then(result => result.data);

    const getById = (id) => $http
        .get(`${BASE}/id/${id}`)
        .then(result => result.data);

    const findDirects = (empId) => $http
        .get(`${BASE}/employee-id/${empId}/directs`)
        .then(result => result.data);

    const findManagers = (empId) => $http
        .get(`${BASE}/employee-id/${empId}/managers`)
        .then(result => result.data);

    const search = (query) => $http
        .get(`${BASE}/search/${query}`)
        .then(x => x.data);

    return {
        getByEmployeeId,
        getById,
        findByUserId,
        findDirects,
        findManagers,
        search
    };
}

store.$inject = [
    '$http',
    'BaseApiUrl'
];

export default store;
<commit_msg>Survey: should display 'unknown' for owners no longer exist<commit_after>/*
 * Waltz - Enterprise Architecture
 * Copyright (C) 2016  Khartec Ltd.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

function store($http,
                 BaseApiUrl) {
    const BASE = `${BaseApiUrl}/person`;

    const unknownPerson = (id, displayName = 'Unknown') => {
        return {
            id: id,
            displayName: displayName
        }
    };

    const getByEmployeeId = (empId) => $http
        .get(`${BASE}/employee-id/${empId}`)
        .then(result => result.data);

    const findByUserId = (userId) => $http
        .get(`${BASE}/user-id/${userId}`)
        .then(result => result.data);

    const getById = (id) => $http
        .get(`${BASE}/id/${id}`)
        .then(result => (result.data)? result.data : unknownPerson(id));

    const findDirects = (empId) => $http
        .get(`${BASE}/employee-id/${empId}/directs`)
        .then(result => result.data);

    const findManagers = (empId) => $http
        .get(`${BASE}/employee-id/${empId}/managers`)
        .then(result => result.data);

    const search = (query) => $http
        .get(`${BASE}/search/${query}`)
        .then(x => x.data);

    return {
        getByEmployeeId,
        getById,
        findByUserId,
        findDirects,
        findManagers,
        search
    };
}

store.$inject = [
    '$http',
    'BaseApiUrl'
];

export default store;
<|endoftext|>


<commit_before>var express = require('express');
var bodyParser = require('body-parser');
var cors = require('cors');
var mbaasApi = require('fh-mbaas-api');
var mbaasExpress = mbaasApi.mbaasExpress();
var queryString = require('querystring');
var request = require('request');

function auth() {
  var router = express.Router();

  router.all('/init', function(req, res) {
        var params = req.body; // params.userId params.password
        if (params && params.userId) {
          console.log('Checking credentials for user ' + params.userId);
          initSession(params.userId, function(err, result){
            if (err) {
              console.log('Invalid credentials for user ' + params.userId);
              res.status(400);
              res.json({message: 'Invalid credentials'});
              return;
            } else {
              res.json({
                status: 'ok',
                userId: params.userId,
                sessionToken: result + '_sessiontoken',
                authResponse: result
              });
              return;
            }
          });

        } else {
          res.status(400);
          res.json({message: params.userId});
        }

  });

  /**
   * Validate the user's session info with Google, and create a session object.
   * This will also create a account object if necessary.
   *
   * @param {String} idToken an idToken provided by an Android Client (see : https://developers.google.com/identity/sign-in/android/backend-auth)
   * @param {Callback} nodeCallback a node callback
   */
  function initSession(idToken, nodeCallback) {
      //validate with google
      var options = {

          url: 'https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=' + (idToken),
          method: 'GET'
      };

      request(options, handleGoogleResponse(idToken, nodeCallback)).end();

  }

  /**
   *
   * This callback consumes Google's response, and performs the appropriate
   * actions on the session. (Set session optionally creating the account).
   *
   * @param {type} idToken an idToken received from Android
   * @param {type} nodeCallback
   * @returns session Data on callback if successful, error on callback otherwise
   */
  function handleGoogleResponse(idToken, nodeCallback) {
      return function (error, response, body) {

          //the whole response has been recieved, so we just print it out here
          if (error) {
           nodeCallback(e);
          } else {
            var resObject = JSON.parse(body);
            if (resObject.error_description) {
              nodeCallback(resObject.error_description, null);
            } else {
              checkAccount(resObject, idToken, nodeCallback);
            }
          }

      };
  }

  /**
   * Creates a user if one does not exist
   *
   * @param {Object}  Google user Token response (see : https://developers.google.com/identity/sign-in/android/backend-auth#calling-the-tokeninfo-endpoint)
   * @param {Sting} sessionToken
   * @param {NodeCallback} nodeCallback
   * @returns session Data on callback if successful, error on callback otherwise
   */
  function checkAccount(googleUserToken, sessionToken, nodeCallback) {
      console.log('checkAccountAndCreateSession');
      var handleResults = function (error, responseData) {
        console.log('checkAccountAndCreateSession_callback');
          if (error) {
              nodeCallback(error, null);
          } else {
              if (!responseData || responseData.count === 0) {
                  //no account, must create.
                  createAccount(googleUserToken, nodeCallback);
              } else if (responseData.count > 1) {
                  nodeCallback("error : Too many accounts returned", null);
              } else {
                  nodeCallback(null, googleUserToken.sub);
              }
          }
      };

      mbaasApi.db({
          "act": "list",
          "type": 'account',
          "eq": {"id": googleUserToken.sub},
      }, handleResults);
  }

  /**
   *  Creates an account and sets the session to that account.
   * @param {Object}  Google user Token response (see : https://developers.google.com/identity/sign-in/android/backend-auth#calling-the-tokeninfo-endpoint)
   * @param {NodeCallback} nodeCallback
   * @returns session Data on callback if successful, error on callback otherwise
   */
  function createAccount(googleUserToken, nodeCallback) {
    authResponse.authToken = '';
      mbaasApi.db({
          "act": "create",
          "type": 'account',
          "fields": [googleUserToken]
      }, function (error, data) {
        console.log('createAccountAndSetSession_cb + ' + data);
          if (error) {
               nodeCallback(error);
          } else {
               nodeCallback(null, googleUserToken.sub);
          }
      });
  }

  return router;

}

module.exports = auth;
<commit_msg>update file /lib/auth.js<commit_after>var express = require('express');
var bodyParser = require('body-parser');
var cors = require('cors');
var mbaasApi = require('fh-mbaas-api');
var mbaasExpress = mbaasApi.mbaasExpress();
var queryString = require('querystring');
var request = require('request');

function auth() {
  var router = express.Router();

  router.all('/init', function(req, res) {
        var params = req.body; // params.userId params.password
        if (params && params.userId) {
          console.log('Checking credentials for user ' + params.userId);
          initSession(params.userId, function(err, result){
            if (err) {
              console.log('Invalid credentials for user ' + params.userId);
              res.status(400);
              res.json({message: 'Invalid credentials'});
              return;
            } else {
              res.json({
                status: 'ok',
                userId: params.userId,
                sessionToken: result + '_sessiontoken',
                authResponse: result
              });
              return;
            }
          });

        } else {
          res.status(400);
          res.json({message: params.userId});
        }

  });

  /**
   * Validate the user's session info with Google, and create a session object.
   * This will also create a account object if necessary.
   *
   * @param {String} idToken an idToken provided by an Android Client (see : https://developers.google.com/identity/sign-in/android/backend-auth)
   * @param {Callback} nodeCallback a node callback
   */
  function initSession(idToken, nodeCallback) {
      //validate with google
      var options = {

          url: 'https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=' + (idToken),
          method: 'GET'
      };

      request(options, handleGoogleResponse(idToken, nodeCallback)).end();

  }

  /**
   *
   * This callback consumes Google's response, and performs the appropriate
   * actions on the session. (Set session optionally creating the account).
   *
   * @param {type} idToken an idToken received from Android
   * @param {type} nodeCallback
   * @returns session Data on callback if successful, error on callback otherwise
   */
  function handleGoogleResponse(idToken, nodeCallback) {
      return function (error, response, body) {

          //the whole response has been recieved, so we just print it out here
          if (error) {
           nodeCallback(e);
          } else {
            var resObject = JSON.parse(body);
            if (resObject.error_description) {
              nodeCallback(resObject.error_description, null);
            } else {
              checkAccount(resObject, idToken, nodeCallback);
            }
          }

      };
  }

  /**
   * Creates a user if one does not exist
   *
   * @param {Object}  Google user Token response (see : https://developers.google.com/identity/sign-in/android/backend-auth#calling-the-tokeninfo-endpoint)
   * @param {Sting} sessionToken
   * @param {NodeCallback} nodeCallback
   * @returns session Data on callback if successful, error on callback otherwise
   */
  function checkAccount(googleUserToken, sessionToken, nodeCallback) {
      console.log('checkAccountAndCreateSession');
      var handleResults = function (error, responseData) {
        console.log('checkAccountAndCreateSession_callback');
          if (error) {
              nodeCallback(error, null);
          } else {
              if (!responseData || responseData.count === 0) {
                  //no account, must create.
                  createAccount(googleUserToken, nodeCallback);
              } else if (responseData.count > 1) {
                  nodeCallback("error : Too many accounts returned", null);
              } else {
                console.log('found ' + responseData);
                  nodeCallback(null, googleUserToken.sub);
              }
          }
      };

      mbaasApi.db({
          "act": "list",
          "type": 'account',
          "eq": {"id": googleUserToken.sub},
      }, handleResults);
  }

  /**
   *  Creates an account and sets the session to that account.
   * @param {Object}  Google user Token response (see : https://developers.google.com/identity/sign-in/android/backend-auth#calling-the-tokeninfo-endpoint)
   * @param {NodeCallback} nodeCallback
   * @returns session Data on callback if successful, error on callback otherwise
   */
  function createAccount(googleUserToken, nodeCallback) {
    authResponse.authToken = '';
      mbaasApi.db({
          "act": "create",
          "type": 'account',
          "fields": [googleUserToken]
      }, function (error, data) {
        console.log('createAccountAndSetSession_cb + ' + data);
          if (error) {
               nodeCallback(error);
          } else {
               nodeCallback(null, googleUserToken.sub);
          }
      });
  }

  return router;

}

module.exports = auth;
<|endoftext|>


<commit_before>// Copyright Teleportd
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

/**
 * fwk.js
 *
 * This is a repository of helper functions available directly from
 * the pipes library object. These functions help adding methods to
 * Crockford style objects, and adds a few functionalities to the
 * Function, Array and String objects
 *
 * WARNING: never add methods to the Object type as they would appear
 * in enumerations. The pipes fwk rely on the NON-EXISTENCE of such
 * extended method on the Object type.
 *
 */

var crypto = require('crypto');

/**
 * method(that, name, method, _super)
 * Adds a method to the current object denoted by that and preserves
 * _super implementation (see Crockford)
 */
exports.method = function(that, name, method, _super) {
    if(_super) {
	var m = that[name];
	_super[name] = function() {
	    return m.apply(that, arguments);
	};
    }
    that[name] = method;
};

/**
 * getter(that, name, obj, prop)
 * Generates a getter on the current object denoted by that
 */
exports.getter = function(that, name, obj, prop) {
    var getter = function() {
	return obj[prop];
    };
    that[name] = getter;
};

/**
 * setter(that, name, obj, prop)
 * Generates a setter on the current object denoted by that
 */
exports.setter = function(that, name, obj, prop) {
    var setter = function (arg) {
	obj[prop] = arg;
	return that;
    };
    that['set' + name.substring(0, 1).toUpperCase() + name.substring(1)] = setter;
};

/**
 * responds(that, name)
 * Tests whether the object responds to a given function name
 */
exports.responds = function(that, name) {
    return (that[name] && typeof that[name] === 'function');
};

/**
 * once()
 * Returns a function that will call the underlying function only once
 * whether it is called once or multiple times
 */
Function.prototype.once = function() {
    var fn = this;
    var done = false;
    return function() {
	if(!done) {
	    args = Array.prototype.slice.call(arguments);
	    done = true;
	    fn.apply(null, args);
	}
    };
};

/**
 * bind()
 * The .bind method from Prototype.js
 */
Function.prototype.bind = function() {
    var fn = this,
    args = Array.prototype.slice.call(arguments),
    object = args.shift();
    return function(){
	return fn.apply(
	    object,
	    args.concat(Array.prototype.slice.call(arguments))
	);
    };
};

/**
 * remove(e)
 * Removes the element e from the Array, using the JS '===' equality
 */
Array.prototype.remove = function(e) {
    for(var i = 0; i < this.length; i++)
	if(e === this[i]) this.splice(i, 1);
};

/**
 * unique()
 * Removes duplicate elements, using the JS '===' equality
 */
Array.prototype.unique = function() {
  var a = this.concat();
  for(var i=0; i<a.length; i++) {
    for(var j=i+1; j<a.length; j++) {
      if(a[i] === a[j]) {
        a.splice(j, 1);
        j--;
      }
    }
  }
  return a;
};

/**
 * shallow(that)
 * Shallow copy of the object that
 */
exports.shallow = function(that) {
    if(that == null || typeof(that) != 'object')
	return that;
    var temp = new that.constructor();
    for(var key in that) {
	if(that.hasOwnProperty(key))
	    temp[key] = that[key];
    }
    return temp;
};

/**
 * clone(that)
 * Deep copy of the object that
 */
exports.clone = function(that) {
    if(that == null || typeof(that) != 'object')
	return that;
    var temp = new that.constructor();
    for(var key in that) {
	if(that.hasOwnProperty(key))
	    temp[key] = clone(that[key]);
    }
    return temp;
};

/**
 * mkhash(that)
 * Generates a 'deep' hash that ignores properties starting with a '_'
 */
exports.mkhash = function(that) {
    var hash = crypto.createHash('sha1');
    for(var i in that) {
	if(i.charAt(0) !== '_' && that.hasOwnProperty(i)) {
	    var str = JSON.stringify(that[i]);
	    if(str)
		hash.update(str);
	}
    }
    /** add args to update */
    for(var j = 1; j < arguments.length; j++)
	hash.update(arguments[j]);
    return hash.digest(encoding='hex');
};

/**
 * forEach(that, fun)
 * Applies Array-like forEach to an object
 */
exports.forEach = function(that, fun /*, thisp */) {
    "use strict";

    if(that === void 0 || that === null)
	throw new TypeError();

    var t = Object(that);

    if(typeof fun !== "function")
	throw new TypeError();

    var thisp = arguments[2];
    for(var i in t) {
	if(t.hasOwnProperty(i)) {
	    fun.call(thisp, t[i], i, t);
	}
    }
};

/**
 * trim() ltrim() rtrim()
 * String trim functions
 */
String.prototype.trim = function() {
  return this.replace(/^\s+|\s+$/g,"");
};
String.prototype.ltrim = function() {
  return this.replace(/^\s+/,"");
};
String.prototype.rtrim = function() {
  return this.replace(/\s+$/,"");
};
<commit_msg>make remove/unique properties non-enumerable on Array.prototype<commit_after>// Copyright Teleportd
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

/**
 * fwk.js
 *
 * This is a repository of helper functions available directly from
 * the pipes library object. These functions help adding methods to
 * Crockford style objects, and adds a few functionalities to the
 * Function, Array and String objects
 *
 * WARNING: never add methods to the Object type as they would appear
 * in enumerations. The pipes fwk rely on the NON-EXISTENCE of such
 * extended method on the Object type.
 *
 */

var crypto = require('crypto');

/**
 * method(that, name, method, _super)
 * Adds a method to the current object denoted by that and preserves
 * _super implementation (see Crockford)
 */
exports.method = function(that, name, method, _super) {
    if(_super) {
	var m = that[name];
	_super[name] = function() {
	    return m.apply(that, arguments);
	};
    }
    that[name] = method;
};

/**
 * getter(that, name, obj, prop)
 * Generates a getter on the current object denoted by that
 */
exports.getter = function(that, name, obj, prop) {
    var getter = function() {
	return obj[prop];
    };
    that[name] = getter;
};

/**
 * setter(that, name, obj, prop)
 * Generates a setter on the current object denoted by that
 */
exports.setter = function(that, name, obj, prop) {
    var setter = function (arg) {
	obj[prop] = arg;
	return that;
    };
    that['set' + name.substring(0, 1).toUpperCase() + name.substring(1)] = setter;
};

/**
 * responds(that, name)
 * Tests whether the object responds to a given function name
 */
exports.responds = function(that, name) {
    return (that[name] && typeof that[name] === 'function');
};

/**
 * once()
 * Returns a function that will call the underlying function only once
 * whether it is called once or multiple times
 */
Function.prototype.once = function() {
    var fn = this;
    var done = false;
    return function() {
	if(!done) {
	    args = Array.prototype.slice.call(arguments);
	    done = true;
	    fn.apply(null, args);
	}
    };
};

/**
 * bind()
 * The .bind method from Prototype.js
 */
Function.prototype.bind = function() {
    var fn = this,
    args = Array.prototype.slice.call(arguments),
    object = args.shift();
    return function(){
	return fn.apply(
	    object,
	    args.concat(Array.prototype.slice.call(arguments))
	);
    };
};

/**
 * remove(e)
 * Removes the element e from the Array, using the JS '===' equality
 */
Object.defineProperty(Array.prototype, 'remove', { value:
  function(e) {
    for(var i = 0; i < this.length; i++)
	    if(e === this[i]) this.splice(i, 1);
  }
});

/**
 * unique()
 * Removes duplicate elements, using the JS '===' equality
 */
Object.defineProperty(Array.prototype, 'unique', { value:
  function() {
    var a = this.concat();
    for(var i=0; i<a.length; i++) {
      for(var j=i+1; j<a.length; j++) {
        if(a[i] === a[j]) {
          a.splice(j, 1);
          j--;
        }
      }
    }
    return a;
  }
});

/**
 * shallow(that)
 * Shallow copy of the object that
 */
exports.shallow = function(that) {
    if(that == null || typeof(that) != 'object')
	return that;
    var temp = new that.constructor();
    for(var key in that) {
	if(that.hasOwnProperty(key))
	    temp[key] = that[key];
    }
    return temp;
};

/**
 * clone(that)
 * Deep copy of the object that
 */
exports.clone = function(that) {
    if(that == null || typeof(that) != 'object')
	return that;
    var temp = new that.constructor();
    for(var key in that) {
	if(that.hasOwnProperty(key))
	    temp[key] = clone(that[key]);
    }
    return temp;
};

/**
 * mkhash(that)
 * Generates a 'deep' hash that ignores properties starting with a '_'
 */
exports.mkhash = function(that) {
    var hash = crypto.createHash('sha1');
    for(var i in that) {
	if(i.charAt(0) !== '_' && that.hasOwnProperty(i)) {
	    var str = JSON.stringify(that[i]);
	    if(str)
		hash.update(str);
	}
    }
    /** add args to update */
    for(var j = 1; j < arguments.length; j++)
	hash.update(arguments[j]);
    return hash.digest(encoding='hex');
};

/**
 * forEach(that, fun)
 * Applies Array-like forEach to an object
 */
exports.forEach = function(that, fun /*, thisp */) {
    "use strict";

    if(that === void 0 || that === null)
	throw new TypeError();

    var t = Object(that);

    if(typeof fun !== "function")
	throw new TypeError();

    var thisp = arguments[2];
    for(var i in t) {
	if(t.hasOwnProperty(i)) {
	    fun.call(thisp, t[i], i, t);
	}
    }
};

/**
 * trim() ltrim() rtrim()
 * String trim functions
 */
String.prototype.trim = function() {
  return this.replace(/^\s+|\s+$/g,"");
};
String.prototype.ltrim = function() {
  return this.replace(/^\s+/,"");
};
String.prototype.rtrim = function() {
  return this.replace(/\s+$/,"");
};
<|endoftext|>


<commit_before>module.exports = Base

var Readable = require('stream').Readable
/* istanbul ignore if */
if (!Readable || process.version.match(/^v0\.10/)) {
  Readable = require('readable-stream').Readable
}

var extraFromError = require('./extra-from-error.js')
var assert = require('assert')
var cleanYamlObject = require('./clean-yaml-object.js')

var domain = require('domain')
var util = require('util')
util.inherits(Base, Readable)

var Parser = require('tap-parser')

var ownOr = require('own-or')
var ownOrEnv = require('own-or-env')

function Base (options) {
  this.start = 0
  this.hrtime = null
  this.time = null
  this.readyToProcess = false
  this.options = options
  this.parent = ownOr(options, 'parent', null)
  this.bail = ownOrEnv(options, 'bail', 'TAP_BAIL', true)
  this.name = ownOr(options, 'name', '')
  this.indent = ownOr(options, 'indent', '')
  this.silent = !!options.silent
  this.buffered = !!options.buffered || !!options.silent
  this.finished = false
  this.strict = ownOrEnv(options, 'strict', 'TAP_STRICT', true)
  this.omitVersion = !!options.omitVersion
  this.preserveWhitespace = ownOr(options, 'preserveWhitespace', true)
  this.jobs = +ownOrEnv(options, 'jobs', 'TAP_JOBS') || 0
  this.skip = ownOr(options, 'skip', false)
  this.todo = ownOr(options, 'todo', false)
  this.setupParser(options)
  this.finished = false
  this.output = ''
  this.results = null
  this.bailedOut = false
  if (this.skip || this.todo)
    this.main = Base.prototype.main

  Readable.apply(this, options)

  domain.create().add(this)
  this.domain.on('error', this.threw.bind(this))

  if (typeof options.debug === 'boolean')
    this.debug = options.debug ? debug : nodebug
}

Base.prototype.passing = function () {
  return this.parser.ok
}

Base.prototype.setTimeout = function (n) {
  if (!this.hrtime)
    this.hrtime = process.hrtime()

  if (!n) {
    clearTimeout(this.timer)
    this.timer = null
  } else {
    this.start = Date.now()
    this.timer = setTimeout(this.timeout.bind(this), n)
    this.timer.unref()
  }
}

Base.prototype.threw = function (er, extra, proxy) {
  if (this.name && !proxy)
    er.test = this.name

  if (!extra)
    extra = extraFromError(er, extra, this.options)

  if (this.results) {
    this.results.ok = false
    if (this.parent)
      this.parent.threw(er, extra, true)
    else
      console.error(er, er.stack)
  } else
    this.parser.ok = false

  return extra
}

Base.prototype.timeout = function (options) {
  this.setTimeout(false)
  var er = new Error('timeout!')
  options = options || {}
  options.expired = options.expired || this.name
  this.threw(new Error('timeout!'), options)
}

Base.prototype.main = function (cb) {
  cb()
}

Base.prototype.online = function (line) {
  this.debug('LINE %j', line)
  return this.push(this.indent + line)
}

Base.prototype.push = function (c, e) {
  assert.equal(typeof c, 'string')
  assert.equal(c.substr(-1), '\n')

  if (this.buffered) {
    this.output += c
    return true
  }

  // We *always* want data coming out immediately.  Test runners have a
  // very special relationship with zalgo. It's more important to ensure
  // that any console.log() lines that appear in the midst of tests are
  // not taken out of context
  if (this._readableState) {
    this._readableState.sync = false
  }

  // this.debug(this._readableState)
  return Readable.prototype.push.call(this, c, e)
}

Base.prototype.onbail = function (reason) {
  this.bailedOut = reason || true
  this.emit('bailout', reason)
}

Base.prototype.oncomplete = function (results) {
  if (this.hrtime) {
    this.hrtime = process.hrtime(this.hrtime)
    this.time = Math.round(this.hrtime[0] * 1e6 + this.hrtime[1] / 1e3) / 1e3
  }

  this.debug('ONCOMPLETE %j %j', this.name, results)
  this.results = results
  this.emit('complete', results)
  var failures = results.failures.filter(function (f) {
    delete f.diag
    delete f.ok
    return f.tapError
  })

  if (failures.length)
    this.options.failures = failures

  this.onbeforeend()
  this.emit('end')
  this.ondone()
}

Base.prototype.onbeforeend = function () {}
Base.prototype.ondone = function () {}

Base.prototype.setupParser = function (options) {
  this.parser = new Parser({
    bail: this.bail,
    strict: this.strict,
    omitVersion: this.omitVersion,
    preserveWhitespace: this.preserveWhitespace
  })
  assert(this.parser.preserveWhitespace)
  this.parser.on('line', this.online.bind(this))
  this.parser.once('bailout', this.onbail.bind(this))
  this.parser.on('complete', this.oncomplete.bind(this))
}

Base.prototype._read = function (n) {
  // this.emit('readable')
  // this.debug('_read %j', this.name, arguments)
}

Base.prototype.inspect = function () {
  return this.constructor.name + ' ' + util.inspect({
    name: this.name,
    jobs: this.jobs,
    buffered: this.buffered,
    pool: this.pool,
    queue: this.queue,
    subtests: this.subtests,
    output: this.output,
    skip: this.skip,
    todo: this.todo,
    results: this.results
  })
}

Base.prototype.debug = (/\btap\b/i.test(process.env.NODE_DEBUG || ''))
  ? debug : nodebug

function nodebug () {}

/* istanbul ignore next */
function debug () {
  var prefix = 'TAP ' + process.pid + ' ' + this.name + ': '
  var msg = util.format.apply(util, arguments).trim()
  msg = prefix + msg.split('\n').join('\n' + prefix)
  console.error(msg)
}
<commit_msg>Remove line breaks from subtest names<commit_after>module.exports = Base

var Readable = require('stream').Readable
/* istanbul ignore if */
if (!Readable || process.version.match(/^v0\.10/)) {
  Readable = require('readable-stream').Readable
}

var extraFromError = require('./extra-from-error.js')
var assert = require('assert')
var cleanYamlObject = require('./clean-yaml-object.js')

var domain = require('domain')
var util = require('util')
util.inherits(Base, Readable)

var Parser = require('tap-parser')

var ownOr = require('own-or')
var ownOrEnv = require('own-or-env')

function Base (options) {
  this.start = 0
  this.hrtime = null
  this.time = null
  this.readyToProcess = false
  this.options = options
  this.parent = ownOr(options, 'parent', null)
  this.bail = ownOrEnv(options, 'bail', 'TAP_BAIL', true)
  this.name = ownOr(options, 'name', '')
  if (!this.name)
    this.name = ''
  else
    this.name = this.name.replace(/[\n\r\s\t]/g, ' ')
  this.indent = ownOr(options, 'indent', '')
  this.silent = !!options.silent
  this.buffered = !!options.buffered || !!options.silent
  this.finished = false
  this.strict = ownOrEnv(options, 'strict', 'TAP_STRICT', true)
  this.omitVersion = !!options.omitVersion
  this.preserveWhitespace = ownOr(options, 'preserveWhitespace', true)
  this.jobs = +ownOrEnv(options, 'jobs', 'TAP_JOBS') || 0
  this.skip = ownOr(options, 'skip', false)
  this.todo = ownOr(options, 'todo', false)
  this.setupParser(options)
  this.finished = false
  this.output = ''
  this.results = null
  this.bailedOut = false
  if (this.skip || this.todo)
    this.main = Base.prototype.main

  Readable.apply(this, options)

  domain.create().add(this)
  this.domain.on('error', this.threw.bind(this))

  if (typeof options.debug === 'boolean')
    this.debug = options.debug ? debug : nodebug
}

Base.prototype.passing = function () {
  return this.parser.ok
}

Base.prototype.setTimeout = function (n) {
  if (!this.hrtime)
    this.hrtime = process.hrtime()

  if (!n) {
    clearTimeout(this.timer)
    this.timer = null
  } else {
    this.start = Date.now()
    this.timer = setTimeout(this.timeout.bind(this), n)
    this.timer.unref()
  }
}

Base.prototype.threw = function (er, extra, proxy) {
  if (this.name && !proxy)
    er.test = this.name

  if (!extra)
    extra = extraFromError(er, extra, this.options)

  if (this.results) {
    this.results.ok = false
    if (this.parent)
      this.parent.threw(er, extra, true)
    else
      console.error(er, er.stack)
  } else
    this.parser.ok = false

  return extra
}

Base.prototype.timeout = function (options) {
  this.setTimeout(false)
  var er = new Error('timeout!')
  options = options || {}
  options.expired = options.expired || this.name
  this.threw(new Error('timeout!'), options)
}

Base.prototype.main = function (cb) {
  cb()
}

Base.prototype.online = function (line) {
  this.debug('LINE %j', line)
  return this.push(this.indent + line)
}

Base.prototype.push = function (c, e) {
  assert.equal(typeof c, 'string')
  assert.equal(c.substr(-1), '\n')

  if (this.buffered) {
    this.output += c
    return true
  }

  // We *always* want data coming out immediately.  Test runners have a
  // very special relationship with zalgo. It's more important to ensure
  // that any console.log() lines that appear in the midst of tests are
  // not taken out of context
  if (this._readableState) {
    this._readableState.sync = false
  }

  // this.debug(this._readableState)
  return Readable.prototype.push.call(this, c, e)
}

Base.prototype.onbail = function (reason) {
  this.bailedOut = reason || true
  this.emit('bailout', reason)
}

Base.prototype.oncomplete = function (results) {
  if (this.hrtime) {
    this.hrtime = process.hrtime(this.hrtime)
    this.time = Math.round(this.hrtime[0] * 1e6 + this.hrtime[1] / 1e3) / 1e3
  }

  this.debug('ONCOMPLETE %j %j', this.name, results)
  this.results = results
  this.emit('complete', results)
  var failures = results.failures.filter(function (f) {
    delete f.diag
    delete f.ok
    return f.tapError
  })

  if (failures.length)
    this.options.failures = failures

  this.onbeforeend()
  this.emit('end')
  this.ondone()
}

Base.prototype.onbeforeend = function () {}
Base.prototype.ondone = function () {}

Base.prototype.setupParser = function (options) {
  this.parser = new Parser({
    bail: this.bail,
    strict: this.strict,
    omitVersion: this.omitVersion,
    preserveWhitespace: this.preserveWhitespace
  })
  assert(this.parser.preserveWhitespace)
  this.parser.on('line', this.online.bind(this))
  this.parser.once('bailout', this.onbail.bind(this))
  this.parser.on('complete', this.oncomplete.bind(this))
}

Base.prototype._read = function (n) {
  // this.emit('readable')
  // this.debug('_read %j', this.name, arguments)
}

Base.prototype.inspect = function () {
  return this.constructor.name + ' ' + util.inspect({
    name: this.name,
    jobs: this.jobs,
    buffered: this.buffered,
    pool: this.pool,
    queue: this.queue,
    subtests: this.subtests,
    output: this.output,
    skip: this.skip,
    todo: this.todo,
    results: this.results
  })
}

Base.prototype.debug = (/\btap\b/i.test(process.env.NODE_DEBUG || ''))
  ? debug : nodebug

function nodebug () {}

/* istanbul ignore next */
function debug () {
  var prefix = 'TAP ' + process.pid + ' ' + this.name + ': '
  var msg = util.format.apply(util, arguments).trim()
  msg = prefix + msg.split('\n').join('\n' + prefix)
  console.error(msg)
}
<|endoftext|>


<commit_before>'use strict';

// List of supported http methods.
var HTTP_METHODS = ['get', 'post', 'put', 'delete'];

// Regexp for path keys.
var KEYS = /(:[\w\-]+)/g;
var SLASH = /([\/.])/g;
var router = {};
var routes = {};

/**
 * Parse path to regexp
 * @param  {String} path URL path
 * @return {Object} Object with new RegExp and keys
 */
function pathRegexp(path) {
    var keys = [];

    if (Object.prototype.toString.call(path) !== '[object String]') {
        throw new Error('Path must to be string!');
    }

    // TODO: Escape char.
    path = path.toLowerCase().replace(KEYS, function() {
        keys.push(arguments[0].slice(1));
        return '(?:([^\/]+?))';
    }).replace(SLASH, '\\$1');

    return {
        path: new RegExp('^' + path + '$'),
        keys: keys
    };
}

/**
 * Find route
 * @param  {String} method HTTP method
 * @param  {String} path URL path
 * @return {OBject|Boolean} Found route object or false
 */
function matchRoute(method, path) {
    var route;

    method = method.toLowerCase();

    // TODO: Use handler to response Error.
    if (!method && HTTP_METHODS.indexOf(method) < 0) {
        throw new Error('Not supported HTTP method: ' + method);
    }

    if (!path && Object.prototype.toString.call(path) !== '[object String]') {
        throw new Error('Path must to be string!');
    }

    for (var i in routes[method]) {
        route = routes[method][i];

        // TODO: call get Params.
        if (route.path.test(path)) {
            return route;
        }
    }

    return false;
}

/**
 * Get params from URL
 * @param  {String} url URL path
 * @param  {Object} route Route object
 * @return {Object} params Object with parsed params
 */
function getParams(url, route) {
    // TODO: Add query params.
    var params = {};

    url.match(route.path).slice(1).forEach(function(value, index) {
        params[route.keys[index]] = value;
    });

    return params;
}

/**
 * Response 404
 * @param {Object} request Request object
 * @param {Object} response Response object
 */
function notFound(request, response) {
    response.writeHead(404, { 'Content-Type': 'text/html' });
    response.end();
}

/**
 * Uniqueness check the path
 * @param  {Object} route
 * @return {Boolean}
 */
var isUniq = function(route) {
    return routes[route.method].some(function(item) {
        return item.path.toString() === route.path.toString();
    });
};

HTTP_METHODS.forEach(function(method) {
    routes[method] = [];
    router[method] = function(path, callback) {
        var route = pathRegexp(path);

        route.method = method;
        route.callback = callback;

        if (isUniq(route)) {
            return console.error('Path '+ path +' already exist.');
        }

        routes[method].push(route);
    };
});

router.listener = function(request, response) {
    var url = request.url;
    var route = matchRoute(request.method, url);

    request.params = getParams(url, route);

    if (route) {
        if (typeof route.callback === 'function') {
            route.callback(request, response);
        }

    } else {
        notFound(request, response);
    }
};

module.exports = router;
<commit_msg>Move check callback is a function type.<commit_after>'use strict';

// List of supported http methods.
var HTTP_METHODS = ['get', 'post', 'put', 'delete'];

// Regexp for path keys.
var KEYS = /(:[\w\-]+)/g;
var SLASH = /([\/.])/g;
var router = {};
var routes = {};

/**
 * Parse path to regexp
 * @param  {String} path URL path
 * @return {Object} Object with new RegExp and keys
 */
function pathRegexp(path) {
    var keys = [];

    if (Object.prototype.toString.call(path) !== '[object String]') {
        throw new Error('Path must to be string!');
    }

    // TODO: Escape char.
    path = path.toLowerCase().replace(KEYS, function() {
        keys.push(arguments[0].slice(1));
        return '(?:([^\/]+?))';
    }).replace(SLASH, '\\$1');

    return {
        path: new RegExp('^' + path + '$'),
        keys: keys
    };
}

/**
 * Find route
 * @param  {String} method HTTP method
 * @param  {String} path URL path
 * @return {Object|Boolean} Found route object or false
 */
function matchRoute(method, path) {
    var route;

    method = method.toLowerCase();

    // TODO: Use handler to response Error.
    if (!method && HTTP_METHODS.indexOf(method) < 0) {
        throw new Error('Not supported HTTP method: ' + method);
    }

    if (!path && Object.prototype.toString.call(path) !== '[object String]') {
        throw new Error('Path must to be string!');
    }

    for (var i in routes[method]) {
        route = routes[method][i];

        // TODO: call get Params.
        if (route.path.test(path)) {
            return route;
        }
    }

    return false;
}

/**
 * Get params from URL
 * @param  {String} url URL path
 * @param  {Object} route Route object
 * @return {Object} params Object with parsed params
 */
function getParams(url, route) {
    // TODO: Add query params.
    var params = {};

    url.match(route.path).slice(1).forEach(function(value, index) {
        params[route.keys[index]] = value;
    });

    return params;
}

/**
 * Response 404
 * @param {Object} request Request object
 * @param {Object} response Response object
 */
function notFound(request, response) {
    response.writeHead(404, { 'Content-Type': 'text/html' });
    response.end();
}

/**
 * Uniqueness check the path
 * @param  {Object} route
 * @return {Boolean}
 */
var isUniq = function(route) {
    return routes[route.method].some(function(item) {
        return item.path.toString() === route.path.toString();
    });
};

HTTP_METHODS.forEach(function(method) {
    routes[method] = [];
    router[method] = function(path, callback) {
        var route = pathRegexp(path);

        if (!typeof route.callback === 'function') {
            throw new Error('Callback is not a function');
        }

        route.callback = callback;
        route.method = method;

        if (isUniq(route)) {
            throw new Error('Path '+ path +' already exist.');
        }

        routes[method].push(route);
    };
});

router.listener = function(request, response) {
    var url = request.url;
    var route = matchRoute(request.method, url);

    if (!route) {
        return notFound(request, response);
    }

    request.params = getParams(url, route);
    route.callback(request, response);
};

module.exports = router;
<|endoftext|>


<commit_before>/*********************************************************
 *  Simple Node.js module for using the Bing Search API  *
 *********************************************************/

// Require dependencies
var request = require('request'),
    url = require('url'),
    _ = require('underscore'),
    qs = require('querystring');

/**
 * @param {Object} options  Options to all Bing calls, allows overriding of
 *        rootUri, accKey (Bing API key), userAgent, reqTimeout
 * @returns {Bing}
 * @constructor
 */
var Bing = function (options) {

  if (!(this instanceof Bing)) return new Bing(options);

  var defaults = {

    //Bing Search API URI
    rootUri: "https://api.cognitive.microsoft.com/bing/v7.0/",

    //Account Key
    accKey: null,

    //Bing UserAgent
    userAgent: 'Bing Search Client for Node.js',

    //Request Timeout
    reqTimeout: 5000
  };

  // Merge options passed in with defaults
  this.options = _.extend(defaults, options);

  // Performs the search request for the given vertical
  this.searchVertical = function (query, vertical, options, callback) {

    if (typeof options === 'function') {
      callback = options;
    }
    if (typeof callback != 'function') {
      throw "Error: Callback function required!";
    }

    // Create a copy of the options, to avoid permanent overwrites
    var opts = JSON.parse(JSON.stringify(this.options));

    if (typeof options === 'object') {
      _.extend(opts, options);
    }

    // Map options and supported variation for old versions with the new names
    var opMap = {
      top: 'count',
      skip: 'offset',
      videosortby: 'videoSortBy',
      videofilters: 'videoFilters',
      adult: 'safeSearch',
      safesearch: 'safeSearch',
      market: 'mkt'
    }
    Object.keys(opts).forEach(function (opt) {
      var newOp = opMap[opt]
      if (newOp) {
        opts[newOp] = opts[newOp] || opts[opt]
        delete opts[opt]
      }
    })

    var reqUri = opts.rootUri + vertical + "?q=" + query

    // Filter the no-query options (accKey, rootUri, userAgent)
    var queryOpts = {}

    Object.keys(opts).forEach(function (opt) {
      if (!~Object.keys(defaults).indexOf(opt)) {
        queryOpts[opt] = opts[opt]
      }
    })

    var qStr = qs.stringify(queryOpts);

    reqUri += qStr ? '&' + qStr : '';

    reqUri = encodeURI(reqUri);

    request({
      uri: reqUri,
      method: opts.method || "GET",
      headers: {
        "User-Agent": opts.userAgent,
        "Ocp-Apim-Subscription-Key": opts.accKey
      },
      timeout: opts.reqTimeout,
      pool: {
        maxSockets: opts.maxSockets ? opts.maxSockets : Infinity
      }

    }, function (err, res, body) {

      if (res && res.statusCode !== 200) {
          err = new Error(body);
      } else {

        // Parse body, if body
        body = typeof body === 'string' ? JSON.parse(body) : body;
      }

      callback(err, res, body);
    });
  };

};

/**
 * @callback requestCallback
 * @param {String} error     Error evaluates to true when an error has occurred.
 * @param {Object} response  Response object from the Bing call.
 * @param {Object} body      JSON of the response.
 */

/**
 * Performs a Bing search in the Web vertical.
 *
 * @param {String} query              Query term to search for.
 *
 * @param {Object} options            Options to command, allows overriding
 *                                    of rootUri, accKey (Bing API key),
 *                                    userAgent, reqTimeout, count, offset
 *
 * @param {requestCallback} callback  Callback called with (potentially
 *                                    json-parsed) response.
 *
 * @function
 */
Bing.prototype.web = function (query, options, callback) {
  this.searchVertical(query, "search", options, callback);
};

// Alias Bing.search to Bing.web
// Note: Keep this for compatibility with older versions
Bing.prototype.search = Bing.prototype.web;

/**
 * Performs a Bing search in the Composite vertical.
 *
 * @param {String} query              Query term to search for.
 *
 * @param {Object} options            Options to command, allows overriding
 *                                    of rootUri, accKey (Bing API key),
 *                                    userAgent, reqTimeout, count, offset,
 *
 * @param {requestCallback} callback  Callback called with (potentially
 *                                    json-parsed) response.
 * @function
 */
Bing.prototype.composite = function (query, options, callback) {
  this.searchVertical(query, "search", options, callback);
};

/**
 * Performs a Bing search in the News vertical.
 *
 * @param {String} query              Query term to search for.
 *
 * @param {Object} options            Options to command, allows overriding
 *                                    of rootUri, accKey (Bing API key),
 *                                    userAgent, reqTimeout, count, offset,
 *
 * @param {requestCallback} callback  Callback called with (potentially
 *                                    json-parsed) response.
 * @function
 */
Bing.prototype.news = function (query, options, callback) {
  this.searchVertical(query, "news/search", options, callback);
};

/**
 * Performs a Bing search in the Video vertical.
 *
 * @param {String} query              Query term to search for.
 *
 * @param {Object} options            Options to command, allows overriding
 *                                    of rootUri, accKey (Bing API key),
 *                                    userAgent, reqTimeout, count, offset,
 *
 * @param {requestCallback} callback  Callback called with (potentially
 *                                    json-parsed) response.
 * @function
 */
Bing.prototype.video = function (query, options, callback) {
  if (options && typeof options === 'object') {

    //compatibility with older versions
    options.videoFilters = options.videoFilters || options.videofilters || '';

    if (options.videoFilters && typeof options.videoFilters === 'object') {

      var filterQuery = Object.keys(options.videoFilters)
                          .map(function(key){
                            return capitalise(key) + ':'
                                     + capitalise(options.videoFilters[key]);
                          })
                          .join('+');

      options.videoFilters = filterQuery;
    }
  }
  this.searchVertical(query, "videos/search", options, callback);
};

/**
 * Performs a Bing search in the Images vertical.
 *
 * @param {String} query              Query term to search for.
 *
 * @param {Object} options            Options to command, allows overriding of
 *                                    rootUri, accKey (Bing API key),
 *                                    userAgent, reqTimeout, count, offset,
 *                                    imageFilters
 *
 * @param {requestCallback} callback  Callback called with (potentially
 *                                    json-parsed) response.
 * @function
 */
Bing.prototype.images = function (query, options, callback) {
  if (options && typeof options === 'object') {

    //compatibility with older versions
    options.imageFilters = options.imageFilters || options.imagefilters || '';

    if (options.imageFilters && typeof options.imageFilters === 'object') {

      var filterQuery = Object.keys(options.imageFilters)
                          .map(function(key){
                            return capitalise(key) + ':'
                                     + capitalise(options.imageFilters[key]);
                          })
                          .join('+');

      options.imageFilters = filterQuery;
    }
  }
  this.searchVertical(query, "images/search", options, callback);
};

/**
 * Performs a Bing search in the Related Search vertical.
 *
 * @param {String} query              Query term to search for.
 *
 * @param {Object} options            Options to command, allows overriding
 *                                    of rootUri, accKey (Bing API key),
 *                                    userAgent, reqTimeout, count, offset,
 *
 * @param {requestCallback} callback  Callback called with (potentially
 *                                    json-parsed) response.
 * @function
 */
Bing.prototype.relatedSearch = function (query, options, callback) {
  this.searchVertical(query, "search", options, callback);
};

/**
 * Performs a Bing search in the Spelling Suggestions vertical.
 *
 * @param {String} query              Query term to search for.
 *
 * @param {Object} options            Options to command, allows overriding
 *                                    of rootUri, accKey (Bing API key),
 *                                    userAgent, reqTimeout, count, offset,
 *
 * @param {requestCallback} callback  Callback called with (potentially
 *                                    json-parsed) response.
 * @function
 */
Bing.prototype.spelling = function (query, options, callback) {
  this.searchVertical(query, "spellcheck", options, callback);
};

/**
 * Capitalises the first word of the passed string
 *
 * @param {String} s   String to be capitalised
 *
 * @function
 */
function capitalise(s) {
  return s.charAt(0).toUpperCase() + s.slice(1);
}

module.exports = Bing;

<commit_msg>Update bing.js<commit_after>/*********************************************************
 *  Simple Node.js module for using the Bing Search API  *
 *********************************************************/

// Require dependencies
var request = require('request'),
    url = require('url'),
    _ = require('underscore'),
    qs = require('querystring');

/**
 * @param {Object} options  Options to all Bing calls, allows overriding of
 *        rootUri, accKey (Bing API key), userAgent, reqTimeout
 * @returns {Bing}
 * @constructor
 */
var Bing = function (options) {

  if (!(this instanceof Bing)) return new Bing(options);

  var defaults = {

    //Bing Search API URI
    rootUri: "https://api.cognitive.microsoft.com/bing/v7.0/search",

    //Account Key
    accKey: null,

    //Bing UserAgent
    userAgent: 'Bing Search Client for Node.js',

    //Request Timeout
    reqTimeout: 5000
  };

  // Merge options passed in with defaults
  this.options = _.extend(defaults, options);

  // Performs the search request for the given vertical
  this.searchVertical = function (query, vertical, options, callback) {

    if (typeof options === 'function') {
      callback = options;
    }
    if (typeof callback != 'function') {
      throw "Error: Callback function required!";
    }

    // Create a copy of the options, to avoid permanent overwrites
    var opts = JSON.parse(JSON.stringify(this.options));

    if (typeof options === 'object') {
      _.extend(opts, options);
    }

    // Map options and supported variation for old versions with the new names
    var opMap = {
      top: 'count',
      skip: 'offset',
      videosortby: 'videoSortBy',
      videofilters: 'videoFilters',
      adult: 'safeSearch',
      safesearch: 'safeSearch',
      market: 'mkt'
    }
    Object.keys(opts).forEach(function (opt) {
      var newOp = opMap[opt]
      if (newOp) {
        opts[newOp] = opts[newOp] || opts[opt]
        delete opts[opt]
      }
    })

    var reqUri = opts.rootUri + vertical + "?q=" + query

    // Filter the no-query options (accKey, rootUri, userAgent)
    var queryOpts = {}

    Object.keys(opts).forEach(function (opt) {
      if (!~Object.keys(defaults).indexOf(opt)) {
        queryOpts[opt] = opts[opt]
      }
    })

    var qStr = qs.stringify(queryOpts);

    reqUri += qStr ? '&' + qStr : '';

    reqUri = encodeURI(reqUri);

    request({
      uri: reqUri,
      method: opts.method || "GET",
      headers: {
        "User-Agent": opts.userAgent,
        "Ocp-Apim-Subscription-Key": opts.accKey
      },
      timeout: opts.reqTimeout,
      pool: {
        maxSockets: opts.maxSockets ? opts.maxSockets : Infinity
      }

    }, function (err, res, body) {

      if (res && res.statusCode !== 200) {
          err = new Error(body);
      } else {

        // Parse body, if body
        body = typeof body === 'string' ? JSON.parse(body) : body;
      }

      callback(err, res, body);
    });
  };

};

/**
 * @callback requestCallback
 * @param {String} error     Error evaluates to true when an error has occurred.
 * @param {Object} response  Response object from the Bing call.
 * @param {Object} body      JSON of the response.
 */

/**
 * Performs a Bing search in the Web vertical.
 *
 * @param {String} query              Query term to search for.
 *
 * @param {Object} options            Options to command, allows overriding
 *                                    of rootUri, accKey (Bing API key),
 *                                    userAgent, reqTimeout, count, offset
 *
 * @param {requestCallback} callback  Callback called with (potentially
 *                                    json-parsed) response.
 *
 * @function
 */
Bing.prototype.web = function (query, options, callback) {
  this.searchVertical(query, "search", options, callback);
};

// Alias Bing.search to Bing.web
// Note: Keep this for compatibility with older versions
Bing.prototype.search = Bing.prototype.web;

/**
 * Performs a Bing search in the Composite vertical.
 *
 * @param {String} query              Query term to search for.
 *
 * @param {Object} options            Options to command, allows overriding
 *                                    of rootUri, accKey (Bing API key),
 *                                    userAgent, reqTimeout, count, offset,
 *
 * @param {requestCallback} callback  Callback called with (potentially
 *                                    json-parsed) response.
 * @function
 */
Bing.prototype.composite = function (query, options, callback) {
  this.searchVertical(query, "search", options, callback);
};

/**
 * Performs a Bing search in the News vertical.
 *
 * @param {String} query              Query term to search for.
 *
 * @param {Object} options            Options to command, allows overriding
 *                                    of rootUri, accKey (Bing API key),
 *                                    userAgent, reqTimeout, count, offset,
 *
 * @param {requestCallback} callback  Callback called with (potentially
 *                                    json-parsed) response.
 * @function
 */
Bing.prototype.news = function (query, options, callback) {
  this.searchVertical(query, "news/search", options, callback);
};

/**
 * Performs a Bing search in the Video vertical.
 *
 * @param {String} query              Query term to search for.
 *
 * @param {Object} options            Options to command, allows overriding
 *                                    of rootUri, accKey (Bing API key),
 *                                    userAgent, reqTimeout, count, offset,
 *
 * @param {requestCallback} callback  Callback called with (potentially
 *                                    json-parsed) response.
 * @function
 */
Bing.prototype.video = function (query, options, callback) {
  if (options && typeof options === 'object') {

    //compatibility with older versions
    options.videoFilters = options.videoFilters || options.videofilters || '';

    if (options.videoFilters && typeof options.videoFilters === 'object') {

      var filterQuery = Object.keys(options.videoFilters)
                          .map(function(key){
                            return capitalise(key) + ':'
                                     + capitalise(options.videoFilters[key]);
                          })
                          .join('+');

      options.videoFilters = filterQuery;
    }
  }
  this.searchVertical(query, "videos/search", options, callback);
};

/**
 * Performs a Bing search in the Images vertical.
 *
 * @param {String} query              Query term to search for.
 *
 * @param {Object} options            Options to command, allows overriding of
 *                                    rootUri, accKey (Bing API key),
 *                                    userAgent, reqTimeout, count, offset,
 *                                    imageFilters
 *
 * @param {requestCallback} callback  Callback called with (potentially
 *                                    json-parsed) response.
 * @function
 */
Bing.prototype.images = function (query, options, callback) {
  if (options && typeof options === 'object') {

    //compatibility with older versions
    options.imageFilters = options.imageFilters || options.imagefilters || '';

    if (options.imageFilters && typeof options.imageFilters === 'object') {

      var filterQuery = Object.keys(options.imageFilters)
                          .map(function(key){
                            return capitalise(key) + ':'
                                     + capitalise(options.imageFilters[key]);
                          })
                          .join('+');

      options.imageFilters = filterQuery;
    }
  }
  this.searchVertical(query, "images/search", options, callback);
};

/**
 * Performs a Bing search in the Related Search vertical.
 *
 * @param {String} query              Query term to search for.
 *
 * @param {Object} options            Options to command, allows overriding
 *                                    of rootUri, accKey (Bing API key),
 *                                    userAgent, reqTimeout, count, offset,
 *
 * @param {requestCallback} callback  Callback called with (potentially
 *                                    json-parsed) response.
 * @function
 */
Bing.prototype.relatedSearch = function (query, options, callback) {
  this.searchVertical(query, "search", options, callback);
};

/**
 * Performs a Bing search in the Spelling Suggestions vertical.
 *
 * @param {String} query              Query term to search for.
 *
 * @param {Object} options            Options to command, allows overriding
 *                                    of rootUri, accKey (Bing API key),
 *                                    userAgent, reqTimeout, count, offset,
 *
 * @param {requestCallback} callback  Callback called with (potentially
 *                                    json-parsed) response.
 * @function
 */
Bing.prototype.spelling = function (query, options, callback) {
  this.searchVertical(query, "spellcheck", options, callback);
};

/**
 * Capitalises the first word of the passed string
 *
 * @param {String} s   String to be capitalised
 *
 * @function
 */
function capitalise(s) {
  return s.charAt(0).toUpperCase() + s.slice(1);
}

module.exports = Bing;

<|endoftext|>


<commit_before>"use strict";

var Command = require ("./command");
var ArgpError = require ("./error");

var Body = module.exports = function (instance){
	this._instance = instance;
	this._reWhitespace = /\s/;
};

Body.prototype.argument = function (name, o){
	if (this._reWhitespace.test (name)){
		throw new ArgpError ("The argument canot contain white space characters");
	}
	if (this._instance._arguments[name]){
		throw new ArgpError ("The argument \"" + name + "\" is already defined");
	}
	o = o || {};
	if (this._instance._command){
		Command._validateTrailing (o.trailing);
	}
	this._instance._argument (name, o);
	return this;
};

Body.prototype.argv = function (){
	return this._instance.argv ();
};

Body.prototype.columns = function (col1, col2){
	this._instance._option ({
		columns: [col1, col2]
	});
	return this;
};

Body.prototype.command = function (){
	return this._instance.command.apply (this._instance, arguments);
};

Body.prototype.help = function (o){
	this._instance._showHelp = true;
	var short = !(o && o.short === false);
	var opt = {};
	if (short) opt.short = "h";
	opt.long = "help";
	opt.description = "Display this help message and exit";
	this._instance._option (opt);
	return this;
};

Body.prototype.main = function (){
	return this._instance.main.apply (this._instance, arguments);
};

Body.prototype.option = function (o){
	if (!o.long && !o.short) throw new ArgpError ("At least a long name " +
			"must be configured");

	if (o.long){
		//Long names cannot contain whitespaces
		if (this._reWhitespace.test (o.long)){
			throw new ArgpError ("The long name canot contain whitespace characters");
		}
		//Cannot be already defined
		for (var p in this._instance._optionsLong){
			if (p === o.long){
				throw new ArgpError ("The long name \"" + o.long +
						"\" is already defined");
			}
		}
	}

	if (o.short){
		if (o.short.length > 1){
			throw new ArgpError ("The short name must be a single character");
		}
		//Short names must be alphanumeric characters
		var code = o.short.charCodeAt (0);
		if (!((code >= 48 && code <= 57) || (code >= 65 && code <= 90) ||
				(code >= 97 && code <= 122))){
			throw new ArgpError ("The short name must be an alphanumeric character");
		}
		//Cannot be already defined
		for (var p in this._instance._optionsShort){
			if (p === o.short){
				throw new ArgpError ("The short name \"" + o.short +
						"\" is already defined");
			}
		}
	}

	if (o.aliases){
		var me = this;
		o.aliases.forEach (function (alias){
			//Cannot be already defined
			if (alias === o.long) throw new ArgpError ("The alias name \"" + alias +
							"\" is already defined");

			for (var p in me._instance._optionsLong){
				if (p === alias){
					throw new ArgpError ("The alias name \"" + alias +
							"\" is already defined");
				}
			}
		});
	}

	this._instance._option (o);

	return this;
};

Body.prototype.text = function (str, prefix){
	this._instance._option ({
		text: str,
		prefix: prefix
	});
	return this;
};

Body.prototype.usage = function (){
	this._instance._showUsage = true;
	this._instance._option ({
		long: "usage",
		description: "Display a short usage message and exit"
	});
	return this;
};

Body.prototype.version = function (str, o){
	this._instance._packageVersion = false;
	this._instance._version = str;
	var short = !(o && o.short === false);
	var opt = {};
	if (short) opt.short = "v";
	opt.long = "version";
	opt.description = "Output version information and exit";
	this._instance._option (opt);
	return this;
};<commit_msg>speed improvements<commit_after>"use strict";

var Command = require ("./command");
var ArgpError = require ("./error");

var Body = module.exports = function (instance){
	this._instance = instance;
	this._reWhitespace = /\s/;
};

Body.prototype.argument = function (name, o){
	if (this._reWhitespace.test (name)){
		throw new ArgpError ("The argument canot contain white space characters");
	}
	if (this._instance._arguments[name]){
		throw new ArgpError ("The argument \"" + name + "\" is already defined");
	}
	o = o || {};
	if (this._instance._command){
		Command._validateTrailing (o.trailing);
	}
	this._instance._argument (name, o);
	return this;
};

Body.prototype.argv = function (){
	return this._instance.argv ();
};

Body.prototype.columns = function (col1, col2){
	this._instance._option ({
		columns: [col1, col2]
	});
	return this;
};

Body.prototype.command = function (name, o){
	return this._instance.command.call (this._instance, name, o);
};

Body.prototype.help = function (o){
	this._instance._showHelp = true;
	var short = !(o && o.short === false);
	var opt = {};
	if (short) opt.short = "h";
	opt.long = "help";
	opt.description = "Display this help message and exit";
	this._instance._option (opt);
	return this;
};

Body.prototype.main = function (){
	return this._instance.main.call (this._instance);
};

Body.prototype.option = function (o){
	if (!o.long && !o.short) throw new ArgpError ("At least a long name " +
			"must be configured");

	if (o.long){
		//Long names cannot contain whitespaces
		if (this._reWhitespace.test (o.long)){
			throw new ArgpError ("The long name canot contain whitespace characters");
		}
		//Cannot be already defined
		for (var p in this._instance._optionsLong){
			if (p === o.long){
				throw new ArgpError ("The long name \"" + o.long +
						"\" is already defined");
			}
		}
	}

	if (o.short){
		if (o.short.length > 1){
			throw new ArgpError ("The short name must be a single character");
		}
		//Short names must be alphanumeric characters
		var code = o.short.charCodeAt (0);
		if (!((code >= 48 && code <= 57) || (code >= 65 && code <= 90) ||
				(code >= 97 && code <= 122))){
			throw new ArgpError ("The short name must be an alphanumeric character");
		}
		//Cannot be already defined
		for (var p in this._instance._optionsShort){
			if (p === o.short){
				throw new ArgpError ("The short name \"" + o.short +
						"\" is already defined");
			}
		}
	}

	if (o.aliases){
		var me = this;
		o.aliases.forEach (function (alias){
			//Cannot be already defined
			if (alias === o.long) throw new ArgpError ("The alias name \"" + alias +
							"\" is already defined");

			for (var p in me._instance._optionsLong){
				if (p === alias){
					throw new ArgpError ("The alias name \"" + alias +
							"\" is already defined");
				}
			}
		});
	}

	this._instance._option (o);

	return this;
};

Body.prototype.text = function (str, prefix){
	this._instance._option ({
		text: str,
		prefix: prefix
	});
	return this;
};

Body.prototype.usage = function (){
	this._instance._showUsage = true;
	this._instance._option ({
		long: "usage",
		description: "Display a short usage message and exit"
	});
	return this;
};

Body.prototype.version = function (str, o){
	this._instance._packageVersion = false;
	this._instance._version = str;
	var short = !(o && o.short === false);
	var opt = {};
	if (short) opt.short = "v";
	opt.long = "version";
	opt.description = "Output version information and exit";
	this._instance._option (opt);
	return this;
};<|endoftext|>


<commit_before>'use strict';

var usage = require('usage'),
    psTree = require('ps-tree'),
    step = require('step'),
    _ = require('underscore');

var core = {};

core.cpuUsage = function (program) {
  var containerName = program.name;
  var cpuUsageValue = 0.0;

  console.log("Target container: " + program.name);

  step(
    function() {
      psTree(containerName, this);
    },
    function(err, children) {

      var displayUsage = _.after(children.length, function(){
        console.log("Processes:" + children.length);
        console.log("CPU usage:" + cpuUsageValue);
      });

      _.each(children, function(target) {
        var pid = target.PID;

        usage.lookup(pid, function(err, result) {
          if (!err) {
            if (program.verbose) {
              var oneUsage = _.template("PID:<%= pid %>\tCPU:<%= cpu%>");
              console.log(oneUsage({pid: pid, cpu: result.cpu}));
            }

            cpuUsageValue += parseFloat(result.cpu);
            displayUsage();
          }
        });

      });
    }
  );
};

module.exports = core;

<commit_msg>CPU使用率の取得方法修正<commit_after>'use strict';

var usage = require('usage'),
    psTree = require('ps-tree'),
    step = require('step'),
    _ = require('underscore');

var core = {};

core.cpuUsage = function (program) {
  var containerName = program.name;
  var cpuUsageValue = 0.0;

  console.log("Target container: " + program.name);

  step(
    function() {
      psTree(containerName, this);
    },
    function(err, children) {

      var displayUsage = _.after(children.length, function(){
        console.log("Processes:" + children.length);
        console.log("CPU usage:" + cpuUsageValue);
      });

      _.each(children, function(target) {
        var pid = target.PID;

        usage.lookup(pid, function(err, result) {
          if (!err) {
            var oneUsageCpu = parseFloat(result.cpu);

            if (program.verbose) {
              var oneUsage = _.template("PID:<%= pid %>\tCPU:<%= cpu%>");
              console.log(oneUsage({pid: pid, cpu: oneUsageCpu}));
            }

            cpuUsageValue += oneUsageCpu;
            displayUsage();
          }
        });

      });
    }
  );
};

module.exports = core;

<|endoftext|>