<commit_before>(function(){

    xtag.register('widget-DAQ', {
        extends: 'div',
        lifecycle: {
            created: function() {
                var xString;

                this.width = this.offsetHeight;
                this.height = 500;

                //get the DAQ structure
                XHR('http://' + this.MIDAS + '/?cmd=jcopy&odb=/DAQ&encoding=json-nokeys',
                    function(res){
                        this.buildDAQ(res);
                    }.bind(this),
                    'application/json');

                xString = '<x-deck id="' + this.id + 'Deck" selected-index=0>';
                xString += '<x-card id="DAQmasterCard"></x-card></x-deck>';
                xtag.innerHTML(this, xString);

                this.masterBlock = document.createElement('div');
                this.masterBlock.setAttribute('class', 'masterDAQ');
                document.getElementById('DAQmasterCard').appendChild(this.masterBlock);

                this.collectorBlock = document.createElement('div');
                this.collectorBlock.setAttribute('id', 'collectorBlock');
                this.collectorBlock.setAttribute('class', 'collectorDAQ');
                document.getElementById('DAQmasterCard').appendChild(this.collectorBlock);

                ////////////////////////////
                //Kinetic.js setup
                ////////////////////////////

                //indices for these arrays correspond to the x-card index on display
                this.stage = [];
                this.mainLayer = [];
                this.scaleLayer = [];
                this.tooltipLayer = [];
                this.TTbkg = [];
                this.text = [];
                this.setupKinetic('collectorBlock');

            },
            inserted: function() {},
            removed: function() {},
            attributeChanged: function() {}
        },
        events: {

        },
        accessors: {
            'MIDAS':{
                attribute: {} //this just needs to be declared
            }
        },
        methods: {
            'buildDAQ' : function(response){
                var data = JSON.parse(response),
                    i,
                    collectorGutter = 10;

                this.collectors = [];
                this.digitizers = [];
                this.collectorCells = [];

                //determine what collectors are present and instantiate collector cells
                for(i=0; i<16; i++){
                    this.collectors[i] = data.hosts['collector0x' + i.toString(16)];
/*
                    if(this.collectors[i]){
                        this.collectorCells[i] = new Kinetic.Rect({
                            x:collectorGutter/2 + i*this.width/16,
                            y:300,
                            width: (this.width - collectorGutter*16) / 16,
                            height:100,
                            fill:'#555555',
                            stroke: '#000000',
                        });
                        this.mainLayer[0].add(this.collectors[i]);
                    }
*/
                }
//                this.mainLayer[0].draw();

                console.log(this.collectors)
            },

            'setupKinetic' : function(targetID){
                var i = this.stage.length;
                //point kinetic at the div and set up the staging and layers:
                this.stage[i] = new Kinetic.Stage({
                    container: targetID,
                    width: this.width,
                    height: this.height
                });
                this.mainLayer[i] = new Kinetic.Layer();       //main rendering layer
                this.scaleLayer[i] = new Kinetic.Layer();      //layer for scales / legends
                this.tooltipLayer[i] = new Kinetic.Layer();    //layer for tooltip info

                //tooltip background:
                this.TTbkg[i] = new Kinetic.Rect({
                    x:-1000,
                    y:-1000,
                    width:100,
                    height:100,
                    fill:'rgba(0,0,0,0.8)',
                    stroke: 'rgba(0,0,0,0)',
                    listening: false
                });
                this.tooltipLayer[i].add(this.TTbkg[i]);

                //tooltip text:
                this.text[i] = new Kinetic.Text({
                    x: -1000,
                    y: -1000,
                    fontFamily: 'Arial',
                    fontSize: 16,
                    text: '',
                    lineHeight: 1.2,
                    fill: '#EEEEEE',
                    listening: false
                });
                this.tooltipLayer[i].add(this.text[i]);
            }
        }
    });

})();<commit_msg>sketching DAQ top view<commit_after>(function(){

    xtag.register('widget-DAQ', {
        extends: 'div',
        lifecycle: {
            created: function() {
                var xString;

                this.width = this.offsetHeight;
                this.height = 500;

                //get the DAQ structure
                XHR('http://' + this.MIDAS + '/?cmd=jcopy&odb=/DAQ&encoding=json-nokeys',
                    function(res){
                        this.buildDAQ(res);
                    }.bind(this),
                    'application/json');

                xString = '<x-deck id="' + this.id + 'Deck" selected-index=0>';
                xString += '<x-card id="DAQmasterCard"></x-card></x-deck>';
                xtag.innerHTML(this, xString);

                this.masterBlock = document.createElement('div');
                this.masterBlock.setAttribute('class', 'masterDAQ');
                document.getElementById('DAQmasterCard').appendChild(this.masterBlock);

                this.collectorBlock = document.createElement('div');
                this.collectorBlock.setAttribute('id', 'collectorBlock');
                this.collectorBlock.setAttribute('class', 'collectorDAQ');
                document.getElementById('DAQmasterCard').appendChild(this.collectorBlock);

                ////////////////////////////
                //Kinetic.js setup
                ////////////////////////////

                //indices for these arrays correspond to the x-card index on display
                this.stage = [];
                this.mainLayer = [];
                this.scaleLayer = [];
                this.tooltipLayer = [];
                this.TTbkg = [];
                this.text = [];
                this.setupKinetic('collectorBlock');

            },
            inserted: function() {},
            removed: function() {},
            attributeChanged: function() {}
        },
        events: {

        },
        accessors: {
            'MIDAS':{
                attribute: {} //this just needs to be declared
            }
        },
        methods: {
            'buildDAQ' : function(response){
                var data = JSON.parse(response),
                    i,
                    collectorGutter = 10;

                this.collectors = [];
                this.digitizers = [];
                this.collectorCells = [];

                //determine what collectors are present and instantiate collector cells
                for(i=0; i<16; i++){
                    this.collectors[i] = data.hosts['collector0x' + i.toString(16)];

                    if(this.collectors[i]){
                        this.collectorCells[i] = new Kinetic.Rect({
                            x:collectorGutter/2 + i*this.width/16,
                            y:300,
                            width: (this.width - collectorGutter*16) / 16,
                            height:100,
                            fill:'#555555',
                            stroke: '#000000',
                        });
                        //this.mainLayer[0].add(this.collectors[i]);
                    }

                }
//                this.mainLayer[0].draw();

                console.log(this.collectors)
            },

            'setupKinetic' : function(targetID){
                var i = this.stage.length;
                //point kinetic at the div and set up the staging and layers:
                this.stage[i] = new Kinetic.Stage({
                    container: targetID,
                    width: this.width,
                    height: this.height
                });
                this.mainLayer[i] = new Kinetic.Layer();       //main rendering layer
                this.scaleLayer[i] = new Kinetic.Layer();      //layer for scales / legends
                this.tooltipLayer[i] = new Kinetic.Layer();    //layer for tooltip info

                //tooltip background:
                this.TTbkg[i] = new Kinetic.Rect({
                    x:-1000,
                    y:-1000,
                    width:100,
                    height:100,
                    fill:'rgba(0,0,0,0.8)',
                    stroke: 'rgba(0,0,0,0)',
                    listening: false
                });
                this.tooltipLayer[i].add(this.TTbkg[i]);

                //tooltip text:
                this.text[i] = new Kinetic.Text({
                    x: -1000,
                    y: -1000,
                    fontFamily: 'Arial',
                    fontSize: 16,
                    text: '',
                    lineHeight: 1.2,
                    fill: '#EEEEEE',
                    listening: false
                });
                this.tooltipLayer[i].add(this.text[i]);
            }
        }
    });

})();<|endoftext|>


<commit_before>/*    Copyright 2016 Firewalla LLC
 *
 *    This program is free software: you can redistribute it and/or  modify
 *    it under the terms of the GNU Affero General Public License, version 3,
 *    as published by the Free Software Foundation.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
'use strict';
var express = require('express');
var router = express.Router();
const passport = require('passport')

var Encryption = require('../lib/Encryption'); // encryption middleware
var encryption = new Encryption();

var CloudWrapper = require('../lib/CloudWrapper');
var cloudWrapper = new CloudWrapper();

let f = require('../../net2/Firewalla.js');

let log = require('../../net2/logger.js')(__filename, "info");

let sc = require('../lib/SystemCheck.js');

let async = require('asyncawait/async');
let await = require('asyncawait/await');

router.post('/message/:gid',

  sc.debugInfo,

  (req, res, next) => {

    let gid = req.params.gid;

    async(() => {
      let controller = await(cloudWrapper.getNetBotController(gid));
      let response = await(controller.msgHandlerAsync(gid, req.body));
      res.body = JSON.stringify(response);
      next();
    })()
      .catch((err) => {
        // netbot controller is not ready yet, waiting for init complete
        res.status(503);
        res.json({error: 'Initializing Firewalla Device, please try later'});
      });
  },

  sc.compressPayloadIfRequired,

  (req, res, next) => {
    res.send();
  }
);

module.exports = router;
<commit_msg>bug fix<commit_after>/*    Copyright 2016 Firewalla LLC
 *
 *    This program is free software: you can redistribute it and/or  modify
 *    it under the terms of the GNU Affero General Public License, version 3,
 *    as published by the Free Software Foundation.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
'use strict';
var express = require('express');
var router = express.Router();
const passport = require('passport')

var Encryption = require('../lib/Encryption'); // encryption middleware
var encryption = new Encryption();

var CloudWrapper = require('../lib/CloudWrapper');
var cloudWrapper = new CloudWrapper();

let f = require('../../net2/Firewalla.js');

let log = require('../../net2/logger.js')(__filename, "info");

let sc = require('../lib/SystemCheck.js');

let async = require('asyncawait/async');
let await = require('asyncawait/await');

router.post('/message/:gid',

  sc.debugInfo,

  (req, res, next) => {

    let gid = req.params.gid;

    async(() => {
      let controller = await(cloudWrapper.getNetBotController(gid));
      let response = await(controller.msgHandlerAsync(gid, req.body));
      res.body = JSON.stringify(response);
      next();
    })()
      .catch((err) => {
        // netbot controller is not ready yet, waiting for init complete
        res.status(503);
        res.json({error: 'Initializing Firewalla Device, please try later'});
      });
  },

  sc.compressPayloadIfRequired,

  (req, res, next) => {
    res.send(res.body);
  }
);

module.exports = router;
<|endoftext|>


<commit_before>#!/bin/env node
/*
   Copyright 2015 The Trustees of Princeton University

   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.
*/

