<commit_before>#!/usr/bin/env node

const puppeteer = require('puppeteer');
const config = require('./config');
const EmailService = require('./email');
// 用到的通知邮件
const emailService1 = new EmailService('sohu');
const emailService2 = new EmailService('163');
const Utils = require('./utils');
const cookies = config.cookies;

let lastList;
// 搜索链接
const targetUrl = `https://steamcommunity.com/market/search?q=&category_730_ItemSet%5B%5D=any&category_730_ProPlayer%5B%5D=any&category_730_StickerCapsule%5B%5D=any&category_730_TournamentTeam%5B%5D=any&category_730_Weapon%5B%5D=any&category_730_Exterior%5B%5D=tag_WearCategory0&category_730_Type%5B%5D=tag_Type_Hands&appid=730`;
let cookieCount = 0;
let errorCount = 0;

(async () => {
    // const browser = await puppeteer.launch({ headless: false, delay: 1000 });
    const browser = await puppeteer.launch({ headless: true, args: ['--disable-timeouts-for-profiling'] });
    const page = await browser.newPage();
    const viewPort = {
        width: 1280,
        height: 800
    };
    page.setViewport(viewPort);

    try {
        run(page);
    } catch (e) {
        console.log(e);
    }
})();

async function run(page) {
    try {
        await page.deleteCookie(...cookies[cookieCount++ % cookies.length]);
        await page.setCookie(...cookies[cookieCount % cookies.length]);
        await page.goto(targetUrl);
        await extractPage(page);
    } catch (e) {
        console.log(e);
    }
    // schedule下一个扫描
    setTimeout(() => run(page),
        Utils.randomIntFromInterval(config.interval.min, config.interval.max) * 1000
    );
}