var rest = require('./rest.js');
var utils = require('./utils.js');
var express = require('express');
var nodeCache = require('node-cache');
var ipfilter = require('express-ipfilter');
var app = express();
var fs = require('fs');
var rangeCheck = require('range_check');

function isJsonString(str) {
    try {
        JSON.parse(str);
    } catch (e) {
        return false;
    }
    return true;
}

function extendIPArray(arr) {
    var new_arr = [];
    for(var i=0;i<arr.length;i++) {
        if(typeof(arr[i]) === "string") {
            new_arr.push(arr[i]);
            if(rangeCheck.ver(arr[i]) === 4) {
                var v6ip = "::ffff:" + arr[i].trim();
                if(arr.indexOf(v6ip) < 0) {
                    new_arr.push(v6ip);
                }
            }
        } else if(arr[i] instanceof Array) {
            // ip range
            // recursively
            new_arr.push(arr[i]);
            if(arr[i].length == 2) {
                if(rangeCheck.ver(arr[i][0]) === 4 && rangeCheck.ver(arr[i][1]) === 4) {
                    var v6ip_begin = "::ffff:" + arr[i][0].trim();
                    var v6ip_end = "::ffff:" + arr[i][1].trim();
                    new_arr.push([v6ip_begin, v6ip_end]);
                }
            }
        }
    }
    return new_arr;
}

// read local whilelist
function getWhilelist() {
    var whitelist = fs.readFileSync('whitelist', 'utf8');
    var list = [];
    if(isJsonString(whitelist)) {
        var json_obj = JSON.parse(whitelist);
        list = json_obj;
    } else {
        list = whitelist.trim().split(/\r?\n/);
    }

    if(list.indexOf("localhost") >= 0 && list.indexOf("127.0.0.1") < 0) {
        list.push("127.0.0.1");
    }

    // handle default ipv6 conversion from ipv4
    return extendIPArray(list);
}

(function main() {
    console.log("Syndicate-UG-HTTP start");

    var args = process.argv.slice(1);
    var param = utils.parse_args(args);

    try {
        // read whitelist
        whitelist = getWhilelist();
        if(whitelist.indexOf("ALL") >= 0) {
            // do not filter
            console.log("accept requests from all hosts");
        } else {
            console.log("accept requests from : " + whitelist);

            // filter ip range
            app.use(ipfilter(whitelist, {mode: 'allow'}));
        }

        // start rest
        app.use(function(req, res, next) {
            console.log('%s %s', req.method, req.url);
            next();
        });

        var ug = rest.init(param);
        var rfdCache = new nodeCache({
            stdTTL: 600,
            checkperiod: 600,
            useClones: false
        });

        rfdCache.on("expired", function(key, value) {
            console.log("closing expired file handle for read - " + key);
            rest.safeclose(ug, value);
        });

        var wfdCache = new nodeCache({
            stdTTL: 3600,
            checkperiod: 600,
            useClones: false
        });

        wfdCache.on("expired", function(key, value) {
            console.log("closing expired file handle for read - " + key);
            rest.safeclose(ug, value);
        });

        app.use(function(req, res, next) {
            req.ug = ug;
            req.rfdCache = rfdCache;
            req.wfdCache = wfdCache;
            next();
        });

        app.use('/', rest.getRouter());

        app.listen(param.port, function() {
            console.log("listening at " + param.port);
        });

        // must not shutdown here!
        //rest.shutdown(ug);
    } catch (e) {
        console.log("Exception occured: " + e);
    }
})();
<commit_msg>Handle a case that whitelist file does not exist<commit_after>#!/bin/env node
/*
   Copyright 2015 The Trustees of Princeton University

   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.
*/

var rest = require('./rest.js');
var utils = require('./utils.js');
var express = require('express');
var nodeCache = require('node-cache');
var ipfilter = require('express-ipfilter');
var app = express();
var fs = require('fs');
var rangeCheck = require('range_check');

function isJsonString(str) {
    try {
        JSON.parse(str);
    } catch (e) {
        return false;
    }
    return true;
}

function extendIPArray(arr) {
    var new_arr = [];
    for(var i=0;i<arr.length;i++) {
        if(typeof(arr[i]) === "string") {
            new_arr.push(arr[i]);
            if(rangeCheck.ver(arr[i]) === 4) {
                var v6ip = "::ffff:" + arr[i].trim();
                if(arr.indexOf(v6ip) < 0) {
                    new_arr.push(v6ip);
                }
            }
        } else if(arr[i] instanceof Array) {
            // ip range
            new_arr.push(arr[i]);
            if(arr[i].length == 2) {
                if(rangeCheck.ver(arr[i][0]) === 4 && rangeCheck.ver(arr[i][1]) === 4) {
                    var v6ip_begin = "::ffff:" + arr[i][0].trim();
                    var v6ip_end = "::ffff:" + arr[i][1].trim();
                    new_arr.push([v6ip_begin, v6ip_end]);
                }
            }
        }
    }
    return new_arr;
}

// read local whilelist
function getWhilelist() {
    var whitelist = "";
    var list = [];

    try {
        whitelist = fs.readFileSync('whitelist', 'utf8');
    } catch (e) {
        // set to default
        whitelist = "ALL";
    }

    if(isJsonString(whitelist)) {
        var json_obj = JSON.parse(whitelist);
        list = json_obj;
    } else {
        list = whitelist.trim().split(/\r?\n/);
    }

    if(list.indexOf("localhost") >= 0 && list.indexOf("127.0.0.1") < 0) {
        list.push("127.0.0.1");
    }

    // handle default ipv6 conversion from ipv4
    return extendIPArray(list);
}

(function main() {
    console.log("Syndicate-UG-HTTP start");

    var args = process.argv.slice(1);
    var param = utils.parse_args(args);

    try {
        // read whitelist
        whitelist = getWhilelist();
        if(whitelist.indexOf("ALL") >= 0) {
            // do not filter
            console.log("accept requests from all hosts");
        } else {
            console.log("accept requests from : " + whitelist);

            // filter ip range
            app.use(ipfilter(whitelist, {mode: 'allow'}));
        }

        // start rest
        app.use(function(req, res, next) {
            console.log('%s %s', req.method, req.url);
            next();
        });

        var ug = rest.init(param);
        var rfdCache = new nodeCache({
            stdTTL: 600,
            checkperiod: 600,
            useClones: false
        });

        rfdCache.on("expired", function(key, value) {
            console.log("closing expired file handle for read - " + key);
            rest.safeclose(ug, value);
        });

        var wfdCache = new nodeCache({
            stdTTL: 3600,
            checkperiod: 600,
            useClones: false
        });

        wfdCache.on("expired", function(key, value) {
            console.log("closing expired file handle for read - " + key);
            rest.safeclose(ug, value);
        });

        app.use(function(req, res, next) {
            req.ug = ug;
            req.rfdCache = rfdCache;
            req.wfdCache = wfdCache;
            next();
        });

        app.use('/', rest.getRouter());

        app.listen(param.port, function() {
            console.log("listening at " + param.port);
        });

        // must not shutdown here!
        //rest.shutdown(ug);
    } catch (e) {
        console.log("Exception occured: " + e);
    }
})();
<|endoftext|>


<commit_before>module.exports = {
  forProjects: function (opts) {
    return Project.query(qb => {
      if (opts.user) {
        qb.leftJoin('projects_users', function () {
          this.on('projects.id', '=', 'projects_users.project_id')
        })
        qb.where(function () {
          this.where('projects.user_id', opts.user)
        })
        .orWhere('projects_users.user_id', opts.user)
      }

      if (opts.community) {
        qb.where(function () {
          var clause = this.whereIn('community_id', opts.community)
          if (opts.includePublic) {
            clause.orWhere('visibility', Project.Visibility.PUBLIC)
          }
        })
      }

      if (opts.published) {
        qb.whereRaw('published_at is not null')
      }

      if (opts.term) {
        Search.addTermToQueryBuilder(opts.term, qb, {
          columns: ['projects.title', 'projects.intention', 'projects.details']
        })
      }

      // this counts total rows matching the criteria, disregarding limit,
      // which is useful for pagination
      qb.select(bookshelf.knex.raw('projects.*, count(*) over () as total'))

      qb.limit(opts.limit)
      qb.offset(opts.offset)
      qb.groupBy('projects.id')
    })
  },

  forPosts: function (opts) {
    return Post.query(function (qb) {
      qb.limit(opts.limit)
      qb.offset(opts.offset)
      qb.where({'post.active': true})

      // this counts total rows matching the criteria, disregarding limit,
      // which is useful for pagination
      qb.select(bookshelf.knex.raw('post.*, count(*) over () as total'))

      if (opts.users) {
        qb.whereIn('post.user_id', opts.users)
      }

      if (opts.excludeUsers) {
        qb.whereNotIn('post.user_id', opts.excludeUsers)
      }

      if (opts.communities) {
        qb.join('post_community', 'post_community.post_id', '=', 'post.id')
        qb.whereIn('post_community.community_id', opts.communities)
        qb.groupBy(['post.id', 'post_community.post_id'])
      }

      if (opts.project) {
        qb.join('posts_projects', 'posts_projects.post_id', '=', 'post.id')
        qb.where('posts_projects.project_id', opts.project)
      } else {
        qb.where('post.visibility', '!=', Post.Visibility.DRAFT_PROJECT)
      }

      if (opts.term) {
        Search.addTermToQueryBuilder(opts.term, qb, {
          columns: ['post.name', 'post.description']
        })
      }

      if (opts.follower) {
        qb.join('follower', 'follower.post_id', '=', 'post.id')
        qb.where('follower.user_id', opts.follower)
        qb.whereRaw('(post.user_id != ? or post.user_id is null)', opts.follower)
      }

      if (!opts.type || opts.type === 'all') {
        qb.where('post.type', '!=', 'welcome')
      } else if (opts.type !== 'all+welcome') {
        qb.where({type: opts.type})
      }

      if (opts.type === 'event' && opts.filter === 'future') {
        qb.whereRaw('(post.start_time > now())')
      }

      if (opts.start_time && opts.end_time) {
        qb.whereRaw('((post.created_at between ? and ?) or (post.updated_at between ? and ?))',
          [opts.start_time, opts.end_time, opts.start_time, opts.end_time])
      }

      if (opts.visibility) {
        qb.whereIn('visibility', opts.visibility)
      }

      if (opts.sort === 'suggested') {
        qb.join('user_post_relevance', 'user_post_relevance.post_id', '=', 'post.id')
        qb.where('user_post_relevance.user_id', opts.forUser)
        qb.orderBy('similarity', 'desc')
        qb.groupBy('similarity')
      } else if (opts.sort === 'fulfilled_at') {
        qb.orderByRaw('post.fulfilled_at desc, post.updated_at desc')
      } else if (Array.isArray(opts.sort)) {
        qb.orderBy(opts.sort[0], opts.sort[1])
      } else if (opts.sort) {
        qb.orderBy(opts.sort, 'desc')
      }
    })
  },

  forUsers: function (opts) {
    return User.query(function (qb) {
      qb.limit(opts.limit || 1000)
      qb.offset(opts.offset || 0)
      qb.where('users.active', '=', true)

      // this is not necessarily what any consumer desires, but
      // some ordering must be specified for pagination
      qb.orderBy('name', 'asc')

      // this counts total rows matching the criteria, disregarding limit,
      // which is useful for pagination
      qb.select(bookshelf.knex.raw('count(users.*) over () as total'))

      if (opts.communities && opts.project) {
        qb.leftJoin('users_community', 'users_community.user_id', '=', 'users.id')
        qb.leftJoin('projects_users', 'projects_users.user_id', '=', 'users.id')
        qb.leftJoin('projects', 'projects.user_id', '=', 'users.id')

        qb.where(function () {
          this.where(function () {
            this.whereIn('users_community.community_id', opts.communities)
            this.where('users_community.active', true)
          })
          .orWhere(function () {
            this.where('projects.id', opts.project)
            .orWhere('projects_users.project_id', opts.project)
          })
        })
      } else if (opts.communities) {
        qb.join('users_community', 'users_community.user_id', '=', 'users.id')
        qb.whereIn('users_community.community_id', opts.communities)
        qb.where('users_community.active', true)
      } else if (opts.project) {
        qb.join('projects_users', 'projects_users.user_id', '=', 'users.id')
        qb.leftJoin('projects', 'projects.user_id', '=', 'users.id')
        qb.where(function () {
          this.where('projects.id', opts.project)
          .orWhere('projects_users.project_id', opts.project)
        })
      }

      if (opts.autocomplete) {
        qb.whereRaw('users.name ilike ?', opts.autocomplete + '%')
      }

      if (opts.term) {
        qb.leftJoin('users_skill', 'users_skill.user_id', '=', 'users.id')
        qb.leftJoin('users_org', 'users_org.user_id', '=', 'users.id')
        Search.addTermToQueryBuilder(opts.term, qb, {
          columns: ['users.name', 'users.bio', 'users_skill.skill_name', 'users_org.org_name']
        })
      }

      // prevent duplicates due to the joins
      qb.groupBy('users.id')

      if (opts.start_time && opts.end_time) {
        qb.whereRaw('users.created_at between ? and ?', [opts.start_time, opts.end_time])
      }

      if (opts.exclude) {
        qb.whereNotIn('id', opts.exclude)
      }
    })
  },

  addTermToQueryBuilder: function (term, qb, opts) {
    var query = _.chain(term.split(/\s*\s/)) // split on whitespace
        .map(word => word.replace(/[,;|:&()!\\]+/, ''))
        .reject(_.isEmpty)
        .map(word => word + ':*') // add prefix matching
        .reduce((result, word) => {
          // build the tsquery string using logical AND operands
          result += ' & ' + word
          return result
        }).value()

    var statement = format('(%s)',
        opts.columns
          .map(col => format("(to_tsvector('english', %s) @@ to_tsquery(?))", col))
          .join(' or '))

    var values = _.times(opts.columns.length, () => query)

    qb.where(() => this.whereRaw(statement, values))
  }

}
<commit_msg>order projects newest first<commit_after>module.exports = {
  forProjects: function (opts) {
    return Project.query(qb => {
      if (opts.user) {
        qb.leftJoin('projects_users', function () {
          this.on('projects.id', '=', 'projects_users.project_id')
        })
        qb.where(function () {
          this.where('projects.user_id', opts.user)
        })
        .orWhere('projects_users.user_id', opts.user)
      }

      if (opts.community) {
        qb.where(function () {
          var clause = this.whereIn('community_id', opts.community)
          if (opts.includePublic) {
            clause.orWhere('visibility', Project.Visibility.PUBLIC)
          }
        })
      }

      if (opts.published) {
        qb.whereRaw('published_at is not null')
      }

      if (opts.term) {
        Search.addTermToQueryBuilder(opts.term, qb, {
          columns: ['projects.title', 'projects.intention', 'projects.details']
        })
      }

      // this counts total rows matching the criteria, disregarding limit,
      // which is useful for pagination
      qb.select(bookshelf.knex.raw('projects.*, count(*) over () as total'))

      qb.limit(opts.limit)
      qb.offset(opts.offset)
      qb.groupBy('projects.id')
      qb.orderBy('projects.updated_at', 'desc')
    })
  },

  forPosts: function (opts) {
    return Post.query(function (qb) {
      qb.limit(opts.limit)
      qb.offset(opts.offset)
      qb.where({'post.active': true})

      // this counts total rows matching the criteria, disregarding limit,
      // which is useful for pagination
      qb.select(bookshelf.knex.raw('post.*, count(*) over () as total'))

      if (opts.users) {
        qb.whereIn('post.user_id', opts.users)
      }

      if (opts.excludeUsers) {
        qb.whereNotIn('post.user_id', opts.excludeUsers)
      }

      if (opts.communities) {
        qb.join('post_community', 'post_community.post_id', '=', 'post.id')
        qb.whereIn('post_community.community_id', opts.communities)
        qb.groupBy(['post.id', 'post_community.post_id'])
      }

      if (opts.project) {
        qb.join('posts_projects', 'posts_projects.post_id', '=', 'post.id')
        qb.where('posts_projects.project_id', opts.project)
      } else {
        qb.where('post.visibility', '!=', Post.Visibility.DRAFT_PROJECT)
      }

      if (opts.term) {
        Search.addTermToQueryBuilder(opts.term, qb, {
          columns: ['post.name', 'post.description']
        })
      }

      if (opts.follower) {
        qb.join('follower', 'follower.post_id', '=', 'post.id')
        qb.where('follower.user_id', opts.follower)
        qb.whereRaw('(post.user_id != ? or post.user_id is null)', opts.follower)
      }

      if (!opts.type || opts.type === 'all') {
        qb.where('post.type', '!=', 'welcome')
      } else if (opts.type !== 'all+welcome') {
        qb.where({type: opts.type})
      }

      if (opts.type === 'event' && opts.filter === 'future') {
        qb.whereRaw('(post.start_time > now())')
      }

      if (opts.start_time && opts.end_time) {
        qb.whereRaw('((post.created_at between ? and ?) or (post.updated_at between ? and ?))',
          [opts.start_time, opts.end_time, opts.start_time, opts.end_time])
      }

      if (opts.visibility) {
        qb.whereIn('visibility', opts.visibility)
      }

      if (opts.sort === 'suggested') {
        qb.join('user_post_relevance', 'user_post_relevance.post_id', '=', 'post.id')
        qb.where('user_post_relevance.user_id', opts.forUser)
        qb.orderBy('similarity', 'desc')
        qb.groupBy('similarity')
      } else if (opts.sort === 'fulfilled_at') {
        qb.orderByRaw('post.fulfilled_at desc, post.updated_at desc')
      } else if (Array.isArray(opts.sort)) {
        qb.orderBy(opts.sort[0], opts.sort[1])
      } else if (opts.sort) {
        qb.orderBy(opts.sort, 'desc')
      }
    })
  },

  forUsers: function (opts) {
    return User.query(function (qb) {
      qb.limit(opts.limit || 1000)
      qb.offset(opts.offset || 0)
      qb.where('users.active', '=', true)

      // this is not necessarily what any consumer desires, but
      // some ordering must be specified for pagination
      qb.orderBy('name', 'asc')

      // this counts total rows matching the criteria, disregarding limit,
      // which is useful for pagination
      qb.select(bookshelf.knex.raw('count(users.*) over () as total'))

      if (opts.communities && opts.project) {
        qb.leftJoin('users_community', 'users_community.user_id', '=', 'users.id')
        qb.leftJoin('projects_users', 'projects_users.user_id', '=', 'users.id')
        qb.leftJoin('projects', 'projects.user_id', '=', 'users.id')

        qb.where(function () {
          this.where(function () {
            this.whereIn('users_community.community_id', opts.communities)
            this.where('users_community.active', true)
          })
          .orWhere(function () {
            this.where('projects.id', opts.project)
            .orWhere('projects_users.project_id', opts.project)
          })
        })
      } else if (opts.communities) {
        qb.join('users_community', 'users_community.user_id', '=', 'users.id')
        qb.whereIn('users_community.community_id', opts.communities)
        qb.where('users_community.active', true)
      } else if (opts.project) {
        qb.join('projects_users', 'projects_users.user_id', '=', 'users.id')
        qb.leftJoin('projects', 'projects.user_id', '=', 'users.id')
        qb.where(function () {
          this.where('projects.id', opts.project)
          .orWhere('projects_users.project_id', opts.project)
        })
      }

      if (opts.autocomplete) {
        qb.whereRaw('users.name ilike ?', opts.autocomplete + '%')
      }

      if (opts.term) {
        qb.leftJoin('users_skill', 'users_skill.user_id', '=', 'users.id')
        qb.leftJoin('users_org', 'users_org.user_id', '=', 'users.id')
        Search.addTermToQueryBuilder(opts.term, qb, {
          columns: ['users.name', 'users.bio', 'users_skill.skill_name', 'users_org.org_name']
        })
      }

      // prevent duplicates due to the joins
      qb.groupBy('users.id')

      if (opts.start_time && opts.end_time) {
        qb.whereRaw('users.created_at between ? and ?', [opts.start_time, opts.end_time])
      }

      if (opts.exclude) {
        qb.whereNotIn('id', opts.exclude)
      }
    })
  },

  addTermToQueryBuilder: function (term, qb, opts) {
    var query = _.chain(term.split(/\s*\s/)) // split on whitespace
        .map(word => word.replace(/[,;|:&()!\\]+/, ''))
        .reject(_.isEmpty)
        .map(word => word + ':*') // add prefix matching
        .reduce((result, word) => {
          // build the tsquery string using logical AND operands
          result += ' & ' + word
          return result
        }).value()

    var statement = format('(%s)',
        opts.columns
          .map(col => format("(to_tsvector('english', %s) @@ to_tsquery(?))", col))
          .join(' or '))

    var values = _.times(opts.columns.length, () => query)

    qb.where(() => this.whereRaw(statement, values))
  }

}
<|endoftext|>