async function extractPage(page) {
    const listEls = await page.$$('.market_listing_row_link');
    if (!listEls || !listEls.length) {
        console.log('没有获得物品列表！');
        if (++errorCount >= config.errorCountThreshold) {
            errorCount = 0;
            play(config.errorSoundFilePath);
        }
        return;
    }

    const itemList = [];
    for (let target of listEls) {
        const item = await page.evaluate((el) => {
            const name = el.querySelector('.market_listing_item_name').innerHTML;
            const count = parseInt(el.querySelector('.market_listing_num_listings_qty').innerHTML.replace(',', ''));
            const link = el.href.replace(/(http|https):\/\//, '');
            return { name, count, link };
        }, target);
        itemList.push(item);
    };
    console.log(Utils.getLocaleDateTime());
    console.log(itemList.map(item => getItemMsg(item, false)).join('\n'));
    const increasedItems = getIncreasedItems(itemList, lastList);
    lastList = itemList;
    if (increasedItems.length) {
        const itemMsgs = increasedItems.map(item => getItemMsg(item, true));
        const msg = itemMsgs.join();
        Utils.notify(config.soundFilePath, config.emailSubject, msg, emailService1, emailService2);
    }
}

function getIncreasedItems(newList, oldList) {
    const result = [];
    if (oldList) {
        newList.forEach((item) => {
            const matchedItem = oldList.find(o => item.link === o.link);
            if (matchedItem) {
                if (matchedItem.count < item.count) {
                    result.push(item);
                }
            } else {
                console.log(`新物品: ${JSON.stringify(item)}`);
                result.push(item);
            }
        });
    }
    return result;
}

function getItemMsg(item, includeLink) {
    let msg = `名称: ${item.name}, 数量: ${item.count}`;
    includeLink && (msg += `, 链接: <a href="${item.link}">点击这里</a> \n<br/>`);
    return msg;
}
<commit_msg>add https to link, aslo add time<commit_after>#!/usr/bin/env node

const puppeteer = require('puppeteer');
const config = require('./config');
const EmailService = require('./email');
// 用到的通知邮件
const emailService1 = new EmailService('sohu');
const emailService2 = new EmailService('163');
const Utils = require('./utils');
const play = require('./sound');
const cookies = config.cookies;

let lastList;
// 搜索链接
const targetUrl = `https://steamcommunity.com/market/search?q=&category_730_ItemSet%5B%5D=any&category_730_ProPlayer%5B%5D=any&category_730_StickerCapsule%5B%5D=any&category_730_TournamentTeam%5B%5D=any&category_730_Weapon%5B%5D=any&category_730_Exterior%5B%5D=tag_WearCategory0&category_730_Type%5B%5D=tag_Type_Hands&appid=730`;
let cookieCount = 0;
let errorCount = 0;

(async () => {
    // const browser = await puppeteer.launch({ headless: false, delay: 1000 });
    const browser = await puppeteer.launch({ headless: true, args: ['--disable-timeouts-for-profiling'] });
    const page = await browser.newPage();
    const viewPort = {
        width: 1280,
        height: 800
    };
    page.setViewport(viewPort);

    try {
        run(page);
    } catch (e) {
        console.log(e);
    }
})();

async function run(page) {
    try {
        await page.deleteCookie(...cookies[cookieCount++ % cookies.length]);
        await page.setCookie(...cookies[cookieCount % cookies.length]);
        await page.goto(targetUrl);
        await extractPage(page);
    } catch (e) {
        console.log(e);
    }
    // schedule下一个扫描
    setTimeout(() => run(page),
        Utils.randomIntFromInterval(config.interval.min, config.interval.max) * 1000
    );
}

async function extractPage(page) {
    const listEls = await page.$$('.market_listing_row_link');
    if (!listEls || !listEls.length) {
        console.log('没有获得物品列表！');
        if (++errorCount >= config.errorCountThreshold) {
            errorCount = 0;
            play(config.errorSoundFilePath);
        }
        return;
    }

    const itemList = [];
    for (let target of listEls) {
        const item = await page.evaluate((el) => {
            const name = el.querySelector('.market_listing_item_name').innerHTML;
            const count = parseInt(el.querySelector('.market_listing_num_listings_qty').innerHTML.replace(',', ''));
            const link = el.href.replace(/(http|https):\/\//, '');
            return { name, count, link };
        }, target);
        itemList.push(item);
    };
    console.log(Utils.getLocaleDateTime());
    console.log(itemList.map(item => getItemMsg(item, false)).join('\n'));
    const increasedItems = getIncreasedItems(itemList, lastList);
    lastList = itemList;
    if (increasedItems.length) {
        const itemMsgs = increasedItems.map(item => getItemMsg(item, true));
        const msg = `发现时间: ${Utils.getLocaleDateTime()} \n<br/> ${itemMsgs.join('\n<br/>')}`;
        Utils.notify(config.soundFilePath, config.emailSubject, msg, emailService1, emailService2);
    }
}

function getIncreasedItems(newList, oldList) {
    const result = [];
    if (oldList) {
        newList.forEach((item) => {
            const matchedItem = oldList.find(o => item.link === o.link);
            if (matchedItem) {
                if (matchedItem.count < item.count) {
                    result.push(item);
                }
            } else {
                console.log(`新物品: ${JSON.stringify(item)}`);
                result.push(item);
            }
        });
    }
    return result;
}

function getItemMsg(item, includeLink) {
    let msg = `名称: ${item.name}, 数量: ${item.count}`;
    includeLink && (msg += `, 链接: <a href="https://${item.link}" target="_blank">点击这里</a>`);
    return msg;
}
<|endoftext|>


<commit_before>PDRClient = angular.module("PDRClient", [
  'ngResource',
  'ngRoute',
  'ngSanitize',
  'templates',
  'angular-redactor',
  'angularMoment',
  'ui.router',
  'ui.bootstrap',
  'ui.select2']);

PDRClient.config(['$stateProvider', '$urlRouterProvider',
  function($stateProvider, $urlRouterProvider) {
    $urlRouterProvider.otherwise("/");

    $stateProvider.state('home', {
      url: '/',
      views: {
        '': {
          controller: 'HomeCtrl',
          templateUrl: 'client/views/shared/include_template.html'
        },
        'sidebar': {
          controller: 'SidebarCtrl',
          templateUrl: 'client/views/sidebar/sidebar_generic.html'
       }
      }
    })
    .state('logout', {
      url: '/logout',
      controller: ['$rootScope', '$scope', 'SessionService', '$location',
        function($rootScope, $scope, SessionService, $location) {
          SessionService
            .logout()
            .then(function() {
              $rootScope.$broadcast('session_updated');
              $location.path('/');
            });
      }],
    })
    .state('login', {
      url: '/login',
      views: {
        '': {
          controller: 'LoginCtrl',
          templateUrl: 'client/views/login/login.html'
        },
        'sidebar': {
          controller: 'SidebarCtrl',
          templateUrl: 'client/views/sidebar/sidebar_login.html'
        }
      }
    })
    .state('assessments', {
      url: '/assessments',
      views: {
        '': {
          controller: 'AssessmentsCtrl',
          templateUrl: 'client/views/assessments/index.html'
        },
        'sidebar': {
          controller: 'SidebarCtrl',
          templateUrl: 'client/views/sidebar/sidebar_generic.html'
        }
      }
   })
   .state('assessment_dashboard', {
     url: '/assessments/:id/dashboard',
     views: {
       '': {
         controller: 'AssessmentDashboardCtrl',
         templateUrl: 'client/views/assessments/dashboard.html'
       },
       'sidebar': {
         controller: 'SidebarCtrl',
         templateUrl: 'client/views/sidebar/assessment_dashboard.html'
       }
     }
   })
   .state('assessment_dashboard', {
     url: '/assessments/:id/report',
     views: {
       '': {
         controller: 'AssessmentReportCtrl',
         templateUrl: 'client/views/assessments/report.html'
       },
       'sidebar': {
         controller: 'SidebarCtrl',
         templateUrl: 'client/views/sidebar/assessment_dashboard.html'
       }
     }
   })
   .state('assessment_assign', {
     url: '/assessments/:id/assign',
     views: {
       '': {
         controller: 'AssessmentAssignCtrl',
         templateUrl: 'client/views/assessments/assign/assign.html'
       }
     }
   })
   .state('assessment_edit', {
     url: '/assessments/:id/edit',
     views: {
       '': {
         controller: 'AssessmentEditCtrl',
         templateUrl: 'client/views/assessments/edit.html'
       },
       'sidebar': {
         controller: 'SidebarCtrl',
         templateUrl: 'client/views/sidebar/sidebar_generic.html'
       }
     }
   })
   .state('response_edit', {
     url: '/assessments/:assessment_id/responses/:response_id',
     views: {
       '': {
         controller: 'ResponseCtrl',
         templateUrl: 'client/views/responses/edit.html'
       },
       'sidebar': {
         controller: 'SidebarResponseCardCtrl',
         templateUrl: 'client/views/sidebar/response_card.html'
       }
     }
   })
   .state('consensus_show', {
     url: '/assessments/:assessment_id/consensus/:response_id',
     views: {
       '': {
         controller: 'ConsensusShowCtrl',
         templateUrl: 'client/views/consensus/show.html'
       },
       'sidebar': {
         controller: 'SidebarResponseCardCtrl',
         templateUrl: 'client/views/sidebar/response_card.html'
       }
     }
   })
   .state('consensus_create', {
     url: '/assessments/:assessment_id/consensus',
     views: {
       '': {
         controller: 'ConsensusCreateCtrl',
         templateUrl: 'client/views/consensus/show.html'
       },
       'sidebar': {
         controller: 'SidebarResponseCardCtrl',
         templateUrl: 'client/views/sidebar/sidebar_generic.html'
       }
     }
   })
   .state('signup', {
     url: '/signup',
     views: {
       '': {
         controller: 'SignupCtrl',
         templateUrl: 'client/views/signup/member.html'
       },
       'sidebar': {
         controller: 'SidebarCtrl',
         templateUrl: 'client/views/sidebar/sidebar_login.html'
       }
     }
   })
   .state('signup_facilitator', {
     url: '/signup/facilitator',
     views: {
       '': {
         controller: 'SignupCtrl',
         templateUrl: 'client/views/signup/facilitator.html'
       },
       'sidebar': {
         controller: 'SidebarCtrl',
         templateUrl: 'client/views/sidebar/sidebar_login.html'
       }
     }
   })

    .state('settings', {
      url: '/settings',
      views: {
        '': {
          controller: 'SettingsCtrl',
          templateUrl: 'client/views/settings/settings.html'
        },
        'sidebar': {
          controller: 'SidebarCtrl',
          templateUrl: 'client/views/sidebar/sidebar_generic.html'
        }
      }
    });

  }
]);
<commit_msg>Added report route<commit_after>PDRClient = angular.module("PDRClient", [
  'ngResource',
  'ngRoute',
  'ngSanitize',
  'templates',
  'angular-redactor',
  'angularMoment',
  'ui.router',
  'ui.bootstrap',
  'ui.select2']);

PDRClient.config(['$stateProvider', '$urlRouterProvider',
  function($stateProvider, $urlRouterProvider) {
    $urlRouterProvider.otherwise("/");

    $stateProvider.state('home', {
      url: '/',
      views: {
        '': {
          controller: 'HomeCtrl',
          templateUrl: 'client/views/shared/include_template.html'
        },
        'sidebar': {
          controller: 'SidebarCtrl',
          templateUrl: 'client/views/sidebar/sidebar_generic.html'
       }
      }
    })
    .state('logout', {
      url: '/logout',
      controller: ['$rootScope', '$scope', 'SessionService', '$location',
        function($rootScope, $scope, SessionService, $location) {
          SessionService
            .logout()
            .then(function() {
              $rootScope.$broadcast('session_updated');
              $location.path('/');
            });
      }],
    })
    .state('login', {
      url: '/login',
      views: {
        '': {
          controller: 'LoginCtrl',
          templateUrl: 'client/views/login/login.html'
        },
        'sidebar': {
          controller: 'SidebarCtrl',
          templateUrl: 'client/views/sidebar/sidebar_login.html'
        }
      }
    })
    .state('assessments', {
      url: '/assessments',
      views: {
        '': {
          controller: 'AssessmentsCtrl',
          templateUrl: 'client/views/assessments/index.html'
        },
        'sidebar': {
          controller: 'SidebarCtrl',
          templateUrl: 'client/views/sidebar/sidebar_generic.html'
        }
      }
   })
   .state('assessment_dashboard', {
     url: '/assessments/:id/dashboard',
     views: {
       '': {
         controller: 'AssessmentDashboardCtrl',
         templateUrl: 'client/views/assessments/dashboard.html'
       },
       'sidebar': {
         controller: 'SidebarCtrl',
         templateUrl: 'client/views/sidebar/assessment_dashboard.html'
       }
     }
   })
   .state('assessment_report', {
     url: '/assessments/:id/report',
     views: {
       '': {
         controller: 'AssessmentReportCtrl',
         templateUrl: 'client/views/assessments/report.html'
       },
       'sidebar': {
         controller: 'SidebarCtrl',
         templateUrl: 'client/views/sidebar/assessment_dashboard.html'
       }
     }
   })
   .state('assessment_assign', {
     url: '/assessments/:id/assign',
     views: {
       '': {
         controller: 'AssessmentAssignCtrl',
         templateUrl: 'client/views/assessments/assign/assign.html'
       }
     }
   })
   .state('assessment_edit', {
     url: '/assessments/:id/edit',
     views: {
       '': {
         controller: 'AssessmentEditCtrl',
         templateUrl: 'client/views/assessments/edit.html'
       },
       'sidebar': {
         controller: 'SidebarCtrl',
         templateUrl: 'client/views/sidebar/sidebar_generic.html'
       }
     }
   })
   .state('response_edit', {
     url: '/assessments/:assessment_id/responses/:response_id',
     views: {
       '': {
         controller: 'ResponseCtrl',
         templateUrl: 'client/views/responses/edit.html'
       },
       'sidebar': {
         controller: 'SidebarResponseCardCtrl',
         templateUrl: 'client/views/sidebar/response_card.html'
       }
     }
   })
   .state('consensus_show', {
     url: '/assessments/:assessment_id/consensus/:response_id',
     views: {
       '': {
         controller: 'ConsensusShowCtrl',
         templateUrl: 'client/views/consensus/show.html'
       },
       'sidebar': {
         controller: 'SidebarResponseCardCtrl',
         templateUrl: 'client/views/sidebar/response_card.html'
       }
     }
   })
   .state('consensus_create', {
     url: '/assessments/:assessment_id/consensus',
     views: {
       '': {
         controller: 'ConsensusCreateCtrl',
         templateUrl: 'client/views/consensus/show.html'
       },
       'sidebar': {
         controller: 'SidebarResponseCardCtrl',
         templateUrl: 'client/views/sidebar/sidebar_generic.html'
       }
     }
   })
   .state('signup', {
     url: '/signup',
     views: {
       '': {
         controller: 'SignupCtrl',
         templateUrl: 'client/views/signup/member.html'
       },
       'sidebar': {
         controller: 'SidebarCtrl',
         templateUrl: 'client/views/sidebar/sidebar_login.html'
       }
     }
   })
   .state('signup_facilitator', {
     url: '/signup/facilitator',
     views: {
       '': {
         controller: 'SignupCtrl',
         templateUrl: 'client/views/signup/facilitator.html'
       },
       'sidebar': {
         controller: 'SidebarCtrl',
         templateUrl: 'client/views/sidebar/sidebar_login.html'
       }
     }
   })

    .state('settings', {
      url: '/settings',
      views: {
        '': {
          controller: 'SettingsCtrl',
          templateUrl: 'client/views/settings/settings.html'
        },
        'sidebar': {
          controller: 'SidebarCtrl',
          templateUrl: 'client/views/sidebar/sidebar_generic.html'
        }
      }
    });

  }
]);
<|endoftext|>


<commit_before>"use strict";
(function() {
  function domReady(callback) {
      document.readyState === "interactive" || document.readyState === "complete" ? callback() : document.addEventListener("DOMContentLoaded", callback);
  };

  function kaiosPadNav (e) {
    var childElem = document.querySelectorAll('div, a, input, button, select, textarea,li');
    function nav(num) {
      var currentIndex = childElem[num];
      var next = +(currentIndex.getAttribute('tabindex')) + 1;
      var items = document.querySelectorAll('.items');
      for (var i=items.length; i--;) {
        var itemIndex = items[i].getAttribute('tabindex');
        if (itemIndex == next) {
          items[i].focus();
        };
      }
    }
    for (var i = 0, len = childElem.length; i < len; i++ ) {
      childElem[i].className += " items";
      childElem[i].setAttribute('tabindex', i);
    }

    var handleKeydown = function(e) {
      switch(e.key) {
        case 'ArrowUp':
          nav(-1);
          console.log('You click on ArrowUp', event.which || event.keyCode || 0);
          break;
        case 'ArrowDown':
          nav(1);
          console.log('You click on ArrowDown', event.which || event.keyCode || 0)
          break;
        case 'ArrowRight':
          nav(1);
          console.log('You click on ArrowRight', event.which || event.keyCode || 0)
          break;
        case 'ArrowLeft':
          nav(-1);
          console.log('You click on ArrowLeft', event.which || event.keyCode || 0)
          break;
      }
    };
    document.activeElement.addEventListener('keydown', handleKeydown);
  };

  var softkeyCallback = {
    left: function() { console.log('You click on SoftLeft') },
    center: function() { console.log('You click on Enter') },
    right: function() { console.log('You click on SoftRight') }
  };
  function handleKeyDownEvent(evt) {
    switch (evt.key) {
        case 'SoftLeft':
            // Action case press left key
            softkeyCallback.left();
        break;

        case 'SoftRight':
            // Action case press right key
            softkeyCallback.right();
        break;

        case 'Enter':
            // Action case press center key
            softkeyCallback.center();
        break;
    }
  };

  domReady(function() {
    kaiosPadNav();
    document.addEventListener('keydown', handleKeyDownEvent);
  });
})();
<commit_msg>update keypad console log print<commit_after>"use strict";
(function() {
  function domReady(callback) {
      document.readyState === "interactive" || document.readyState === "complete" ? callback() : document.addEventListener("DOMContentLoaded", callback);
  };

  function kaiosPadNav (e) {
    var childElem = document.querySelectorAll('div, a, input, button, select, textarea,li');
    for (var i = 0, len = childElem.length; i < len; i++ ) {
      childElem[i].className += " items";
      childElem[i].setAttribute('tabindex', i);
    }
    function nav(num) {
      var currentIndex = childElem[num];
      var next = +(currentIndex.getAttribute('tabindex')) + 1;
      var items = document.querySelectorAll('.items');
      for (var i=items.length; i--;) {
        var itemIndex = items[i].getAttribute('tabindex');
        if (itemIndex == next) {
          items[i].focus();
        };
      }
    }
    var handleKeydown = function(e) {
      switch(e.key) {
        case 'ArrowUp':
          nav(-1);
          console.log('You click on ArrowUp', event.which || event.keyCode || 0);
          break;
        case 'ArrowDown':
          nav(1);
          console.log('You click on ArrowDown', event.which || event.keyCode || 0)
          break;
        case 'ArrowRight':
          nav(1);
          console.log('You click on ArrowRight', event.which || event.keyCode || 0)
          break;
        case 'ArrowLeft':
          nav(-1);
          console.log('You click on ArrowLeft', event.which || event.keyCode || 0)
          break;
      }
    };
    document.activeElement.addEventListener('keydown', handleKeydown);
  };

  var softkeyCallback = {
    left: function() { console.log('You click on SoftLeft') },
    center: function() { console.log('You click on Enter') },
    right: function() { console.log('You click on SoftRight') }
  };
  function handleKeyDownEvent(evt) {
    switch (evt.key) {
        case 'SoftLeft':
            // Action case press left key
            softkeyCallback.left();
        break;

        case 'SoftRight':
            // Action case press right key
            softkeyCallback.right();
        break;

        case 'Enter':
            // Action case press center key
            softkeyCallback.center();
        break;
    }
  };

  domReady(function() {
    kaiosPadNav();
    document.addEventListener('keydown', handleKeyDownEvent);
  });
})();
<|endoftext|>


<commit_before>// 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
//
//   http://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.

couchTests.view_sandboxing = function(debug) {
  var db = new CouchDB("test_suite_db", {"X-Couch-Full-Commit":"false"});
  db.deleteDb();
  db.createDb();
  if (debug) debugger;

  var doc = {integer: 1, string: "1", array: [1, 2, 3]};
  T(db.save(doc).ok);
/*
  // make sure that attempting to change the document throws an error
  var results = db.query(function(doc) {
    doc.integer = 2;
    emit(null, doc);
  });
  T(results.total_rows == 0);

  var results = db.query(function(doc) {
    doc.array[0] = 0;
    emit(null, doc);
  });
  T(results.total_rows == 0);
*/
  // make sure that a view cannot invoke interpreter internals such as the
  // garbage collector
  var results = db.query(function(doc) {
    gc();
    emit(null, doc);
  });
  T(results.total_rows == 0);

  // make sure that a view cannot access the map_funs array defined used by
  // the view server
  var results = db.query(function(doc) { map_funs.push(1); emit(null, doc); });
  T(results.total_rows == 0);

  // make sure that a view cannot access the map_results array defined used by
  // the view server
  var results = db.query(function(doc) { map_results.push(1); emit(null, doc); });
  T(results.total_rows == 0);
};
<commit_msg>Seal documents before passing them to map functions (JavaScript view server only). This prevents one map function from modifying a document before it's passed to another map function. Has no effect on array fields for some Spidermonkey versions (see https://bugzilla.mozilla.org/show_bug.cgi?id=449657).<commit_after>// 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
//
//   http://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.

couchTests.view_sandboxing = function(debug) {
  var db = new CouchDB("test_suite_db", {"X-Couch-Full-Commit":"false"});
  db.deleteDb();
  db.createDb();
  if (debug) debugger;

  var doc = {integer: 1, string: "1", array: [1, 2, 3]};
  T(db.save(doc).ok);
/*
  // make sure that attempting to change the document throws an error
  var results = db.query(function(doc) {
    doc.integer = 2;
    emit(null, doc);
  });
  T(results.total_rows == 0);

  var results = db.query(function(doc) {
    doc.array[0] = 0;
    emit(null, doc);
  });
  T(results.total_rows == 0);
*/
  // make sure that a view cannot invoke interpreter internals such as the
  // garbage collector
  var results = db.query(function(doc) {
    gc();
    emit(null, doc);
  });
  T(results.total_rows == 0);

  // make sure that a view cannot access the map_funs array defined used by
  // the view server
  var results = db.query(function(doc) { map_funs.push(1); emit(null, doc); });
  T(results.total_rows == 0);

  // make sure that a view cannot access the map_results array defined used by
  // the view server
  var results = db.query(function(doc) { map_results.push(1); emit(null, doc); });
  T(results.total_rows == 0);

  // test for COUCHDB-925
  // altering 'doc' variable in map function affects other map functions
  var ddoc = {
    _id: "_design/foobar",
    language: "javascript",
    views: {
      view1: {
        map:
          (function(doc) {
            if (doc.values) {
              doc.values = [666];
            }
            if (doc.tags) {
              doc.tags.push("qwerty");
            }
            if (doc.tokens) {
              doc.tokens["c"] = 3;
            }
          }).toString()
      },
      view2: {
        map:
          (function(doc) {
            if (doc.values) {
              emit(doc._id, doc.values);
            }
            if (doc.tags) {
              emit(doc._id, doc.tags);
            }
            if (doc.tokens) {
              emit(doc._id, doc.tokens);
            }
          }).toString()
      }
    }
  };
  var doc1 = {
    _id: "doc1",
    values: [1, 2, 3]
  };
  var doc2 = {
    _id: "doc2",
    tags: ["foo", "bar"],
    tokens: {a: 1, b: 2}
  };

  db.deleteDb();
  db.createDb();
  T(db.save(ddoc).ok);
  T(db.save(doc1).ok);
  T(db.save(doc2).ok);

  var view1Results = db.view(
    "foobar/view1", {bypass_cache: Math.round(Math.random() * 1000)});
  var view2Results = db.view(
    "foobar/view2", {bypass_cache: Math.round(Math.random() * 1000)});

  TEquals(0, view1Results.rows.length, "view1 has 0 rows");
  TEquals(3, view2Results.rows.length, "view2 has 3 rows");

  TEquals(doc1._id, view2Results.rows[0].key);
  TEquals(doc2._id, view2Results.rows[1].key);
  TEquals(doc2._id, view2Results.rows[2].key);

  // https://bugzilla.mozilla.org/show_bug.cgi?id=449657
  TEquals(3, view2Results.rows[0].value.length,
    "Warning: installed SpiderMonkey version doesn't allow sealing of arrays");
  if (view2Results.rows[0].value.length === 3) {
    TEquals(1, view2Results.rows[0].value[0]);
    TEquals(2, view2Results.rows[0].value[1]);
    TEquals(3, view2Results.rows[0].value[2]);
  }

  TEquals(1, view2Results.rows[1].value["a"]);
  TEquals(2, view2Results.rows[1].value["b"]);
  TEquals('undefined', typeof view2Results.rows[1].value["c"],
    "doc2.tokens object was not sealed");

  TEquals(2, view2Results.rows[2].value.length,
    "Warning: installed SpiderMonkey version doesn't allow sealing of arrays");
  if (view2Results.rows[2].value.length === 2) {
    TEquals("foo", view2Results.rows[2].value[0]);
    TEquals("bar", view2Results.rows[2].value[1]);
  }

  // cleanup
  db.deleteDb();
};
<|endoftext|>


<commit_before>;(function()
{
	// CommonJS
	SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);

	function Brush()
	{
		var keywords =	'if fi then elif else for do done until while break continue case esac function return in eq ne ge le';
		var commands =  'alias apropos awk basename base64 bash bc bg builtin bzip2 cal cat cd cfdisk chgrp chmod chown chroot' +
						'cksum clear cmp comm command cp cron crontab csplit cut date dc dd ddrescue declare df ' +
						'diff diff3 dig dir dircolors dirname dirs du echo egrep eject enable env ethtool eval ' +
						'exec exit expand export expr false fdformat fdisk fg fgrep file find fmt fold format ' +
						'free fsck ftp gawk gcc gdb getconf getopts grep groups gzip hash head history hostname id ifconfig ' +
						'import install join kill less let ln local locate logname logout look lpc lpr lprint ' +
						'lprintd lprintq lprm ls lsof make man mkdir mkfifo mkisofs mknod more mount mtools ' +
						'mv nasm ndisasm netstat nice nl nohup nslookup od open op passwd paste pathchk ping popd pr printcap ' +
						'printenv printf ps pushd pwd quota quotacheck quotactl ram rcp read readonly renice ' +
						'remsync rm rmdir rsync screen scp sdiff sed select seq set sftp shift shopt shutdown ' +
						'sleep sort source split ssh strace strings su sudo sum symlink sync tail tar tee test time ' +
						'times touch top traceroute trap tr true tsort tty type ulimit umask umount unalias ' +
						'uname unexpand uniq units unset unshar useradd usermod users uuencode uudecode v vdir ' +
						'vi watch wc whereis which who whoami Wget xargs xxd yes'
						;

		this.regexList = [
			{ regex: /^#!.*$/gm,											css: 'preprocessor bold' },
			{ regex: /\/[\w-\/]+/gm,										css: 'plain' },
			{ regex: SyntaxHighlighter.regexLib.singleLinePerlComments,		css: 'comments' },		// one line comments
			{ regex: SyntaxHighlighter.regexLib.doubleQuotedString,			css: 'string' },		// double quoted strings
			{ regex: SyntaxHighlighter.regexLib.singleQuotedString,			css: 'string' },		// single quoted strings
			{ regex: new RegExp(this.getKeywords(keywords), 'gm'),			css: 'keyword' },		// keywords
			{ regex: new RegExp(this.getKeywords(commands), 'gm'),			css: 'functions' }		// commands
			];
	}

	Brush.prototype	= new SyntaxHighlighter.Highlighter();
	Brush.aliases	= ['bash', 'shell', 'sh'];

	SyntaxHighlighter.brushes.Bash = Brush;

	// CommonJS
	typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
<commit_msg>Adding support for here documents in Bash Brush<commit_after>;(function()
{
	// CommonJS
	SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);

	function Brush()
	{
		function hereDocProcess(match, regexInfo)
		{
			var constructor = SyntaxHighlighter.Match,
				result = []
				;
			if (match.here_doc != null)
				result.push(new constructor(match.here_doc, match.index + match[0].indexOf(match.here_doc), 'string'));

			if (match.full_tag != null)
				result.push(new constructor(match.full_tag, match.index, 'preprocessor'));

			if (match.end_tag != null)
				result.push(new constructor(match.end_tag, match.index + match[0].lastIndexOf(match.end_tag), 'preprocessor'));
			return result;
		}
		var keywords =	'if fi then elif else for do done until while break continue case esac function return in eq ne ge le';
		var commands =  'alias apropos awk basename base64 bash bc bg builtin bzip2 cal cat cd cfdisk chgrp chmod chown chroot' +
						'cksum clear cmp comm command cp cron crontab csplit cut date dc dd ddrescue declare df ' +
						'diff diff3 dig dir dircolors dirname dirs du echo egrep eject enable env ethtool eval ' +
						'exec exit expand export expr false fdformat fdisk fg fgrep file find fmt fold format ' +
						'free fsck ftp gawk gcc gdb getconf getopts grep groups gzip hash head history hostname id ifconfig ' +
						'import install join kill less let ln local locate logname logout look lpc lpr lprint ' +
						'lprintd lprintq lprm ls lsof make man mkdir mkfifo mkisofs mknod more mount mtools ' +
						'mv nasm ndisasm netstat nice nl nohup nslookup od open op passwd paste pathchk ping popd pr printcap ' +
						'printenv printf ps pushd pwd quota quotacheck quotactl ram rcp read readonly renice ' +
						'remsync rm rmdir rsync screen scp sdiff sed select seq set sftp shift shopt shutdown ' +
						'sleep sort source split ssh strace strings su sudo sum symlink sync tail tar tee test time ' +
						'times touch top traceroute trap tr true tsort tty type ulimit umask umount unalias ' +
						'uname unexpand uniq units unset unshar useradd usermod users uuencode uudecode v vdir ' +
						'vi watch wc whereis which who whoami Wget xargs xxd yes'
						;

		this.regexList = [
			{ regex: /^#!.*$/gm,											css: 'preprocessor bold' },
			{ regex: /\/[\w-\/]+/gm,										css: 'plain' },
			{ regex: SyntaxHighlighter.regexLib.singleLinePerlComments,		css: 'comments' },		// one line comments
			{ regex: SyntaxHighlighter.regexLib.doubleQuotedString,			css: 'string' },		// double quoted strings
			{ regex: SyntaxHighlighter.regexLib.singleQuotedString,			css: 'string' },		// single quoted strings
			{ regex: new RegExp(this.getKeywords(keywords), 'gm'),			css: 'keyword' },		// keywords
			{ regex: new RegExp(this.getKeywords(commands), 'gm'),			css: 'functions' },		// commands
			{ regex: new XRegExp("(?<full_tag>(<|<){2}(?<tag>\\w+)) .*$(?<here_doc>[\\s\\S]*)(?<end_tag>^\\k<tag>$)",'gm'),	func: hereDocProcess }
			];
	}

	Brush.prototype	= new SyntaxHighlighter.Highlighter();
	Brush.aliases	= ['bash', 'shell', 'sh'];

	SyntaxHighlighter.brushes.Bash = Brush;

	// CommonJS
	typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
})();
<|endoftext|>


<commit_before>import 'react-native';
import React from 'react';
import Index from '../index.android.js';

// Note: test renderer must be required after react-native.
import renderer  from 'react-test-renderer';

it('renders correctly', () => {
  const tree = renderer.create(
    <Index />
  );
});
<commit_msg>Update index.android.js<commit_after>import 'react-native';
import React from 'react';
import Index from '../index.android.js';

// Note: test renderer must be required after react-native.
import renderer  from 'react-test-renderer';

it('renders correctly', () => {
  const tree = renderer.create(
    <AppNavigator />
    ).toJSON();
  expect(tree).toMatchSnapshot();
});
<|endoftext|>


<commit_before>/*

    #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=#
      This file is part of the Smart Developer Hub Project:
        http://www.smartdeveloperhub.org/
      Center for Open Middleware
            http://www.centeropenmiddleware.com/
    #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=#
      Copyright (C) 2015 Center for Open Middleware.
    #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=#
      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
                http://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.
    #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=#
*/

'use strict';

var uuid = require('node-uuid');

/**
 * Get full API Swagger JSON description.
 * This method use express (http://expressjs.com/)
 * @param req Request http://expressjs.com/api.html#req
 * @param res Response http://expressjs.com/api.html#res
 * @param next Pass control to the next handler
 */
module.exports.login = function login (req, res, next) {
    console.log("Trying to login in SDH-API");
    passport.authenticate('ldapauth', {session: false})(req, res, function() {
        console.log("... LDAP ...");
        if(req.user != null) {
            console.log("LDAP credentials validation");
            //Create a new session
            var token = uuid.v4();
            GLOBAL.SESSIONS[token] = {
                info: {
                    lastAccess: Date.now()
                },
                data: req.user
            };

            var thePos;
            var theAvatar;
            // TODO add in req.user 'positions': {orgId: [positionId]} and 'roles': {projectId: [roleId]}
            if (usersById[req.user.uidNumber] == undefined) {
                thePos = {1:[69]};
            }
            else {
                thePos = usersById[req.user.uidNumber].positionsByOrgId;
            }
            req.user["positions"] = thePos;
            if (typeof usersById[req.user.uidNumber].avatar == 'undefined') {
                theAvatar = "http://hospitalfranciscovilar.com.br/wp-content/uploads/2013/11/gravatar-60-grey.jpg";
                req.user["avatar"] = theAvatar;
            } else {
                theAvatar = usersById[req.user.uidNumber].avatar;
                req.user["avatar"] = theAvatar;
            }

            console.log("positions: " + thePos);
            console.log(JSON.stringify({token: token, user: req.user}));
            res.statusCode = 200;
            res.setHeader('Content-Type', 'application/json');
            res.end(JSON.stringify({token: token, user: req.user}));
        } else {
            console.log("Login Error. User '" + req.body.username + '"');
            res.statusCode = 401;
            res.end();
        }

    });
};

function randomIntFromInterval(min,max) {
    return Math.floor(Math.random()*(max-min+1)+min);
}

module.exports.check = function check (req, res, next) {

    passport.authenticate('bearer', {session: false})(req, res, function() {

        res.statusCode = 200;
        res.end();
    });

};

module.exports.logout = function logout(req, res, next) {

    passport.authenticate('bearer', {session: false})(req, res, function() {

        // TODO make sessions global if necessary
        var Sessions = require('../sessions');

        //Remove the session
        var token = Sessions.getToken(req);
        var session = Sessions.getSession(token);
        if(session != null) {
            Sessions.deleteSession(token);
        }

        res.statusCode = 200;
        res.end();
    });

};<commit_msg>Change Auth log to the new log system<commit_after>/*

    #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=#
      This file is part of the Smart Developer Hub Project:
        http://www.smartdeveloperhub.org/
      Center for Open Middleware
            http://www.centeropenmiddleware.com/
    #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=#
      Copyright (C) 2015 Center for Open Middleware.
    #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=#
      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
                http://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.
    #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=#
*/

'use strict';

var uuid = require('node-uuid');

/**
 * Get full API Swagger JSON description.
 * This method use express (http://expressjs.com/)
 * @param req Request http://expressjs.com/api.html#req
 * @param res Response http://expressjs.com/api.html#res
 * @param next Pass control to the next handler
 */
module.exports.login = function login (req, res, next) {
    log.info("Trying to login in SDH-API");
    passport.authenticate('ldapauth', {session: false})(req, res, function() {
        log.debug("LDAP Connected");
        if(req.user != null) {
            log.trace("LDAP credentials validation");
            //Create a new session
            var token = uuid.v4();
            GLOBAL.SESSIONS[token] = {
                info: {
                    lastAccess: Date.now()
                },
                data: req.user
            };

            var thePos;
            var theAvatar;
            // TODO add in req.user 'positions': {orgId: [positionId]} and 'roles': {projectId: [roleId]}
            if (usersById[req.user.uidNumber] == undefined) {
                thePos = {1:[69]};
            }
            else {
                thePos = usersById[req.user.uidNumber].positionsByOrgId;
            }
            req.user["positions"] = thePos;
            if (typeof usersById[req.user.uidNumber].avatar == 'undefined') {
                theAvatar = "http://hospitalfranciscovilar.com.br/wp-content/uploads/2013/11/gravatar-60-grey.jpg";
                req.user["avatar"] = theAvatar;
            } else {
                theAvatar = usersById[req.user.uidNumber].avatar;
                req.user["avatar"] = theAvatar;
            }

            log.info(JSON.stringify({token: token, user: req.user}));
            res.statusCode = 200;
            res.setHeader('Content-Type', 'application/json');
            res.end(JSON.stringify({token: token, user: req.user}));
        } else {
            log.error("Login Error. User '" + req.body.username + '"');
            res.statusCode = 401;
            res.end();
        }

    });
};

function randomIntFromInterval(min,max) {
    return Math.floor(Math.random()*(max-min+1)+min);
}

module.exports.check = function check (req, res, next) {

    passport.authenticate('bearer', {session: false})(req, res, function() {

        res.statusCode = 200;
        res.end();
    });

};

module.exports.logout = function logout(req, res, next) {

    passport.authenticate('bearer', {session: false})(req, res, function() {

        // TODO make sessions global if necessary
        var Sessions = require('../sessions');

        //Remove the session
        var token = Sessions.getToken(req);
        var session = Sessions.getSession(token);
        if(session != null) {
            Sessions.deleteSession(token);
        }

        res.statusCode = 200;
        res.end();
    });

};<|endoftext|>


<commit_before>angular.module('run.controller', [])

.controller('RunController', function($scope, $timeout, $location, Geo){
  $scope.raceStarted = 0;
  $scope.startTime;
  $scope.userLocation;
  $scope.destination;

  var tick = function() {
    $scope.time = Math.floor((Date.now() - $scope.startTime)/1000);
    $timeout(tick, 100)
  }

  $scope.startRun = function() {
    $scope.startTime = Date.now();
    $scope.raceStarted = true;
    tick();
  }

  $scope.currentCoords = {
    lat: null,
    lng: null
  };
  // $scope.getCurrentCoords = function() {
  //   console.log('ran');
  //   Geo.getCurrentCoords(function(coordsObj) {
  //     $scope.currentCoords = coordsObj;
  //     console.log('$scope.currentCoords.lat: ', $scope.currentCoords.lat);
  //     console.log('$scope.currentCoords.lng: ', $scope.currentCoords.lng);
  //   });
  // };

  $scope.makeInitialMap = function($scope) {
    console.log('in controller');
    Geo.makeInitialMap($scope);
  };

  $scope.makeInitialMap($scope);

  $scope.updateCurrentPosition = function($scope, $location) {
    Geo.updateCurrentPosition($scope);
    $scope.checkIfFinished($location);
  };

  $scope.checkIfFinished = function($location) {
    console.log('check if finished');
    if ($scope.destination && $scope.userLocation) {
      var conv = 110.574;
      var currLat = $scope.destination.lat;
      var currLng = $scope.destination.lng;
      var destLat = $scope.userLocation.lat;
      var destLng = $scope.userLocation.lng;
      var distRemaining = Math.sqrt(Math.pow((currLat - destLat), 2) + Math.pow((currLng - destLng) , 2));

      if (distRemaining < 0.0008) {
        $location.path('/finish');
        clearInterval($scope.geoUpdater);
      }
    }
  }

  // Determine user location and update map each second
<<<<<<< HEAD
<<<<<<< HEAD
  $scope.geoUpdater = setInterval(function() {$scope.updateCurrentPosition($scope, $location)}, 1000);
=======
  $scope.geoUpdater = setInterval(function() {$scope.updateCurrentPosition($scope)}, 1000);
>>>>>>> Modify race end conditions
=======
  $scope.geoUpdater = setInterval(function() {$scope.updateCurrentPosition($scope, $location)}, 1000);
>>>>>>> Determine whether user has reached destination

  // Stop geotracker upon canceling run
  $scope.stopGeoUpdater = function() {
    clearInterval($scope.geoUpdater);
  };
})
<commit_msg>Resolve ending newline<commit_after>angular.module('run.controller', [])

.controller('RunController', function($scope, $timeout, $location, Geo){
  $scope.raceStarted = 0;
  $scope.startTime;
  $scope.userLocation;
  $scope.destination;

  var tick = function() {
    $scope.time = Math.floor((Date.now() - $scope.startTime)/1000);
    $timeout(tick, 100)
  }

  $scope.startRun = function() {
    $scope.startTime = Date.now();
    $scope.raceStarted = true;
    tick();
  }

  $scope.currentCoords = {
    lat: null,
    lng: null
  };
  // $scope.getCurrentCoords = function() {
  //   console.log('ran');
  //   Geo.getCurrentCoords(function(coordsObj) {
  //     $scope.currentCoords = coordsObj;
  //     console.log('$scope.currentCoords.lat: ', $scope.currentCoords.lat);
  //     console.log('$scope.currentCoords.lng: ', $scope.currentCoords.lng);
  //   });
  // };

  $scope.makeInitialMap = function($scope) {
    console.log('in controller');
    Geo.makeInitialMap($scope);
  };

  $scope.makeInitialMap($scope);

  $scope.updateCurrentPosition = function($scope, $location) {
    Geo.updateCurrentPosition($scope);
    $scope.checkIfFinished($location);
  };

  $scope.checkIfFinished = function($location) {
    if ($scope.destination && $scope.userLocation) {
      var currLat = $scope.destination.lat;
      var currLng = $scope.destination.lng;
      var destLat = $scope.userLocation.lat;
      var destLng = $scope.userLocation.lng;
      var distRemaining = Math.sqrt(Math.pow((currLat - destLat), 2) + Math.pow((currLng - destLng) , 2));

      if (distRemaining < 0.0008) {
        $location.path('/finish');
        clearInterval($scope.geoUpdater);
      }
    }
  }

  // Determine user location and update map each second
<<<<<<< HEAD
<<<<<<< HEAD
  $scope.geoUpdater = setInterval(function() {$scope.updateCurrentPosition($scope, $location)}, 1000);
=======
  $scope.geoUpdater = setInterval(function() {$scope.updateCurrentPosition($scope)}, 1000);
>>>>>>> Modify race end conditions
=======
  $scope.geoUpdater = setInterval(function() {$scope.updateCurrentPosition($scope, $location)}, 1000);
>>>>>>> Determine whether user has reached destination

  // Stop geotracker upon canceling run
  $scope.stopGeoUpdater = function() {
    clearInterval($scope.geoUpdater);
  };
})
<|endoftext|>


<commit_before>var React = require('react');
var axios = require('axios');

export default class ControlPanel extends React.Component {
    //TODO (#31): add listeners for Keyboard controls
    constructor(props) {
        super(props);
        this.state = {
            power: 50,
            discoveredBots: [],
            keyboard: false,
            xbox: false,
            trackedBots: [],
        };

        this.handleInputChange = this.handleInputChange.bind(this);
        this.updateDiscoveredBots = this.updateDiscoveredBots.bind(this);
        this.sendKV = this.sendKV.bind(this);
        this.startLogging = this.startLogging.bind(this);
        this.sendMotors = this.sendMotors.bind(this);
        this.removeBot = this.removeBot.bind(this);
        this.xboxToggle = this.xboxToggle.bind(this);
        this.getTrackedBots = this.getTrackedBots.bind(this);
        this.selectBot = this.selectBot.bind(this);
        this.onKeyDown = this.onKeyDown.bind(this);
        window.addEventListener('keydown', this.onKeyDown);

    }

     /* sends a command to bot according to the button pressed */
    onKeyDown(event){
        if (this.state.keyboard){
           if(event.keyCode==87) {
                // If the 'W' key is pressed,move forward
                this.sendMotors(20,20,20,20);
                var a=this;
                setTimeout(function(){
                    a.sendMotors(0,0,0,0);
                },500);
            }
            else if (event.keyCode==65){
                // If the 'A' key is pressed, turn left
                this.sendMotors(0,20,0,0);
                var a=this;
                setTimeout(function(){
                    a.sendMotors(0,0,0,0);
                },500);
            }
            else if (event.keyCode==68){
                // If the 'D' key is pressed, turn right
                this.sendMotors(20,0,0,0);
                var a=this;
                setTimeout(function(){
                    a.sendMotors(0,0,0,0);
                },500);
            }
            else if(event.keyCode==83){
                //If the 'S' ket is pressed,move backward
                this.sendMotors(-20,-20,-20,-20);
                var a=this;
                setTimeout(function(){
                    a.sendMotors(0,0,0,0);
                },500);
            }
        }
    }

    /* handler for input changes to modify the state */
    handleInputChange(event) {
        const target = event.target;
        const value = target.value;
        const name = target.name;
        if (name=="xbox"){
            this.setState({
                [name]: target.checked
            });
            this.xboxToggle(target.checked);
        } else if (name=="keyboard"){
            this.setState({
                [name]: target.checked
            });
            console.log(this.state.keyboard)
        } else {
            this.setState({
                [name]: value
            });
        }
    }

    /**
     * Updates tracked bots before page load.
     */
    componentWillMount() {
        this.getTrackedBots()
    }

    /* sends a key-value command to bot */
    sendKV(event){
        const pow = this.state.power;
        const target = event.target;
        if(target.id=="fwd") {
            this.sendMotors(pow, pow, pow, pow);
        }
        else if(target.id=="bck") {
            this.sendMotors(-pow, -pow, -pow, -pow);
        }
        else if(target.id=="lft") {
            this.sendMotors(-pow, pow, -pow, pow);
        }
        else if(target.id=="rt") {
            this.sendMotors(pow, -pow, pow, -pow);
        }
        else if(target.id=="cw"){
            this.sendMotors(pow, -pow, pow, -pow);
        }
        else if(target.id=="ccw"){
            this.sendMotors(-pow, pow, -pow, pow);
        }
        else if(target.id=="stop"){
            this.sendMotors(0,0,0,0);
        }
        else if(target.id=="log") {
            this.startLogging();
        }
        else {
            axios({
                method:'POST',
                url:'/sendKV',
                data: JSON.stringify({
                    key: document.getElementById('kv_key').value,
                    value: document.getElementById('kv_value').value,
                    name: this.props.currentBot
                }),
            })
            .then(function(response) {
                console.log('sent kv');
            })
            .catch(function (error) {
                console.warn(error);
            });
        }
    }

    /* sends a motor command to bot
    * input: front left, front right, back left, back right (all ints)
    * */
    sendMotors(fl,fr,bl,br){
        const _this = this;
        axios({
            method:'POST',
            url:'/commandBot',
            data: JSON.stringify({
                name: this.props.currentBot,
                fl: fl,
                fr: fr,
                bl: bl,
                br: br
            }),
        })
        .then(function(response) {
            console.log('Sent motor command: ' + response)
        })
        .catch(function (error) {
            console.warn(error);
        });
    }

    /**
     * Gets bots currently tracked
     */
    getTrackedBots() {
        const _this = this;
        axios({
            method:'POST',
            url:'/getTrackedBots',
            })
                .then(function(response) {
                    _this.setState({trackedBots: response.data});
            })
                .catch(function (error) {
                    console.log(error);
        });
    }

    /**
     * Handles onChange for bot dropdown. Changes currently selected bot.
     */
    selectBot(event) {
        this.props.setCurrentBot(event.target.value);
    }

    /* starts data logging */
    startLogging(){
        console.log("logging data listener");
        axios({
            method:'POST',
            url:'/logdata',
            data: JSON.stringify({name: this.props.currentBot}),
            processData: false,
        })
        .then(function(response) {
            console.log('started logging data');
        })
        .catch(function (error) {
            console.warn(error);
        });
    }

    /* removes selected bot from list */
    removeBot(){
        console.log("remove bot listener");
        axios({
            method:'POST',
            url:'/removeBot',
            data: JSON.stringify({name: this.props.currentBot}),
        })
        .then(function(response) {
            console.log('removed bot successfully');
        })
        .catch(function (error) {
            console.warn(error);
        });
    }

    /* toggles xbox controls on or off */
    xboxToggle(checked){
        console.log('xboxToggle '+checked);
        if (checked){
            axios({
                method:'POST',
                url:'/runXbox',
                data: JSON.stringify({name: this.props.currentBot}),
            })
            .then(function(response) {
                console.log('successfully toggled Xbox ON');
            })
            .catch(function (error) {
                console.warn(error);
            });
        } else {
            axios({
                method:'POST',
                url:'/stopXbox',
                data: JSON.stringify({name: this.props.currentBot}),
            })
            .then(function(response) {
                console.log('successfully toggled Xbox OFF');
            })
            .catch(function (error) {
                console.warn(error);
            });
        }
    }

    updateDiscoveredBots(){
        //TODO (#32) - change below request to axios
        //        $.ajax({
        //            method: "POST",
        //            url: '/discoverBots',
        //            dataType: 'json',
        //            data: '',
        //            contentType: 'application/json',
        //            success: function (data) {
        //                 //Check if discovered_bots and data are the same (check length and then contents)
        //                if(data.length != discovered_bots.length){
        //                    //If not then clear list and re-make displayed elements
        //                    redoDiscoverList(data);
        //                }
        //                else{
        //                    //Check value to ensure both structures contain the same data
        //                    for(let x=0;x<data.length;x++){
        //                        if(data[x]!=discovered_bots[x]){
        //                            redoDiscoverList(data);
        //                            //Prevent the list from being remade constantly
        //                            break;
        //                        }
        //                    }
        //                }
        //                setTimeout(updateDiscoveredBots,3000); // Try again in 3 sec
        //            }
        //        });
    }

    redoDiscoverList(data){
        let new_bots = [];

        for (let i = 0; i < data.length; i++) {
            //Trim the forward-slash
            var ip_address = data[i].substring(1);
            new_bots.push(ip_address)
        }
        this.setState({discoveredBots: new_bots})
    }

    render(){
        return (

                Control Panel

Movement controls:

                                 Choose bot:
                                <select value={this.props.currentBot} onChange={this.selectBot}> id="botlist" name="bots">
                                    <option value="(DEBUG) Sim Bot">(DEBUG) Sim Bot</option>
                                    {
                                        this.state.trackedBots.map(function(botname, idx){
                                            return <option
                                                        key={idx}
                                                        value={botname}>
                                                   {botname}
                                                   </option>
                                        })
                                    }
                                </select>

                        <button className="btn btn-danger" id="removeBot" onClick={this.removeBot}>Remove Bot</button>

                        Power ({this.state.power}):
                        <input id="power" type="range" name="power" min="0" max="100" value={this.state.power} defaultValue="50" onChange={this.handleInputChange}/>

                        <button className="btn" id="ccw" onClick={this.sendKV}>turn CCW</button>
                        <button className="btn" id="fwd" onClick={this.sendKV}>forward</button>
                        <button className="btn" id="cw" onClick={this.sendKV}>turn CW</button>

                        <button className="btn" id="lft" onClick={this.sendKV}>left</button>
                        <button className="btn btn-danger" id="stop" onClick={this.sendKV}>STOP</button>
                        <button className="btn" id="rt" onClick={this.sendKV}>right</button>

                        <button className="btn btn-success" id="log" onClick={this.sendKV}>log data</button>
                        <button className="btn" id="bck" onClick={this.sendKV}>backward</button>

                            Keyboard Controls

                                <input name="keyboard" type="checkbox" id="keyboard-controls" onChange={this.handleInputChange} />

                            Xbox Controls

                                <input name="xbox" type="checkbox" id="xbox-controls" onChange={this.handleInputChange}/>

                        <input type="text" id="kv_key" placeholder="Key (e.g. WHEELS)"/>
                        <input type="text" id="kv_value" placeholder="Value (e.g. 10,10)"/>
                        <button id="sendkv" onClick={this.sendKV} className="btn btn-success">Send KV</button>

        )
    }
}

// $(document).ready(function() {
//     /*
//      * Event listener for key inputs. Sends to selected bot.
//      */
//     var lastKeyPressed;
//     window.onkeydown = function (e) {
//         let keyboardEnable = document.getElementById('keyboard-controls').checked;
//         if (!keyboardEnable) return;
//
//         let pow = getPower();
//         let code = e.keyCode ? e.keyCode : e.which;
//
//         if (code === lastKeyPressed) return;
//
//         if (code === 87) {
//             // w=forward
//             sendMotors(pow, pow, pow, pow);
//
//         } else if (code === 83) {
//             // s=backward
//             sendMotors(-pow, -pow, -pow, -pow);
//
//         } else if (code == 65) {
//             // a=ccw
//             sendMotors(-pow, pow, -pow, pow);
//
//         } else if (code == 68) {
//             // d=cw
//             sendMotors(pow, -pow, pow, -pow);
//
//         } else if (code == 81) {
//             // q=left
//             sendMotors(-pow, pow, pow, -pow);
//
//         } else if (code == 69) {
//             // e=right
//             sendMotors(pow, -pow, -pow, pow);
//         } else {
//             return;
//         }
//         lastKeyPressed = code;
//     };
//
//     window.onkeyup = function (e) {
//         let keyboardEnable = document.getElementById('keyboard-controls').checked;
//         if (!keyboardEnable) return;
//
//         let code = e.keyCode ? e.keyCode : e.which;
//
//         if (code === lastKeyPressed) {
//             // Stop
//             sendMotors(0,0,0,0);
//             lastKeyPressed = -1;
//         }
//     };
// });
//
// /*
// *   Send KV -- allows users to manually send key and value to bot (for debugging/testing
//     purposes)
// */
// function sendKV(){
//     $.ajax({
//         method:'POST',
//         url:'/sendKV',
//         dataType: 'json',
//         data: JSON.stringify({
//             key:$("#kv_key").val(),
//             value:$("#kv_value").val(),
//             name:getBotID()
//         }),
//         contentType: 'application/json'
//     });
// }
<commit_msg>delete settime and use last semester's method<commit_after>var React = require('react');
var axios = require('axios');
var lastKeyPressed;
export default class ControlPanel extends React.Component {
    //TODO (#31): add listeners for Keyboard controls
    constructor(props) {
        super(props);
        this.state = {
            power: 50,
            discoveredBots: [],
            keyboard: false,
            xbox: false,
            trackedBots: [],
        };

        this.handleInputChange = this.handleInputChange.bind(this);
        this.updateDiscoveredBots = this.updateDiscoveredBots.bind(this);
        this.sendKV = this.sendKV.bind(this);
        this.startLogging = this.startLogging.bind(this);
        this.sendMotors = this.sendMotors.bind(this);
        this.removeBot = this.removeBot.bind(this);
        this.xboxToggle = this.xboxToggle.bind(this);
        this.getTrackedBots = this.getTrackedBots.bind(this);
        this.selectBot = this.selectBot.bind(this);
        this.onKeyDown = this.onKeyDown.bind(this);
        window.addEventListener('keydown', this.onKeyDown);

    }

     /* sends a command to bot according to the button pressed */
    onKeyDown(event){
        if (this.state.keyboard){
            const pow = this.state.power;
            if (event.keyCode == lastKeyPressed) {
                // Stop
                this.sendMotors(0,0,0,0);
                lastKeyPressed = -1;
            }
            else{
                if(event.keyCode==87) {
                    // If the 'W' key is pressed,move forward
                    this.sendMotors(pow, pow, pow, pow);
                }
                else if(event.keyCode==83){
                    //If the 'S' ket is pressed,move backward
                    this.sendMotors(-pow, -pow, -pow, -pow);
                }
                else if (event.keyCode==65) {
                    // If the 'A' key is pressed,ccw
                    this.sendMotors(-pow, pow, -pow, pow);
                }
                else if (event.keyCode==68){
                    // If the 'D' key is pressed,cw
                    this.sendMotors(pow, -pow, pow, -pow);
                }
                else if (event.keyCode==81){
                    // If the 'Q' key is pressed,left
                    this.sendMotors(-pow, pow, pow, -pow);
                }
                else if (event.keyCode==69){
                    // If the 'E' key is pressed,right
                    this.sendMotors(pow, -pow, -pow, pow);
                }
                else{
                    return;
                }
                lastKeyPressed = event.keyCode;
            }
        }
    }

    /* handler for input changes to modify the state */
    handleInputChange(event) {
        const target = event.target;
        const value = target.value;
        const name = target.name;
        if (name=="xbox"){
            this.setState({
                [name]: target.checked
            });
            this.xboxToggle(target.checked);
        } else if (name=="keyboard"){
            this.setState({
                [name]: target.checked
            });
            console.log(this.state.keyboard)
        } else {
            this.setState({
                [name]: value
            });
        }
    }

    /**
     * Updates tracked bots before page load.
     */
    componentWillMount() {
        this.getTrackedBots()
    }

    /* sends a key-value command to bot */
    sendKV(event){
        const pow = this.state.power;
        const target = event.target;
        if(target.id=="fwd") {
            this.sendMotors(pow, pow, pow, pow);
        }
        else if(target.id=="bck") {
            this.sendMotors(-pow, -pow, -pow, -pow);
        }
        else if(target.id=="lft") {
            this.sendMotors(-pow, pow, -pow, pow);
        }
        else if(target.id=="rt") {
            this.sendMotors(pow, -pow, pow, -pow);
        }
        else if(target.id=="cw"){
            this.sendMotors(pow, -pow, pow, -pow);
        }
        else if(target.id=="ccw"){
            this.sendMotors(-pow, pow, -pow, pow);
        }
        else if(target.id=="stop"){
            this.sendMotors(0,0,0,0);
        }
        else if(target.id=="log") {
            this.startLogging();
        }
        else {
            axios({
                method:'POST',
                url:'/sendKV',
                data: JSON.stringify({
                    key: document.getElementById('kv_key').value,
                    value: document.getElementById('kv_value').value,
                    name: this.props.currentBot
                }),
            })
            .then(function(response) {
                console.log('sent kv');
            })
            .catch(function (error) {
                console.warn(error);
            });
        }
    }

    /* sends a motor command to bot
    * input: front left, front right, back left, back right (all ints)
    * */
    sendMotors(fl,fr,bl,br){
        const _this = this;
        axios({
            method:'POST',
            url:'/commandBot',
            data: JSON.stringify({
                name: this.props.currentBot,
                fl: fl,
                fr: fr,
                bl: bl,
                br: br
            }),
        })
        .then(function(response) {
            console.log('Sent motor command: ' + response)
        })
        .catch(function (error) {
            console.warn(error);
        });
    }

    /**
     * Gets bots currently tracked
     */
    getTrackedBots() {
        const _this = this;
        axios({
            method:'POST',
            url:'/getTrackedBots',
            })
                .then(function(response) {
                    _this.setState({trackedBots: response.data});
            })
                .catch(function (error) {
                    console.log(error);
        });
    }

    /**
     * Handles onChange for bot dropdown. Changes currently selected bot.
     */
    selectBot(event) {
        this.props.setCurrentBot(event.target.value);
    }

    /* starts data logging */
    startLogging(){
        console.log("logging data listener");
        axios({
            method:'POST',
            url:'/logdata',
            data: JSON.stringify({name: this.props.currentBot}),
            processData: false,
        })
        .then(function(response) {
            console.log('started logging data');
        })
        .catch(function (error) {
            console.warn(error);
        });
    }

    /* removes selected bot from list */
    removeBot(){
        console.log("remove bot listener");
        axios({
            method:'POST',
            url:'/removeBot',
            data: JSON.stringify({name: this.props.currentBot}),
        })
        .then(function(response) {
            console.log('removed bot successfully');
        })
        .catch(function (error) {
            console.warn(error);
        });
    }

    /* toggles xbox controls on or off */
    xboxToggle(checked){
        console.log('xboxToggle '+checked);
        if (checked){
            axios({
                method:'POST',
                url:'/runXbox',
                data: JSON.stringify({name: this.props.currentBot}),
            })
            .then(function(response) {
                console.log('successfully toggled Xbox ON');
            })
            .catch(function (error) {
                console.warn(error);
            });
        } else {
            axios({
                method:'POST',
                url:'/stopXbox',
                data: JSON.stringify({name: this.props.currentBot}),
            })
            .then(function(response) {
                console.log('successfully toggled Xbox OFF');
            })
            .catch(function (error) {
                console.warn(error);
            });
        }
    }

    updateDiscoveredBots(){
        //TODO (#32) - change below request to axios
        //        $.ajax({
        //            method: "POST",
        //            url: '/discoverBots',
        //            dataType: 'json',
        //            data: '',
        //            contentType: 'application/json',
        //            success: function (data) {
        //                 //Check if discovered_bots and data are the same (check length and then contents)
        //                if(data.length != discovered_bots.length){
        //                    //If not then clear list and re-make displayed elements
        //                    redoDiscoverList(data);
        //                }
        //                else{
        //                    //Check value to ensure both structures contain the same data
        //                    for(let x=0;x<data.length;x++){
        //                        if(data[x]!=discovered_bots[x]){
        //                            redoDiscoverList(data);
        //                            //Prevent the list from being remade constantly
        //                            break;
        //                        }
        //                    }
        //                }
        //                setTimeout(updateDiscoveredBots,3000); // Try again in 3 sec
        //            }
        //        });
    }

    redoDiscoverList(data){
        let new_bots = [];

        for (let i = 0; i < data.length; i++) {
            //Trim the forward-slash
            var ip_address = data[i].substring(1);
            new_bots.push(ip_address)
        }
        this.setState({discoveredBots: new_bots})
    }

    render(){
        return (

                Control Panel

Movement controls:

                                 Choose bot:
                                <select value={this.props.currentBot} onChange={this.selectBot}> id="botlist" name="bots">
                                    <option value="(DEBUG) Sim Bot">(DEBUG) Sim Bot</option>
                                    {
                                        this.state.trackedBots.map(function(botname, idx){
                                            return <option
                                                        key={idx}
                                                        value={botname}>
                                                   {botname}
                                                   </option>
                                        })
                                    }
                                </select>

                        <button className="btn btn-danger" id="removeBot" onClick={this.removeBot}>Remove Bot</button>

                        Power ({this.state.power}):
                        <input id="power" type="range" name="power" min="0" max="100" value={this.state.power} defaultValue="50" onChange={this.handleInputChange}/>

                        <button className="btn" id="ccw" onClick={this.sendKV}>turn CCW</button>
                        <button className="btn" id="fwd" onClick={this.sendKV}>forward</button>
                        <button className="btn" id="cw" onClick={this.sendKV}>turn CW</button>

                        <button className="btn" id="lft" onClick={this.sendKV}>left</button>
                        <button className="btn btn-danger" id="stop" onClick={this.sendKV}>STOP</button>
                        <button className="btn" id="rt" onClick={this.sendKV}>right</button>

                        <button className="btn btn-success" id="log" onClick={this.sendKV}>log data</button>
                        <button className="btn" id="bck" onClick={this.sendKV}>backward</button>

                            Keyboard Controls

                                <input name="keyboard" type="checkbox" id="keyboard-controls" onChange={this.handleInputChange} />

                            Xbox Controls

                                <input name="xbox" type="checkbox" id="xbox-controls" onChange={this.handleInputChange}/>

                        <input type="text" id="kv_key" placeholder="Key (e.g. WHEELS)"/>
                        <input type="text" id="kv_value" placeholder="Value (e.g. 10,10)"/>
                        <button id="sendkv" onClick={this.sendKV} className="btn btn-success">Send KV</button>

        )
    }
}

// $(document).ready(function() {
//     /*
//      * Event listener for key inputs. Sends to selected bot.
//      */
//     var lastKeyPressed;
//     window.onkeydown = function (e) {
//         let keyboardEnable = document.getElementById('keyboard-controls').checked;
//         if (!keyboardEnable) return;
//
//         let pow = getPower();
//         let code = e.keyCode ? e.keyCode : e.which;
//
//         if (code === lastKeyPressed) return;
//
//         if (code === 87) {
//             // w=forward
//             sendMotors(pow, pow, pow, pow);
//
//         } else if (code === 83) {
//             // s=backward
//             sendMotors(-pow, -pow, -pow, -pow);
//
//         } else if (code == 65) {
//             // a=ccw
//             sendMotors(-pow, pow, -pow, pow);
//
//         } else if (code == 68) {
//             // d=cw
//             sendMotors(pow, -pow, pow, -pow);
//
//         } else if (code == 81) {
//             // q=left
//             sendMotors(-pow, pow, pow, -pow);
//
//         } else if (code == 69) {
//             // e=right
//             sendMotors(pow, -pow, -pow, pow);
//         } else {
//             return;
//         }
//         lastKeyPressed = code;
//     };
//
//     window.onkeyup = function (e) {
//         let keyboardEnable = document.getElementById('keyboard-controls').checked;
//         if (!keyboardEnable) return;
//
//         let code = e.keyCode ? e.keyCode : e.which;
//
//         if (code === lastKeyPressed) {
//             // Stop
//             sendMotors(0,0,0,0);
//             lastKeyPressed = -1;
//         }
//     };
// });
//
// /*
// *   Send KV -- allows users to manually send key and value to bot (for debugging/testing
//     purposes)
// */
// function sendKV(){
//     $.ajax({
//         method:'POST',
//         url:'/sendKV',
//         dataType: 'json',
//         data: JSON.stringify({
//             key:$("#kv_key").val(),
//             value:$("#kv_value").val(),
//             name:getBotID()
//         }),
//         contentType: 'application/json'
//     });
// }
<|endoftext|>


<commit_before>'use strict';

module.exports = {
  client: {
    lib: {
      css: [
        'public/lib/bootstrap/dist/css/bootstrap.css',
        'public/lib/bootstrap/dist/css/bootstrap-theme.css',
        'public/lib/materialize/bin/materialize.css',
        'public/lib/angular-material/angular-material.css',
        /*'public/lib/material-design-lite/material.css',*/
      ],
      js: [
        'public/lib/angular/angular.js',
        'public/lib/angular-resource/angular-resource.js',
        'public/lib/angular-animate/angular-animate.js',
        'public/lib/angular-aria/angular-aria.js',
        'public/lib/angular-ui-router/release/angular-ui-router.js',
        'public/lib/angular-material/angular-material.js',
        /*'public/lib/material-design-lite/material.js',*/
        'public/lib/angular-ui-utils/ui-utils.js',
        'public/lib/angular-bootstrap/ui-bootstrap-tpls.js',
        'public/lib/angular-file-upload/angular-file-upload.js',
        /*'public/lib/materialize/bin/materialize.js'*/
      ],
      tests: ['public/lib/angular-mocks/angular-mocks.js']
    },
    css: [
      'modules/*/client/css/*.css'
    ],
    less: [
      'modules/*/client/less/*.less'
    ],
    sass: [
      'modules/*/client/scss/*.scss'
    ],
    js: [
      'modules/core/client/app/config.js',
      'modules/core/client/app/init.js',
      'modules/*/client/*.js',
      'modules/*/client/**/*.js'
    ],
    views: ['modules/*/client/views/**/*.html']
  },
  server: {
    gruntConfig: 'gruntfile.js',
    gulpConfig: 'gulpfile.js',
    allJS: ['server.js', 'config/**/*.js', 'modules/*/server/**/*.js'],
    models: 'modules/*/server/models/**/*.js',
    routes: ['modules/!(core)/server/routes/**/*.js', 'modules/core/server/routes/**/*.js'],
    sockets: 'modules/*/server/sockets/**/*.js',
    config: 'modules/*/server/config/*.js',
    policies: 'modules/*/server/policies/*.js',
    views: 'modules/*/server/views/*.html'
  }
};
<commit_msg>quitando materializecss por conflictos<commit_after>'use strict';

module.exports = {
  client: {
    lib: {
      css: [
        'public/lib/bootstrap/dist/css/bootstrap.css',
        'public/lib/bootstrap/dist/css/bootstrap-theme.css',
        /*'public/lib/materialize/bin/materialize.css',*/
        'public/lib/angular-material/angular-material.css',
        /*'public/lib/material-design-lite/material.css',*/
      ],
      js: [
        'public/lib/angular/angular.js',
        'public/lib/angular-resource/angular-resource.js',
        'public/lib/angular-animate/angular-animate.js',
        'public/lib/angular-aria/angular-aria.js',
        'public/lib/angular-ui-router/release/angular-ui-router.js',
        'public/lib/angular-material/angular-material.js',
        /*'public/lib/material-design-lite/material.js',*/
        'public/lib/angular-ui-utils/ui-utils.js',
        'public/lib/angular-bootstrap/ui-bootstrap-tpls.js',
        'public/lib/angular-file-upload/angular-file-upload.js',
        /*'public/lib/materialize/bin/materialize.js'*/
      ],
      tests: ['public/lib/angular-mocks/angular-mocks.js']
    },
    css: [
      'modules/*/client/css/*.css'
    ],
    less: [
      'modules/*/client/less/*.less'
    ],
    sass: [
      'modules/*/client/scss/*.scss'
    ],
    js: [
      'modules/core/client/app/config.js',
      'modules/core/client/app/init.js',
      'modules/*/client/*.js',
      'modules/*/client/**/*.js'
    ],
    views: ['modules/*/client/views/**/*.html']
  },
  server: {
    gruntConfig: 'gruntfile.js',
    gulpConfig: 'gulpfile.js',
    allJS: ['server.js', 'config/**/*.js', 'modules/*/server/**/*.js'],
    models: 'modules/*/server/models/**/*.js',
    routes: ['modules/!(core)/server/routes/**/*.js', 'modules/core/server/routes/**/*.js'],
    sockets: 'modules/*/server/sockets/**/*.js',
    config: 'modules/*/server/config/*.js',
    policies: 'modules/*/server/policies/*.js',
    views: 'modules/*/server/views/*.html'
  }
};
<|endoftext|>


<commit_before>/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the clear BSD license.
 * See http://svn.openlayers.org/trunk/openlayers/license.txt
 * for the full text of the license. */

/**
 * @requires OpenLayers/Handler.js
 */

/**
 * Class: OpenLayers.Handler.Click
 * A handler for mouse clicks.  The intention of this handler is to give
 *     controls more flexibility with handling clicks.  Browsers trigger
 *     click events twice for a double-click.  In addition, the mousedown,
 *     mousemove, mouseup sequence fires a click event.  With this handler,
 *     controls can decide whether to ignore clicks associated with a double
 *     click.  By setting a <pixelTolerance>, controls can also ignore clicks
 *     that include a drag.  Create a new instance with the
 *     <OpenLayers.Handler.Click> constructor.
 *
 * Inherits from:
 *  - <OpenLayers.Handler>
 */
OpenLayers.Handler.Click = OpenLayers.Class(OpenLayers.Handler, {

    /**
     * APIProperty: delay
     * {Number} Number of milliseconds between clicks before the event is
     *     considered a double-click.
     */
    delay: 300,

    /**
     * APIProperty: single
     * {Boolean} Handle single clicks.  Default is true.  If false, clicks
     * will not be reported.  If true, single-clicks will be reported.
     */
    single: true,

    /**
     * APIProperty: double
     * {Boolean} Handle double-clicks.  Default is false.
     */
    'double': false,

    /**
     * APIProperty: pixelTolerance
     * {Number} Maximum number of pixels between mouseup and mousedown for an
     *     event to be considered a click.  Default is null.  If set to an
     *     integer value, clicks with a drag greater than the value will be
     *     ignored.  This property can only be set when the handler is
     *     constructed.
     */
    pixelTolerance: null,

    /**
     * APIProperty: stopSingle
     * {Boolean} Stop other listeners from being notified of clicks.  Default
     *     is false.  If true, any click listeners registered before this one
     *     will not be notified of *any* click event (associated with double
     *     or single clicks).
     */
    stopSingle: false,

    /**
     * APIProperty: stopDouble
     * {Boolean} Stop other listeners from being notified of double-clicks.
     *     Default is false.  If true, any click listeners registered before
     *     this one will not be notified of *any* double-click events.
     *
     * The one caveat with stopDouble is that given a map with two click
     *     handlers, one with stopDouble true and the other with stopSingle
     *     true, the stopSingle handler should be activated last to get
     *     uniform cross-browser performance.  Since IE triggers one click
     *     with a dblclick and FF triggers two, if a stopSingle handler is
     *     activated first, all it gets in IE is a single click when the
     *     second handler stops propagation on the dblclick.
     */
    stopDouble: false,

    /**
     * Property: timerId
     * {Number} The id of the timeout waiting to clear the <delayedEvent>.
     */
    timerId: null,

    /**
     * Property: down
     * {<OpenLayers.Pixel>} The pixel location of the last mousedown.
     */
    down: null,

    /**
     * Property: cachedEvent
     * {Event} Since IE doesn't let us call window.setTimeout with extra
     *     arguments, we cache the last click event here.
     */
    cachedEvent: null,

    /**
     * Constructor: OpenLayers.Handler.Click
     * Create a new click handler.
     *
     * Parameters:
     * control - {<OpenLayers.Control>} The control that is making use of
     *     this handler.  If a handler is being used without a control, the
     *     handler's setMap method must be overridden to deal properly with
     *     the map.
     * callbacks - {Object} An object with keys corresponding to callbacks
     *     that will be called by the handler. The callbacks should
     *     expect to recieve a single argument, the click event.
     *     Callbacks for 'click' and 'dblclick' are supported.
     * options - {Object} Optional object whose properties will be set on the
     *     handler.
     */
    initialize: function(control, callbacks, options) {
        OpenLayers.Handler.prototype.initialize.apply(this, arguments);
        // optionally register for mouseup and mousedown
        if(this.pixelTolerance != null) {
            this.mousedown = function(evt) {
                this.down = evt.xy;
                return true;
            };
        }
    },

    /**
     * Method: mousedown
     * Handle mousedown.  Only registered as a listener if pixelTolerance is
     *     a non-zero value at construction.
     *
     * Returns:
     * {Boolean} Continue propagating this event.
     */
    mousedown: null,

    /**
     * Method: dblclick
     * Handle dblclick.  For a dblclick, we get two clicks in some browsers
     *     (FF) and one in others (IE).  So we need to always register for
     *     dblclick to properly handle single clicks.
     *
     * Returns:
     * {Boolean} Continue propagating this event.
     */
    dblclick: function(evt) {
        if(this.passesTolerance(evt)) {
            if(this["double"]) {
                this.callback('dblclick', [evt]);
            }
            this.clearTimer();
        }
        return !this.stopDouble;
    },

    /**
     * Method: click
     * Handle click.
     *
     * Returns:
     * {Boolean} Continue propagating this event.
     */
    click: function(evt) {
        if(this.passesTolerance(evt)) {
            if(this.timerId != null) {
                // already received a click
                this.clearTimer();
            } else {
                // set the timer, send evt only if single is true
                var clickEvent = this.single ? evt : null;
                this.timerId = window.setTimeout(
                    OpenLayers.Function.bind(this.delayedCall, this, clickEvent),
                    this.delay
                );
            }
        }
        return !this.stopSingle;
    },

    /**
     * Method: passesTolerance
     * Determine whether the event is within the optional pixel tolerance.
     *
     * Returns:
     * {Boolean} The click is within the pixel tolerance (if specified).
     */
    passesTolerance: function(evt) {
        var passes = true;
        if(this.pixelTolerance) {
            var dpx = Math.sqrt(
                Math.pow(this.down.x - evt.xy.x, 2) +
                Math.pow(this.down.y - evt.xy.y, 2)
            );
            if(dpx > this.pixelTolerance) {
                passes = false;
            }
        }
        return passes;
    },

    /**
     * Method: clearTimer
     * Clear the timer and set <timerId> to null.
     */
    clearTimer: function() {
        if(this.timerId != null) {
            window.clearTimeout(this.timerId);
            this.timerId = null;
        }
    },

    /**
     * Method: delayedCall
     * Sets <timerId> to null.  And optionally triggers the click callback if
     *     <cachedEvent> is set.
     */
    delayedCall: function(evt) {
        this.timerId = null;
        if(evt) {
            this.callback('click', [evt]);
        }
    },

    /**
     * APIMethod: deactivate
     * Deactivate the handler.
     *
     * Returns:
     * {Boolean} The handler was successfully deactivated.
     */
    deactivate: function() {
        var deactivated = false;
        if(OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) {
            this.clearTimer();
            this.down = null;
            deactivated = true;
        }
        return deactivated;
    },

    CLASS_NAME: "OpenLayers.Handler.Click"
});
<commit_msg>click handler's cachedEvent property isn't needed. r=tschaub. (closes #1252)<commit_after>/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the clear BSD license.
 * See http://svn.openlayers.org/trunk/openlayers/license.txt
 * for the full text of the license. */

/**
 * @requires OpenLayers/Handler.js
 */

/**
 * Class: OpenLayers.Handler.Click
 * A handler for mouse clicks.  The intention of this handler is to give
 *     controls more flexibility with handling clicks.  Browsers trigger
 *     click events twice for a double-click.  In addition, the mousedown,
 *     mousemove, mouseup sequence fires a click event.  With this handler,
 *     controls can decide whether to ignore clicks associated with a double
 *     click.  By setting a <pixelTolerance>, controls can also ignore clicks
 *     that include a drag.  Create a new instance with the
 *     <OpenLayers.Handler.Click> constructor.
 *
 * Inherits from:
 *  - <OpenLayers.Handler>
 */
OpenLayers.Handler.Click = OpenLayers.Class(OpenLayers.Handler, {

    /**
     * APIProperty: delay
     * {Number} Number of milliseconds between clicks before the event is
     *     considered a double-click.
     */
    delay: 300,

    /**
     * APIProperty: single
     * {Boolean} Handle single clicks.  Default is true.  If false, clicks
     * will not be reported.  If true, single-clicks will be reported.
     */
    single: true,

    /**
     * APIProperty: double
     * {Boolean} Handle double-clicks.  Default is false.
     */
    'double': false,

    /**
     * APIProperty: pixelTolerance
     * {Number} Maximum number of pixels between mouseup and mousedown for an
     *     event to be considered a click.  Default is null.  If set to an
     *     integer value, clicks with a drag greater than the value will be
     *     ignored.  This property can only be set when the handler is
     *     constructed.
     */
    pixelTolerance: null,

    /**
     * APIProperty: stopSingle
     * {Boolean} Stop other listeners from being notified of clicks.  Default
     *     is false.  If true, any click listeners registered before this one
     *     will not be notified of *any* click event (associated with double
     *     or single clicks).
     */
    stopSingle: false,

    /**
     * APIProperty: stopDouble
     * {Boolean} Stop other listeners from being notified of double-clicks.
     *     Default is false.  If true, any click listeners registered before
     *     this one will not be notified of *any* double-click events.
     *
     * The one caveat with stopDouble is that given a map with two click
     *     handlers, one with stopDouble true and the other with stopSingle
     *     true, the stopSingle handler should be activated last to get
     *     uniform cross-browser performance.  Since IE triggers one click
     *     with a dblclick and FF triggers two, if a stopSingle handler is
     *     activated first, all it gets in IE is a single click when the
     *     second handler stops propagation on the dblclick.
     */
    stopDouble: false,

    /**
     * Property: timerId
     * {Number} The id of the timeout waiting to clear the <delayedEvent>.
     */
    timerId: null,

    /**
     * Property: down
     * {<OpenLayers.Pixel>} The pixel location of the last mousedown.
     */
    down: null,

    /**
     * Constructor: OpenLayers.Handler.Click
     * Create a new click handler.
     *
     * Parameters:
     * control - {<OpenLayers.Control>} The control that is making use of
     *     this handler.  If a handler is being used without a control, the
     *     handler's setMap method must be overridden to deal properly with
     *     the map.
     * callbacks - {Object} An object with keys corresponding to callbacks
     *     that will be called by the handler. The callbacks should
     *     expect to recieve a single argument, the click event.
     *     Callbacks for 'click' and 'dblclick' are supported.
     * options - {Object} Optional object whose properties will be set on the
     *     handler.
     */
    initialize: function(control, callbacks, options) {
        OpenLayers.Handler.prototype.initialize.apply(this, arguments);
        // optionally register for mouseup and mousedown
        if(this.pixelTolerance != null) {
            this.mousedown = function(evt) {
                this.down = evt.xy;
                return true;
            };
        }
    },

    /**
     * Method: mousedown
     * Handle mousedown.  Only registered as a listener if pixelTolerance is
     *     a non-zero value at construction.
     *
     * Returns:
     * {Boolean} Continue propagating this event.
     */
    mousedown: null,

    /**
     * Method: dblclick
     * Handle dblclick.  For a dblclick, we get two clicks in some browsers
     *     (FF) and one in others (IE).  So we need to always register for
     *     dblclick to properly handle single clicks.
     *
     * Returns:
     * {Boolean} Continue propagating this event.
     */
    dblclick: function(evt) {
        if(this.passesTolerance(evt)) {
            if(this["double"]) {
                this.callback('dblclick', [evt]);
            }
            this.clearTimer();
        }
        return !this.stopDouble;
    },

    /**
     * Method: click
     * Handle click.
     *
     * Returns:
     * {Boolean} Continue propagating this event.
     */
    click: function(evt) {
        if(this.passesTolerance(evt)) {
            if(this.timerId != null) {
                // already received a click
                this.clearTimer();
            } else {
                // set the timer, send evt only if single is true
                var clickEvent = this.single ? evt : null;
                this.timerId = window.setTimeout(
                    OpenLayers.Function.bind(this.delayedCall, this, clickEvent),
                    this.delay
                );
            }
        }
        return !this.stopSingle;
    },

    /**
     * Method: passesTolerance
     * Determine whether the event is within the optional pixel tolerance.
     *
     * Returns:
     * {Boolean} The click is within the pixel tolerance (if specified).
     */
    passesTolerance: function(evt) {
        var passes = true;
        if(this.pixelTolerance) {
            var dpx = Math.sqrt(
                Math.pow(this.down.x - evt.xy.x, 2) +
                Math.pow(this.down.y - evt.xy.y, 2)
            );
            if(dpx > this.pixelTolerance) {
                passes = false;
            }
        }
        return passes;
    },

    /**
     * Method: clearTimer
     * Clear the timer and set <timerId> to null.
     */
    clearTimer: function() {
        if(this.timerId != null) {
            window.clearTimeout(this.timerId);
            this.timerId = null;
        }
    },

    /**
     * Method: delayedCall
     * Sets <timerId> to null.  And optionally triggers the click callback if
     *     evt is set.
     */
    delayedCall: function(evt) {
        this.timerId = null;
        if(evt) {
            this.callback('click', [evt]);
        }
    },

    /**
     * APIMethod: deactivate
     * Deactivate the handler.
     *
     * Returns:
     * {Boolean} The handler was successfully deactivated.
     */
    deactivate: function() {
        var deactivated = false;
        if(OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) {
            this.clearTimer();
            this.down = null;
            deactivated = true;
        }
        return deactivated;
    },

    CLASS_NAME: "OpenLayers.Handler.Click"
});
<|endoftext|>