<commit_before>(function(){

    xtag.register('widget-DAQ', {
        extends: 'div',
        lifecycle: {
            created: function() {
                var xString, option, title, deckWrap, builderLink;

                this.width = this.offsetWidth;
                this.height = window.innerHeight*0.6;
                this.showing = 0;
                this.lastCollectorTTindex = null;
                this.lastDigitizerTTindex = null;

                //get the DAQ structure
                XHR('http://' + this.MIDAS + '/?cmd=jcopy&odb=/DAQ&encoding=json-nokeys',
                    function(res){
                        this.buildDAQ(res);
                    }.bind(this),
                    'application/json');

                //build DOM
                this.navBlock = document.createElement('div');
                this.navBlock.setAttribute('class', 'DAQnav');
                this.appendChild(this.navBlock);

                title = document.createElement('h1');
                title.innerHTML = 'DAQ';
                this.navBlock.appendChild(title);

                builderLink = document.createElement('a');
                builderLink.setAttribute('href', '/MSCbuilder');
                builderLink.innerHTML = 'MSC Builder';
                builderLink.setAttribute('class', 'stdin');

                this.cardNav = document.createElement('select');
                this.cardNav.setAttribute('id', 'DAQnav')
                this.cardNav.setAttribute('class', 'stdin');
                this.cardNav.onchange = function(){
                    var targetIndex = parseInt(selected('DAQnav'), 10);
                    document.getElementById('DAQdeck').shuffleTo(targetIndex);
                    this.writeCollectorTooltip(-1);
                    this.showing = targetIndex;
                }.bind(this)
                this.navBlock.appendChild(this.cardNav);

                option = document.createElement('option');
                option.value = 0;
                option.innerHTML = 'Master'
                this.cardNav.appendChild(option);

                deckWrap = document.createElement('div');
                this.appendChild(deckWrap);

                xString = '<x-deck id="DAQdeck" selected-index=0>';
                xString += '<x-card id="DAQmasterCard"></x-card></x-deck>';
                xtag.innerHTML(deckWrap, xString);
                this.nCards = 1

                this.masterBlock = document.createElement('div');
                this.masterBlock.setAttribute('class', 'DAQheadNode');
                document.getElementById('DAQmasterCard').appendChild(this.masterBlock);

                this.collectorBlock = document.createElement('div');
                this.collectorBlock.setAttribute('id', 'collectorBlock');
                document.getElementById('DAQmasterCard').appendChild(this.collectorBlock);

                this.tooltip = document.createElement('div');
                this.tooltip.setAttribute('id', 'tooltip');
                this.appendChild(this.tooltip);

                ////////////////////////////
                //Kinetic.js setup
                ////////////////////////////

                //indices for these arrays correspond to the x-card index on display
                this.stage = [];
                this.mainLayer = [];
                this.scaleLayer = [];

                //let repopulate know that the detector would like to be updated every loop:
                if(!window.refreshTargets)
                    window.refreshTargets = [];
                window.refreshTargets[window.refreshTargets.length] = this;
            },
            inserted: function() {},
            removed: function() {},
            attributeChanged: function() {}
        },
        events: {

        },
        accessors: {
            'MIDAS':{
                attribute: {} //this just needs to be declared
            }
        },
        methods: {
            'buildDAQ' : function(response){
                var data = JSON.parse(response),
                    i, j, k, option,
                    collectorGutter = this.width*0.02,
                    collectorWidth = (this.width - collectorGutter*16) / 16,
                    xLength = collectorGutter/2,
                    xLeft, xRight, M, S, C, MSCstring;

                this.collectors = [];
                this.digitizers = [];
                this.collectorCells = [];
                this.localMSC = [];

                //determine what collectors are present and instantiate x-cards for each one
                for(i=0; i<16; i++){
                    this.collectors[i] = data.hosts['collector0x' + i.toString(16)];

                    if(this.collectors[i]){
                        document.getElementById('DAQdeck').innerHTML += '<x-card id="collector'+i+'">

</x-card>';
                        option = document.createElement('option');
                        option.value = this.nCards;
                        option.innerHTML = 'Collector 0x' + i.toString(16).toUpperCase();
                        this.cardNav.appendChild(option);
                        this.nCards++;

                    }
                }

                //now that the xdeck is built, paint master canvas:
                //collectors:
                this.setupKinetic('collectorBlock');
                for(i=0; i<16; i++){
                    if(this.collectors[i]){
                        this.collectorCells[i] = new Kinetic.Rect({
                            x:collectorGutter/2 + i*this.width/16,
                            y:this.height*0.6,
                            width: collectorWidth,
                            height:this.height*0.2,
                            fill:'#555555',
                            stroke: '#000000',
                            strokeWidth: 4
                        });
                        this.collectorCells[i].on('click', this.clickCollector.bind(this, i));
                        this.collectorCells[i].on('mousemove', this.moveTooltip.bind(this) );
                        this.collectorCells[i].on('mouseover', this.writeCollectorTooltip.bind(this, i) );
                        this.collectorCells[i].on('mouseout', this.writeCollectorTooltip.bind(this, -1));
                        this.mainLayer[0].add(this.collectorCells[i]);

                        this.localMSC[i] = []
                    } else{
                        //terminate loose cord with red x
                        xLeft = new Kinetic.Line({
                            points: [(collectorGutter + collectorWidth)/2 + i*(collectorGutter+collectorWidth) - xLength, 0.6*this.height - xLength, (collectorGutter + collectorWidth)/2 + i*(collectorGutter+collectorWidth) + xLength, 0.6*this.height + xLength],
                            stroke: '#FF0000',
                            strokeWidth: 8
                        });
                        xRight = new Kinetic.Line({
                            points: [(collectorGutter + collectorWidth)/2 + i*(collectorGutter+collectorWidth) + xLength, 0.6*this.height - xLength, (collectorGutter + collectorWidth)/2 + i*(collectorGutter+collectorWidth) - xLength, 0.6*this.height + xLength],
                            stroke: '#FF0000',
                            strokeWidth: 8
                        });
                        this.mainLayer[0].add(xLeft);
                        this.mainLayer[0].add(xRight);
                    }
                }

                //cabling:
                this.masterCables = [[],[],[],[]]; //1-to-4 cables: outer index counts master port, inner index counts collector
                for(i=0; i<4; i++){
                    this.masterCables[i][0] = new Kinetic.Line({
                        points: [collectorWidth*2 + collectorGutter*1.75 + i*(collectorWidth + collectorGutter)*4,0, collectorWidth*2 + collectorGutter*1.75 + i*(collectorWidth + collectorGutter)*4, 0.3*this.height],
                        stroke: '#000000',
                        strokeWidth: 4
                    });
                    this.mainLayer[0].add(this.masterCables[i][0]);
                    this.masterCables[i][0].moveToBottom();
                    for(j=1; j<5; j++){
                        this.masterCables[i][j] = new Kinetic.Line({
                            points: [collectorWidth*2 + collectorGutter*1.75 + i*(collectorWidth + collectorGutter)*4, 0.3*this.height, (collectorGutter + collectorWidth)/2 + (4*i+j-1)*(collectorGutter+collectorWidth), 0.6*this.height],
                            stroke: '#000000',
                            strokeWidth: 4
                        });
                        this.mainLayer[0].add(this.masterCables[i][j]);
                        this.masterCables[i][j].moveToBottom();
                    }
                }
                this.mainLayer[0].draw();

                //and again for each collector card
                this.digitizerCells = [];
                this.collectorCables = [];
                for(i=0; i<16; i++){
                    this.digitizerCells[i] = [];

                    if(!this.collectors[i]) continue;

                    this.setupKinetic('digitizerBlock'+i);
                    for(j=0; j<16; j++){
                        if(data.hosts['collector0x' + i.toString(16)].digitizers[j]){
                            this.digitizerCells[i][j] = new Kinetic.Rect({
                                x:collectorGutter/2 + j*this.width/16,
                                y:this.height*0.6,
                                width: collectorWidth,
                                height:this.height*0.2,
                                fill:'#555555',
                                stroke: '#000000',
                                strokeWidth: 4
                            });
                            this.digitizerCells[i][j].on('mousemove', this.moveTooltip.bind(this) );
                            this.digitizerCells[i][j].on('mouseover', this.writeDigitizerTooltip.bind(this, j) );
                            this.digitizerCells[i][j].on('mouseout', this.writeDigitizerTooltip.bind(this, -1));
                            this.mainLayer[i+1].add(this.digitizerCells[i][j]);

                            this.localMSC[i][j] = {};
                        } else{
                            //terminate loose cord with red x
                            xLeft = new Kinetic.Line({
                                points: [(collectorGutter + collectorWidth)/2 + j*(collectorGutter+collectorWidth) - xLength, 0.6*this.height - xLength, (collectorGutter + collectorWidth)/2 + j*(collectorGutter+collectorWidth) + xLength, 0.6*this.height + xLength],
                                stroke: '#FF0000',
                                strokeWidth: 8
                            });
                            xRight = new Kinetic.Line({
                                points: [(collectorGutter + collectorWidth)/2 + j*(collectorGutter+collectorWidth) + xLength, 0.6*this.height - xLength, (collectorGutter + collectorWidth)/2 + j*(collectorGutter+collectorWidth) - xLength, 0.6*this.height + xLength],
                                stroke: '#FF0000',
                                strokeWidth: 8
                            });
                            this.mainLayer[i+1].add(xLeft);
                            this.mainLayer[i+1].add(xRight);
                        }

                    }

                    //cabling:
                    this.collectorCables[i] = [];
                    for(j=0; j<4; j++){
                        this.collectorCables[i][j] = [];
                        this.collectorCables[i][j][0] = new Kinetic.Line({
                            points: [collectorWidth*2 + collectorGutter*1.75 + j*(collectorWidth + collectorGutter)*4,0, collectorWidth*2 + collectorGutter*1.75 + j*(collectorWidth + collectorGutter)*4, 0.3*this.height],
                            stroke: '#000000',
                            strokeWidth: 4
                        });
                        this.mainLayer[i+1].add(this.collectorCables[i][j][0]);
                        this.collectorCables[i][j][0].moveToBottom();
                        for(k=1; k<5; k++){
                            this.collectorCables[i][j][k] = new Kinetic.Line({
                                points: [collectorWidth*2 + collectorGutter*1.75 + j*(collectorWidth + collectorGutter)*4, 0.3*this.height, (collectorGutter + collectorWidth)/2 + (4*j+k-1)*(collectorGutter+collectorWidth), 0.6*this.height],
                                stroke: '#000000',
                                strokeWidth: 4
                            });
                            this.mainLayer[i+1].add(this.collectorCables[i][j][k]);
                            this.collectorCables[i][j][k].moveToBottom();
                        }
                    }
                    this.mainLayer[i+1].draw();

                }

                //build the MSC table in per-digitizer chunks
                //this.localMSC[collector index][digitizer index][ADC index] = channel name
                for(i=0; i<data.MSC.MSC.length; i++){
                    M = (parseInt(data.MSC.MSC[i],10) & 0xF000) >> 12;
                    S = (parseInt(data.MSC.MSC[i],10) & 0x0F00) >> 8;
                    C = parseInt(data.MSC.MSC[i],10) & 0x00FF;
                    MSCstring = data.MSC.MSC[i].toString(16).toUpperCase();
                        if(MSCstring.length == 1)
                            MSCstring = '000' + MSCstring;
                        else if(MSCstring.length == 2)
                            MSCstring = '00' + MSCstring;
                        else if(MSCstring.length == 3)
                            MSCstring = '0' + MSCstring
                    this.localMSC[M][S][data.MSC.chan[i]] = '0x'+MSCstring;
                }

            },

            'setupKinetic' : function(targetID){
                var i = this.stage.length;
                //point kinetic at the div and set up the staging and layers:
                this.stage[i] = new Kinetic.Stage({
                    container: targetID,
                    width: this.width,
                    height: this.height
                });
                this.mainLayer[i] = new Kinetic.Layer();       //main rendering layer
                this.scaleLayer[i] = new Kinetic.Layer();      //layer for scales / legends

                this.stage[i].add(this.mainLayer[i]);
                this.stage[i].add(this.scaleLayer[i]);
            },

            'clickCollector' : function(index){
                //document.getElementById('DAQdeck').shuffleTo(index+1);
                document.getElementById('DAQnav').value = index+1;
                document.getElementById('DAQnav').onchange();
            },

            //move the tooltip around
            'moveTooltip' : function(evt){
                var tt = document.getElementById('tooltip');

                tt.setAttribute('style', 'display:block; z-index:10; position: absolute; left:' + evt.pageX + '; top:' + evt.pageY  + ';');
            },

            //formulate the tooltip text for cell i and write it on the tooltip layer.
            'writeCollectorTooltip': function(i){
                var text;

                if(i!=-1){
                    text = 'Collector 0x' + i.toString(16);
                } else {
                    text = '';
                }

                this.lastCollectorTTindex = i;
                if(text != '')
                    document.getElementById('tooltip').innerHTML = text;
                else
                    document.getElementById('tooltip').setAttribute('style', '');
            },

            'writeDigitizerTooltip': function(i){
                var text, key;

                if(i!=-1){
                    text = 'Digitizer 0x' + i.toString(16).toUpperCase();
                    for(key in this.localMSC[this.showing-1][i]){
                        text += '
' + key + ' ' + this.localMSC[this.showing-1][i][key];
                    }
                } else {
                    text = '';
                }

                this.lastDigitizerTTindex = i;
                if(text != '')
                    document.getElementById('tooltip').innerHTML = text;
                else
                    document.getElementById('tooltip').setAttribute('style', '');
            },

            'update' : function(){
                //keep the tooltip updated:
                if(this.showing == 0 && (this.lastCollectorTTindex || this.lastCollectorTTindex==0)){
                    this.writeCollectorTooltip(this.lastCollectorTTindex);
                } else if(this.lastDigitizerTTindex || this.lastDigitizerTTindex==0){
                    this.writeDigitizerTooltip(this.lastDigitizerTTindex);
                }

            }
        }
    });

})();<commit_msg>msc builder link from DAQ page<commit_after>(function(){

    xtag.register('widget-DAQ', {
        extends: 'div',
        lifecycle: {
            created: function() {
                var xString, option, title, deckWrap, builderLink;

                this.width = this.offsetWidth;
                this.height = window.innerHeight*0.6;
                this.showing = 0;
                this.lastCollectorTTindex = null;
                this.lastDigitizerTTindex = null;

                //get the DAQ structure
                XHR('http://' + this.MIDAS + '/?cmd=jcopy&odb=/DAQ&encoding=json-nokeys',
                    function(res){
                        this.buildDAQ(res);
                    }.bind(this),
                    'application/json');

                //build DOM
                this.navBlock = document.createElement('div');
                this.navBlock.setAttribute('class', 'DAQnav');
                this.appendChild(this.navBlock);

                title = document.createElement('h1');
                title.innerHTML = 'DAQ';
                this.navBlock.appendChild(title);

                builderLink = document.createElement('a');
                builderLink.setAttribute('href', '/MSCbuilder');
                builderLink.innerHTML = 'MSC Builder';
                builderLink.setAttribute('class', 'stdin');
                this.navBlock.appendChild(builderLink);

                this.cardNav = document.createElement('select');
                this.cardNav.setAttribute('id', 'DAQnav')
                this.cardNav.setAttribute('class', 'stdin');
                this.cardNav.onchange = function(){
                    var targetIndex = parseInt(selected('DAQnav'), 10);
                    document.getElementById('DAQdeck').shuffleTo(targetIndex);
                    this.writeCollectorTooltip(-1);
                    this.showing = targetIndex;
                }.bind(this)
                this.navBlock.appendChild(this.cardNav);

                option = document.createElement('option');
                option.value = 0;
                option.innerHTML = 'Master'
                this.cardNav.appendChild(option);

                deckWrap = document.createElement('div');
                this.appendChild(deckWrap);

                xString = '<x-deck id="DAQdeck" selected-index=0>';
                xString += '<x-card id="DAQmasterCard"></x-card></x-deck>';
                xtag.innerHTML(deckWrap, xString);
                this.nCards = 1

                this.masterBlock = document.createElement('div');
                this.masterBlock.setAttribute('class', 'DAQheadNode');
                document.getElementById('DAQmasterCard').appendChild(this.masterBlock);

                this.collectorBlock = document.createElement('div');
                this.collectorBlock.setAttribute('id', 'collectorBlock');
                document.getElementById('DAQmasterCard').appendChild(this.collectorBlock);

                this.tooltip = document.createElement('div');
                this.tooltip.setAttribute('id', 'tooltip');
                this.appendChild(this.tooltip);

                ////////////////////////////
                //Kinetic.js setup
                ////////////////////////////

                //indices for these arrays correspond to the x-card index on display
                this.stage = [];
                this.mainLayer = [];
                this.scaleLayer = [];

                //let repopulate know that the detector would like to be updated every loop:
                if(!window.refreshTargets)
                    window.refreshTargets = [];
                window.refreshTargets[window.refreshTargets.length] = this;
            },
            inserted: function() {},
            removed: function() {},
            attributeChanged: function() {}
        },
        events: {

        },
        accessors: {
            'MIDAS':{
                attribute: {} //this just needs to be declared
            }
        },
        methods: {
            'buildDAQ' : function(response){
                var data = JSON.parse(response),
                    i, j, k, option,
                    collectorGutter = this.width*0.02,
                    collectorWidth = (this.width - collectorGutter*16) / 16,
                    xLength = collectorGutter/2,
                    xLeft, xRight, M, S, C, MSCstring;

                this.collectors = [];
                this.digitizers = [];
                this.collectorCells = [];
                this.localMSC = [];

                //determine what collectors are present and instantiate x-cards for each one
                for(i=0; i<16; i++){
                    this.collectors[i] = data.hosts['collector0x' + i.toString(16)];

                    if(this.collectors[i]){
                        document.getElementById('DAQdeck').innerHTML += '<x-card id="collector'+i+'">

</x-card>';
                        option = document.createElement('option');
                        option.value = this.nCards;
                        option.innerHTML = 'Collector 0x' + i.toString(16).toUpperCase();
                        this.cardNav.appendChild(option);
                        this.nCards++;

                    }
                }

                //now that the xdeck is built, paint master canvas:
                //collectors:
                this.setupKinetic('collectorBlock');
                for(i=0; i<16; i++){
                    if(this.collectors[i]){
                        this.collectorCells[i] = new Kinetic.Rect({
                            x:collectorGutter/2 + i*this.width/16,
                            y:this.height*0.6,
                            width: collectorWidth,
                            height:this.height*0.2,
                            fill:'#555555',
                            stroke: '#000000',
                            strokeWidth: 4
                        });
                        this.collectorCells[i].on('click', this.clickCollector.bind(this, i));
                        this.collectorCells[i].on('mousemove', this.moveTooltip.bind(this) );
                        this.collectorCells[i].on('mouseover', this.writeCollectorTooltip.bind(this, i) );
                        this.collectorCells[i].on('mouseout', this.writeCollectorTooltip.bind(this, -1));
                        this.mainLayer[0].add(this.collectorCells[i]);

                        this.localMSC[i] = []
                    } else{
                        //terminate loose cord with red x
                        xLeft = new Kinetic.Line({
                            points: [(collectorGutter + collectorWidth)/2 + i*(collectorGutter+collectorWidth) - xLength, 0.6*this.height - xLength, (collectorGutter + collectorWidth)/2 + i*(collectorGutter+collectorWidth) + xLength, 0.6*this.height + xLength],
                            stroke: '#FF0000',
                            strokeWidth: 8
                        });
                        xRight = new Kinetic.Line({
                            points: [(collectorGutter + collectorWidth)/2 + i*(collectorGutter+collectorWidth) + xLength, 0.6*this.height - xLength, (collectorGutter + collectorWidth)/2 + i*(collectorGutter+collectorWidth) - xLength, 0.6*this.height + xLength],
                            stroke: '#FF0000',
                            strokeWidth: 8
                        });
                        this.mainLayer[0].add(xLeft);
                        this.mainLayer[0].add(xRight);
                    }
                }

                //cabling:
                this.masterCables = [[],[],[],[]]; //1-to-4 cables: outer index counts master port, inner index counts collector
                for(i=0; i<4; i++){
                    this.masterCables[i][0] = new Kinetic.Line({
                        points: [collectorWidth*2 + collectorGutter*1.75 + i*(collectorWidth + collectorGutter)*4,0, collectorWidth*2 + collectorGutter*1.75 + i*(collectorWidth + collectorGutter)*4, 0.3*this.height],
                        stroke: '#000000',
                        strokeWidth: 4
                    });
                    this.mainLayer[0].add(this.masterCables[i][0]);
                    this.masterCables[i][0].moveToBottom();
                    for(j=1; j<5; j++){
                        this.masterCables[i][j] = new Kinetic.Line({
                            points: [collectorWidth*2 + collectorGutter*1.75 + i*(collectorWidth + collectorGutter)*4, 0.3*this.height, (collectorGutter + collectorWidth)/2 + (4*i+j-1)*(collectorGutter+collectorWidth), 0.6*this.height],
                            stroke: '#000000',
                            strokeWidth: 4
                        });
                        this.mainLayer[0].add(this.masterCables[i][j]);
                        this.masterCables[i][j].moveToBottom();
                    }
                }
                this.mainLayer[0].draw();

                //and again for each collector card
                this.digitizerCells = [];
                this.collectorCables = [];
                for(i=0; i<16; i++){
                    this.digitizerCells[i] = [];

                    if(!this.collectors[i]) continue;

                    this.setupKinetic('digitizerBlock'+i);
                    for(j=0; j<16; j++){
                        if(data.hosts['collector0x' + i.toString(16)].digitizers[j]){
                            this.digitizerCells[i][j] = new Kinetic.Rect({
                                x:collectorGutter/2 + j*this.width/16,
                                y:this.height*0.6,
                                width: collectorWidth,
                                height:this.height*0.2,
                                fill:'#555555',
                                stroke: '#000000',
                                strokeWidth: 4
                            });
                            this.digitizerCells[i][j].on('mousemove', this.moveTooltip.bind(this) );
                            this.digitizerCells[i][j].on('mouseover', this.writeDigitizerTooltip.bind(this, j) );
                            this.digitizerCells[i][j].on('mouseout', this.writeDigitizerTooltip.bind(this, -1));
                            this.mainLayer[i+1].add(this.digitizerCells[i][j]);

                            this.localMSC[i][j] = {};
                        } else{
                            //terminate loose cord with red x
                            xLeft = new Kinetic.Line({
                                points: [(collectorGutter + collectorWidth)/2 + j*(collectorGutter+collectorWidth) - xLength, 0.6*this.height - xLength, (collectorGutter + collectorWidth)/2 + j*(collectorGutter+collectorWidth) + xLength, 0.6*this.height + xLength],
                                stroke: '#FF0000',
                                strokeWidth: 8
                            });
                            xRight = new Kinetic.Line({
                                points: [(collectorGutter + collectorWidth)/2 + j*(collectorGutter+collectorWidth) + xLength, 0.6*this.height - xLength, (collectorGutter + collectorWidth)/2 + j*(collectorGutter+collectorWidth) - xLength, 0.6*this.height + xLength],
                                stroke: '#FF0000',
                                strokeWidth: 8
                            });
                            this.mainLayer[i+1].add(xLeft);
                            this.mainLayer[i+1].add(xRight);
                        }

                    }

                    //cabling:
                    this.collectorCables[i] = [];
                    for(j=0; j<4; j++){
                        this.collectorCables[i][j] = [];
                        this.collectorCables[i][j][0] = new Kinetic.Line({
                            points: [collectorWidth*2 + collectorGutter*1.75 + j*(collectorWidth + collectorGutter)*4,0, collectorWidth*2 + collectorGutter*1.75 + j*(collectorWidth + collectorGutter)*4, 0.3*this.height],
                            stroke: '#000000',
                            strokeWidth: 4
                        });
                        this.mainLayer[i+1].add(this.collectorCables[i][j][0]);
                        this.collectorCables[i][j][0].moveToBottom();
                        for(k=1; k<5; k++){
                            this.collectorCables[i][j][k] = new Kinetic.Line({
                                points: [collectorWidth*2 + collectorGutter*1.75 + j*(collectorWidth + collectorGutter)*4, 0.3*this.height, (collectorGutter + collectorWidth)/2 + (4*j+k-1)*(collectorGutter+collectorWidth), 0.6*this.height],
                                stroke: '#000000',
                                strokeWidth: 4
                            });
                            this.mainLayer[i+1].add(this.collectorCables[i][j][k]);
                            this.collectorCables[i][j][k].moveToBottom();
                        }
                    }
                    this.mainLayer[i+1].draw();

                }

                //build the MSC table in per-digitizer chunks
                //this.localMSC[collector index][digitizer index][ADC index] = channel name
                for(i=0; i<data.MSC.MSC.length; i++){
                    M = (parseInt(data.MSC.MSC[i],10) & 0xF000) >> 12;
                    S = (parseInt(data.MSC.MSC[i],10) & 0x0F00) >> 8;
                    C = parseInt(data.MSC.MSC[i],10) & 0x00FF;
                    MSCstring = data.MSC.MSC[i].toString(16).toUpperCase();
                        if(MSCstring.length == 1)
                            MSCstring = '000' + MSCstring;
                        else if(MSCstring.length == 2)
                            MSCstring = '00' + MSCstring;
                        else if(MSCstring.length == 3)
                            MSCstring = '0' + MSCstring
                    this.localMSC[M][S][data.MSC.chan[i]] = '0x'+MSCstring;
                }

            },

            'setupKinetic' : function(targetID){
                var i = this.stage.length;
                //point kinetic at the div and set up the staging and layers:
                this.stage[i] = new Kinetic.Stage({
                    container: targetID,
                    width: this.width,
                    height: this.height
                });
                this.mainLayer[i] = new Kinetic.Layer();       //main rendering layer
                this.scaleLayer[i] = new Kinetic.Layer();      //layer for scales / legends

                this.stage[i].add(this.mainLayer[i]);
                this.stage[i].add(this.scaleLayer[i]);
            },

            'clickCollector' : function(index){
                //document.getElementById('DAQdeck').shuffleTo(index+1);
                document.getElementById('DAQnav').value = index+1;
                document.getElementById('DAQnav').onchange();
            },

            //move the tooltip around
            'moveTooltip' : function(evt){
                var tt = document.getElementById('tooltip');

                tt.setAttribute('style', 'display:block; z-index:10; position: absolute; left:' + evt.pageX + '; top:' + evt.pageY  + ';');
            },

            //formulate the tooltip text for cell i and write it on the tooltip layer.
            'writeCollectorTooltip': function(i){
                var text;

                if(i!=-1){
                    text = 'Collector 0x' + i.toString(16);
                } else {
                    text = '';
                }

                this.lastCollectorTTindex = i;
                if(text != '')
                    document.getElementById('tooltip').innerHTML = text;
                else
                    document.getElementById('tooltip').setAttribute('style', '');
            },

            'writeDigitizerTooltip': function(i){
                var text, key;

                if(i!=-1){
                    text = 'Digitizer 0x' + i.toString(16).toUpperCase();
                    for(key in this.localMSC[this.showing-1][i]){
                        text += '
' + key + ' ' + this.localMSC[this.showing-1][i][key];
                    }
                } else {
                    text = '';
                }

                this.lastDigitizerTTindex = i;
                if(text != '')
                    document.getElementById('tooltip').innerHTML = text;
                else
                    document.getElementById('tooltip').setAttribute('style', '');
            },

            'update' : function(){
                //keep the tooltip updated:
                if(this.showing == 0 && (this.lastCollectorTTindex || this.lastCollectorTTindex==0)){
                    this.writeCollectorTooltip(this.lastCollectorTTindex);
                } else if(this.lastDigitizerTTindex || this.lastDigitizerTTindex==0){
                    this.writeDigitizerTooltip(this.lastDigitizerTTindex);
                }

            }
        }
    });

})();<|endoftext|>


<commit_before>import "../loadenv"

import stream from "getstream"
import moment from "moment"
import normalize from "normalize-url"
import async from "async"

import RSS from "../models/rss"
import Article from "../models/article"

import "../utils/db"
import config from "../config"
import logger from "../utils/logger"
import util from "util"

import sendRssFeedToCollections from "../utils/events/sendRssFeedToCollections"
import { ParseFeed } from "./parsers"

import async_tasks from "../async_tasks"

const streamClient = stream.connect(config.stream.apiKey, config.stream.apiSecret)

// connect the handler to the queue
logger.info("Starting the RSS worker")

// TODO: move this to a separate main.js
async_tasks.ProcessRssQueue(15, handleRSS)

// the top level handleRSS just intercepts error handling before it goes to Bull
async function handleRSS(job) {
    let promise = _handleRSS(job)
    promise.catch(err => {
        logger.warn(`rss job ${job} broke with err ${err}`)
    })
    return promise
}

// Handle Podcast scrapes the podcast and updates the episodes
async function handleRSS(job) {
    logger.info(`Processing ${job.data.url}`)

    // verify we have the rss object
    let rssID = job.data.rss
    let rss = await RSS.findOne({ _id: rssID })
    if (!rss) {
        logger.warn(`RSS with ID ${rssID} does not exist`)
        return
    }

    // mark as done, will be schedule again in 15 min from now
    // we do this early so a temporary failure doesnt leave things in a broken state
    let completed = await markDone(rssID)
    logger.info(`Marked ${rssID} as done`)

    // parse the articles
    let rssContent
    try {
        rssContent = await util.promisify(ParseFeed)(job.data.url)
    } catch (e) {
        logger.info(`rss scraping broke for url ${job.data.url}`)
        return
    }

    // update the articles
    logger.info(`Updating ${rssContent.articles.length} articles for feed ${rssID}`)
    let allArticles = await Promise.all(
        rssContent.articles.map(article => {
            let normalizedUrl = normalize(article.url)
            article.url = normalizedUrl
            return updateArticle(rssID, normalizedUrl, article)
        }),
    )

    // updatedArticles will contain `null` for all articles that didn't get updated, that we alrady have in the system.
    let updatedArticles = allArticles.filter(updatedArticle => {
        return updatedArticle
    })

    let rssFeed = streamClient.feed("rss", rssID)
    logger.info(`Syncing ${updatedArticles.length} articles to Stream`)
    if (updatedArticles.length > 0) {
        let chunkSize = 100
        for (let i = 0, j = updatedArticles.length; i < j; i += chunkSize) {
            let chunk = updatedArticles.slice(i, i + chunkSize)

            let streamArticles = chunk.map(article => {
                return {
                    actor: article.rss,
                    foreign_id: `articles:${article._id}`,
                    object: article._id,
                    time: article.publicationDate,
                    verb: "rss_article",
                }
            })

            let streamResponse = await rssFeed.addActivities(streamArticles)
            let response = await sendRssFeedToCollections(job.data.rss)
        }
    }
    logger.info(`Completed scraping for ${job.data.url}`)
}

// updateArticle updates the article in mongodb
async function updateArticle(rssID, normalizedUrl, post) {
    let rawArticle = await Article.findOneAndUpdate(
        {
            rss: rssID,
            url: normalizedUrl,
        },
        {
            commentUrl: post.commentUrl,
            content: post.content,
            description: post.description,
            images: post.images || {},
            publicationDate: post.publicationDate,
            rss: rssID,
            title: post.title,
            url: post.url,
        },
        {
            new: true,
            rawResult: true,
            upsert: true,
        },
    )
    if (rawArticle.lastErrorObject.updatedExisting) {
        // article already exists
        return
    }

    let article = rawArticle.value
    // after article is created, add to algolia, stream, and og scraper queue
    let response = await async_tasks.OgQueueAdd(
        {
            type: "rss",
            url: article.url,
        },
        {
            removeOnComplete: true,
            removeOnFail: true,
        },
    )
    return article
}

// markDone sets lastScraped to now and isParsing to false
async function markDone(rssID) {
    /*
	Set the last scraped for the given rssID
	*/
    let now = moment().toISOString()
    let updated = await RSS.update(
        { _id: rssID },
        {
            lastScraped: now,
            isParsing: false,
        },
    )
    return updated
}
<commit_msg>more concurrency for rss<commit_after>import "../loadenv"

import stream from "getstream"
import moment from "moment"
import normalize from "normalize-url"
import async from "async"

import RSS from "../models/rss"
import Article from "../models/article"

import "../utils/db"
import config from "../config"
import logger from "../utils/logger"
import util from "util"

import sendRssFeedToCollections from "../utils/events/sendRssFeedToCollections"
import { ParseFeed } from "./parsers"

import async_tasks from "../async_tasks"

const streamClient = stream.connect(config.stream.apiKey, config.stream.apiSecret)

// connect the handler to the queue
logger.info("Starting the RSS worker")

// TODO: move this to a separate main.js
async_tasks.ProcessRssQueue(30, handleRSS)

// the top level handleRSS just intercepts error handling before it goes to Bull
async function handleRSS(job) {
    let promise = _handleRSS(job)
    promise.catch(err => {
        logger.warn(`rss job ${job} broke with err ${err}`)
    })
    return promise
}

// Handle Podcast scrapes the podcast and updates the episodes
async function handleRSS(job) {
    logger.info(`Processing ${job.data.url}`)

    // verify we have the rss object
    let rssID = job.data.rss
    let rss = await RSS.findOne({ _id: rssID })
    if (!rss) {
        logger.warn(`RSS with ID ${rssID} does not exist`)
        return
    }

    // mark as done, will be schedule again in 15 min from now
    // we do this early so a temporary failure doesnt leave things in a broken state
    let completed = await markDone(rssID)
    logger.info(`Marked ${rssID} as done`)

    // parse the articles
    let rssContent
    try {
        rssContent = await util.promisify(ParseFeed)(job.data.url)
    } catch (e) {
        logger.info(`rss scraping broke for url ${job.data.url}`)
        return
    }

    // update the articles
    logger.info(`Updating ${rssContent.articles.length} articles for feed ${rssID}`)
    let allArticles = await Promise.all(
        rssContent.articles.map(article => {
            let normalizedUrl = normalize(article.url)
            article.url = normalizedUrl
            return updateArticle(rssID, normalizedUrl, article)
        }),
    )

    // updatedArticles will contain `null` for all articles that didn't get updated, that we alrady have in the system.
    let updatedArticles = allArticles.filter(updatedArticle => {
        return updatedArticle
    })

    let rssFeed = streamClient.feed("rss", rssID)
    logger.info(`Syncing ${updatedArticles.length} articles to Stream`)
    if (updatedArticles.length > 0) {
        let chunkSize = 100
        for (let i = 0, j = updatedArticles.length; i < j; i += chunkSize) {
            let chunk = updatedArticles.slice(i, i + chunkSize)

            let streamArticles = chunk.map(article => {
                return {
                    actor: article.rss,
                    foreign_id: `articles:${article._id}`,
                    object: article._id,
                    time: article.publicationDate,
                    verb: "rss_article",
                }
            })

            let streamResponse = await rssFeed.addActivities(streamArticles)
            let response = await sendRssFeedToCollections(job.data.rss)
        }
    }
    logger.info(`Completed scraping for ${job.data.url}`)
}

// updateArticle updates the article in mongodb
async function updateArticle(rssID, normalizedUrl, post) {
    let rawArticle = await Article.findOneAndUpdate(
        {
            rss: rssID,
            url: normalizedUrl,
        },
        {
            commentUrl: post.commentUrl,
            content: post.content,
            description: post.description,
            images: post.images || {},
            publicationDate: post.publicationDate,
            rss: rssID,
            title: post.title,
            url: post.url,
        },
        {
            new: true,
            rawResult: true,
            upsert: true,
        },
    )
    if (rawArticle.lastErrorObject.updatedExisting) {
        // article already exists
        return
    }

    let article = rawArticle.value
    // after article is created, add to algolia, stream, and og scraper queue
    let response = await async_tasks.OgQueueAdd(
        {
            type: "rss",
            url: article.url,
        },
        {
            removeOnComplete: true,
            removeOnFail: true,
        },
    )
    return article
}

// markDone sets lastScraped to now and isParsing to false
async function markDone(rssID) {
    /*
	Set the last scraped for the given rssID
	*/
    let now = moment().toISOString()
    let updated = await RSS.update(
        { _id: rssID },
        {
            lastScraped: now,
            isParsing: false,
        },
    )
    return updated
}
<|endoftext|>


<commit_before>import React from 'react';
import './styles/App.css';
import {FirebaseContext} from './components/Firebase';
import {Button} from 'react-bootstrap';

class App extends React.Component {

  static contextType = FirebaseContext;
  constructor() {
    super();
    this.state = {authState: false, userInfo: null};
  }

  afterAuthStateCheck(status) {
    console.log(status);
    if (status.signInStatus) {
      this.setState({authState: true, userInfo: status.userInfo});
      console.log("You have logged in.");
    }
    else {
      this.setState({authState: false, userInfo: null});
      console.log("You havent logged in yet");
      this.context.createFirebaseWidget();
    }
  }

  componentDidMount() {
    console.log(this.context);
    this.context.getUserInfo().then( (status) => this.afterAuthStateCheck(status));

    //Example code: Read the db function
    this.context.db.collection('users').get().then((snapshot) => {
      snapshot.docs.forEach(doc => {
        console.log(doc.data());
      })
    });

    //Example code: Write to the db function
    this.context.db.collection('users').add({
      displayName: "memo",
      email: "memo@email.com"
    });

  }
  render () {
    console.log(this.state);
    const display = (this.state.authState)? "block" : "none";
    console.log(display);
    const displayObject = {display: display};
    return (

            <Button id="sign-out" style={displayObject}>Sign Out</Button>

Hello {this.state.userInfo}

    )
  }
}

export default App;<commit_msg>Delete debugging console log<commit_after>import React from 'react';
import './styles/App.css';
import {FirebaseContext} from './components/Firebase';
import {Button} from 'react-bootstrap';

class App extends React.Component {

  static contextType = FirebaseContext;
  constructor() {
    super();
    this.state = {authState: false, userInfo: null};
  }

  afterAuthStateCheck(status) {
    console.log(status);
    if (status.signInStatus) {
      this.setState({authState: true, userInfo: status.userInfo});
      console.log("You have logged in.");
    }
    else {
      this.setState({authState: false, userInfo: null});
      console.log("You havent logged in yet");
      this.context.createFirebaseWidget();
    }
  }

  componentDidMount() {
    console.log(this.context);
    this.context.getUserInfo().then( (status) => this.afterAuthStateCheck(status));

    //Example code: Read the db function
    this.context.db.collection('users').get().then((snapshot) => {
      snapshot.docs.forEach(doc => {
        console.log(doc.data());
      })
    });

    //Example code: Write to the db function
    this.context.db.collection('users').add({
      displayName: "memo",
      email: "memo@email.com"
    });

  }
  render () {

    const display = (this.state.authState)? "block" : "none";
    const displayObject = {display: display};
    return (

            <Button id="sign-out" style={displayObject}>Sign Out</Button>

Hello {this.state.userInfo}

    )
  }
}

export default App;<|endoftext|>


<commit_before>const request = require('superagent');
const { URL } = require('url');
const path = require('path');

/**
Get the title of a page from a URL quickly,but inaccurately. Allows both for URLs with a trailing
slash and for URLs without.

This is considered inaccurate because this function not handle redirects, e.g. /wiki/Cats and
/wiki/Cat are the same article but produce different outputs with this function.
*/
exports.getPageTitle = function getPageTitle(url) {
  const p = new URL(url).pathname;
  return path.basename(p);
}
<commit_msg>Add function for getPageName<commit_after>const request = require('superagent');
const { URL } = require('url');
const path = require('path');

const endpoint = 'https://en.wikipedia.org/w/api.php';

/**
Get the title of a page from a URL quickly,but inaccurately. Allows both for URLs with a trailing
slash and for URLs without.

This is considered inaccurate because this function not handle redirects, e.g. /wiki/Cats and
/wiki/Cat are the same article but produce different outputs with this function.
*/
exports.getPageTitle = function getPageTitle(url) {
  const p = new URL(url).pathname;
  return path.basename(p);
}

/**
Get the name of a Wikipedia page accurately by following redirects (slow)
*/
exports.getPageName = function getPageName(page) {
  return new Promise((resolve, reject) => {
    request
      .get(endpoint)
      .query({
        format: 'json',
        action: 'query',
        titles: page,
        redirects: 1,
      })
      .end((err, res) => {
        if (err) reject(err);
        else resolve(Object.values(res.body.query.pages)[0].title)
      })
  });
}
<|endoftext|>


<commit_before>"use strict";
var schedule;
if (typeof process === "object" && typeof process.version === "string") {
    schedule = parseInt(process.version.split(".")[1], 10) > 10
        ? global.setImmediate : process.nextTick;
}
else if (typeof MutationObserver !== "undefined") {
    schedule = function(fn) {
        var div = document.createElement("div");
        var observer = new MutationObserver(fn);
        observer.observe(div, {attributes: true});
        return function() { div.classList.toggle("foo"); };
    };
    schedule.isStatic = true;
}
else if (typeof setTimeout !== "undefined") {
    schedule = function (fn) {
        setTimeout(fn, 0);
    };
}
else {
    schedule = function() {
        throw new Error(NO_ASYNC_SCHEDULER);
    };
}
module.exports = schedule;
<commit_msg>Use setImmediate in iojs<commit_after>"use strict";
var schedule;
if (typeof process === "object" && typeof process.version === "string") {
    var version = process.version.split(".").map(Number);
    schedule = (version[0] === 0 && version[1] > 10) || (version[0] > 0)
        ? global.setImmediate : process.nextTick;
}
else if (typeof MutationObserver !== "undefined") {
    schedule = function(fn) {
        var div = document.createElement("div");
        var observer = new MutationObserver(fn);
        observer.observe(div, {attributes: true});
        return function() { div.classList.toggle("foo"); };
    };
    schedule.isStatic = true;
}
else if (typeof setTimeout !== "undefined") {
    schedule = function (fn) {
        setTimeout(fn, 0);
    };
}
else {
    schedule = function() {
        throw new Error(NO_ASYNC_SCHEDULER);
    };
}
module.exports = schedule;
<|endoftext|>


<commit_before>// game.js
// ========
"use strict";
module.exports = {
  map: function(size) {
   this.size = size || 70;
   function tile(properties) {
     //constructor
       if (properties.hasOwnProperty("x") && properties.hasOwnProperty("y")) {
           if(properties.x >= 0 && properties.y >= 0) {
             this.x = properties.x || 0;
             this.y = properties.y || 0;
           }
       }
     if (properties.hasOwnProperty("color")) {
         this.color = properties.color || "#ffffff";
     }
     if (properties.hasOwnProperty("kind")) {
       this.kind = null;
       switch (properties.Type) {
         case "floor":
         //floor
           this.kind = 0;
           break;
         default:
         //wall
         this.kind = 1;

       }
     }
     //Construct the list of items and players on the tile
     if (properties.hasOwnProperty("objects")) {
       this.objects =  new Array();
       if (Array.isArray(properties.objects)) {
           for (var i = 0; i < properties.objects.length; i++) {
             this.objects.push(properties.objects[i]);
           }
       }
     }
   }
   tile.prototype.getTile = function () {
    var color = "#ffffff";
    var objectKey = "";
    for (var key in this.objects) {
        color  = this.objects[key];
        objectKey =  key;
    }
    if (color === "#ffffff") {
        color = this.color;
    }
      return {
            "objects":objectKey,
            "color": color
      }
   };
   //create map
  this.mapArray = new Array();
   for (var i = 0; i < size; i++) {
     this.mapArray[i] =  new Array();
     for (var l = 0; l < size; l++) {
       var tileType = 0;
       var colorVal = "#ffffff";
       if ((i === 0) || (l === 0) || (i === this.size-1) || (l === this.size-1) ) {
         tileType = 1;
         colorVal = "#000000";
       }
      this.mapArray[i][l] = new tile({
         "x": i,
         "y": l,
         "color": colorVal,
         "objects": {},
         "kind": tileType
       });
     }
   }
 }
};
module.exports.map.prototype.getAbove = function (x,y) {
  console.log(mapArray.length)
 if (y > this.mapArray.length) {
    return mapArray[x][0];
  }
  if (y < 0) {
    return mapArray[x][mapArray.length];
  } else {
      return this.mapArray[x][y+1];
  }
};
module.exports.map.prototype.getBelow = function (x,y) {
 if (y > this.mapArray.length) {
    return mapArray[x][0];
  }
  if (y < 0) {
    return mapArray[x][mapArray.length];
  } else {
      return this.mapArray[x][y-1];
  }
};
module.exports.map.prototype.getRight = function (x,y) {
 if (x > this.mapArray.length) {
    return mapArray[0][y];
  }
  if (x < 0) {
    return mapArray[mapArray.length][y];
  } else {
      return this.mapArray[x+1][y];
  }
};
module.exports.map.prototype.getLeft = function (x,y) {
 if (x > this.mapArray.length) {
    return mapArray[0][y];
  }
  if (x < 0) {
    return mapArray[mapArray.length][y];
  } else {
      return this.mapArray[x-1][y];
  }
};
module.exports.map.prototype.getTile = function (x,y) {
return this.mapArray[x][y];
};
module.exports.map.prototype.setTile = function (x,y,element) {
 this.mapArray[x][y] = element;
};
module.exports.map.prototype.setPlayer = function (x,y,player) {
    function getRandomColor() {
     var letters = '0123456789ABCDEF'.split('');
     var color = '#';
     for (var i = 0; i < 6; i++ ) {
         color += letters[Math.floor(Math.random() * 16)];
     }
     return color;
   }
 this.mapArray[x][y].objects[String(player)] = getRandomColor();
};
module.exports.map.prototype.movePlayer = function (x,y,direction,player) {
  console.log(x,y,direction,player);
  console.log(this.mapArray[x][y].objects);
  //first verify that player is on the tile
  if (this.mapArray[x][y].objects.hasOwnProperty(String(player.username))) {
    switch(direction) {
    case "up":
    if( this.mapArray[x][y-1].kind != 1) {
     this.mapArray[x][y-1].objects[String(player.username)] = this.mapArray[x][y].objects[String(player.username)];
     delete this.mapArray[x][y].objects[String(player.username)]; // remove reference to player on previous tile

   }
        break;
    case "down":
    if( this.mapArray[x][y+1].kind != 1) {
     this.mapArray[x][y+1].objects[String(player.username)] = this.mapArray[x][y].objects[String(player.username)];
     delete this.mapArray[x][y].objects[String(player.username)]; // remove reference to player on previous tile

   }
        break;
    default:

}
  }
    console.log(x,y,direction,player);
};
module.exports.map.prototype.printMap = function() {
var mapVals = new Array();
  for (var i = 0; i < this.mapArray.length; i++) {
    mapVals[i] = [];
      for (var l = 0; l < this.mapArray[i].length; l++) {

            mapVals[i][l] = this.mapArray[i][l].getTile();

      }
  }
  return mapVals;
};
<commit_msg>fixed typos<commit_after>// game.js
// ========
"use strict";
module.exports = {
  map: function(size) {
   this.size = size || 70;
   function tile(properties) {
     //constructor
       if (properties.hasOwnProperty("x") && properties.hasOwnProperty("y")) {
           if(properties.x >= 0 && properties.y >= 0) {
             this.x = properties.x || 0;
             this.y = properties.y || 0;
           }
       }
     if (properties.hasOwnProperty("color")) {
         this.color = properties.color || "#ffffff";
     }
     if (properties.hasOwnProperty("kind")) {
       this.kind = null;
       switch (properties.Type) {
         case "floor":
         //floor
           this.kind = 0;
           break;
         default:
         //wall
         this.kind = 1;

       }
     }
     //Construct the list of items and players on the tile
     if (properties.hasOwnProperty("objects")) {
       this.objects =  new Array();
       if (Array.isArray(properties.objects)) {
           for (var i = 0; i < properties.objects.length; i++) {
             this.objects.push(properties.objects[i]);
           }
       }
     }
   }
   tile.prototype.getTile = function () {
    var color = "#ffffff";
    var objectKey = "";
    for (var key in this.objects) {
        color  = this.objects[key];
        objectKey =  key;
    }
    if (color === "#ffffff") {
        color = this.color;
    }
      return {
            "objects":objectKey,
            "color": color
      }
   };
   //create map
  this.mapArray = new Array();
   for (var i = 0; i < size; i++) {
     this.mapArray[i] =  new Array();
     for (var l = 0; l < size; l++) {
       var tileType = 0;
       var colorVal = "#ffffff";
       if ((i === 0) || (l === 0) || (i === this.size-1) || (l === this.size-1) ) {
         tileType = 1;
         colorVal = "#000000";
       }
      this.mapArray[i][l] = new tile({
         "x": i,
         "y": l,
         "color": colorVal,
         "objects": {},
         "kind": tileType
       });
     }
   }
 }
};
module.exports.map.prototype.getAbove = function (x,y) {
  console.log(this.mapArray.length)
 if (y > this.mapArray.length) {
    return this.mapArray[x][0];
  }
  if (y < 0) {
    return this.mapArray[x][this.mapArray.length];
  } else {
      return this.mapArray[x][y+1];
  }
};
module.exports.map.prototype.getBelow = function (x,y) {
 if (y > this.mapArray.length) {
    return this.mapArray[x][0];
  }
  if (y < 0) {
    return this.mapArray[x][this.mapArray.length];
  } else {
      return this.mapArray[x][y-1];
  }
};
module.exports.map.prototype.getRight = function (x,y) {
 if (x > this.mapArray.length) {
    return this.mapArray[0][y];
  }
  if (x < 0) {
    return this.mapArray[this.mapArray.length][y];
  } else {
      return this.mapArray[x+1][y];
  }
};
module.exports.map.prototype.getLeft = function (x,y) {
 if (x > this.mapArray.length) {
    return this.mapArray[0][y];
  }
  if (x < 0) {
    return this.mapArray[this.mapArray.length][y];
  } else {
      return this.mapArray[x-1][y];
  }
};
module.exports.map.prototype.getTile = function (x,y) {
return this.mapArray[x][y];
};
module.exports.map.prototype.setTile = function (x,y,element) {
 this.mapArray[x][y] = element;
};
module.exports.map.prototype.setPlayer = function (x,y,player) {
    function getRandomColor() {
     var letters = '0123456789ABCDEF'.split('');
     var color = '#';
     for (var i = 0; i < 6; i++ ) {
         color += letters[Math.floor(Math.random() * 16)];
     }
     return color;
   }
 this.mapArray[x][y].objects[String(player)] = getRandomColor();
};
module.exports.map.prototype.movePlayer = function (x,y,direction,player) {
  console.log(x,y,direction,player);
  console.log(this.mapArray[x][y].objects);
  //first verify that player is on the tile
  if (this.mapArray[x][y].objects.hasOwnProperty(String(player.username))) {
    switch(direction) {
    case "up":
    if( this.mapArray[x][y-1].kind != 1) {
     this.mapArray[x][y-1].objects[String(player.username)] = this.mapArray[x][y].objects[String(player.username)];
     delete this.mapArray[x][y].objects[String(player.username)]; // remove reference to player on previous tile

   }
        break;
    case "down":
    if( this.mapArray[x][y+1].kind != 1) {
     this.mapArray[x][y+1].objects[String(player.username)] = this.mapArray[x][y].objects[String(player.username)];
     delete this.mapArray[x][y].objects[String(player.username)]; // remove reference to player on previous tile

   }
        break;
    default:

}
  }
    console.log(x,y,direction,player);
};
module.exports.map.prototype.printMap = function() {
var mapVals = new Array();
  for (var i = 0; i < this.mapArray.length; i++) {
    mapVals[i] = [];
      for (var l = 0; l < this.mapArray[i].length; l++) {

            mapVals[i][l] = this.mapArray[i][l].getTile();

      }
  }
  return mapVals;
};
<|endoftext|>