<commit_before>var express = require('express');
var http = require('http');
var url = require('url');
var bodyParser = require('body-parser');
var app = express();
var pg = require('pg');
var port = process.env.PORT || 5000
var fs = require('fs');
var parse = require('csv-parse');
var async = require('async');
var multer  =   require('multer');
var csv = require("fast-csv");
var request = require('request');
var cheerio = require('cheerio');

var timeout = require('req-timeout');

express.timeout = timeout;
app.use(express.timeout(300000));

app.configure('development', function() {
  app.use(timeout(300000));
});

// timeout the request at 3 seconds
app.configure('production', function() {
  app.use(timeout(300000));
});

app.use(app.router);

var storage =   multer.diskStorage({
  destination: function (req, file, callback) {
    callback(null, './uploads');
  },
  filename: function (req, file, callback) {
    callback(null, 'lastuploadedfile.csv');
  }
});
var upload = multer({ storage : storage}).single('userPhoto');

app.use(bodyParser.urlencoded({extended:true}));
app.use(bodyParser.json());

app.all('*', function(req, res, next) {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Headers', 'X-Requested-With, Authorization, Content-Type');
  next();
});

app.listen(port);
app.timeout = 100000;
console.log('Listening at ' + port);
var records = [];

var inputFile='uploads/file.csv';
var totalLength = 0;
var counterLength = 0;

var parser = parse({delimiter: ','}, function (err, data) {
  console.log('Length: ' + data.length);
  totalLength = data.length;
  var datetime = new Date();
  // console.log(datetime);
  var csvStream = csv.createWriteStream({headers: true, quoteColumns: {'Product Description': true}}),
  writableStream = fs.createWriteStream("outputfiles/Output_" + datetime + ".csv");

  writableStream.on("finish", function(){
    console.log("DONE!");
  });

  csvStream.pipe(writableStream);
  counterLength = 0;

  async.eachSeries(data, function (line, callback) {

    var url = 'http://www.gmoutletparts.com/oe-gm/' + line[4];

    request(url, ( function(line) {
        return function(err, resp, body) {
            if (err)
                throw err;
            $ = cheerio.load(body);
            // TODO: scraping goes here!
            var salePrice = '0';
            var listPrice = '0';

            $('#product_price').each( function () {
                salePrice = $(this).text();
            });

            $('#product_price2').each( function () {
                listPrice = $(this).text();
            });

            //use old price
            if(salePrice == '0' || listPrice == '0'){
              // console.log('old price')
              salePrice = line[10];
              listPrice = line[12];
            }else{
              salePrice = salePrice.substring(1, salePrice.length);
              listPrice = listPrice.substring(1, listPrice.length);
              // console.log('new price::::', salePrice, listPrice);
            }

            if(line[0] != 'Item Type'){
              csvStream.write({
                'Item Type': line[0],
                'Product ID': line[1],
                'Product Name': line[2],
                'Product Type': line[3],
                'Product Code/SKU': line[4],
                'Bin Picking Number': line[5],
                'Brand Name': line[6],
                'Option Set': line[7],
                'Option Set Align': line[8],
                'Product Description': line[9],
                'Price': salePrice,
                'Cost Price': line[11],
                'Retail Price': listPrice,
                'Sale Price': line[13],
                'Fixed Shipping Cost': line[14],
                'Free Shipping': line[15],
                'Product Warranty': line[16],
                'Product Weight': line[17],
                'Product Width': line[18],
                'Product Height': line[19],
                'Product Depth': line[20],
                'Allow Purchases?': line[21],
                'Product Visible?': line[22],
                'Product Availability': line[23],
                'Track Inventory': line[24],
                'Current Stock Level': line[25],
                'Low Stock Level': line[26],
                'Category': line[27],
                'Product File - 1': line[28],
                'Product File Description - 1': line[29],
                'Product File Max Downloads - 1': line[30],
                'Product File Expires After - 1': line[31],
                'Product Image ID - 1': line[32],
                'Product Image File - 1': line[33],
                'Product Image Description - 1': line[34],
                'Product Image Is Thumbnail - 1': line[35],
                'Product Image Sort - 1': line[36],
                'Product Image ID - 2': line[37],
                'Product Image File - 2': line[38],
                'Product Image Description - 2': line[39],
                'Product Image Is Thumbnail - 2': line[40],
                'Product Image Sort - 2': line[41],
                'Product Image ID - 3': line[42],
                'Product Image File - 3': line[43],
                'Product Image Description - 3': line[44],
                'Product Image Is Thumbnail - 3': line[45],
                'Product Image Sort - 3': line[46],
                'Search Keywords': line[47],
                'Page Title': line[48],
                'Meta Keywords': line[49],
                'Meta Description': line[50],
                'MYOB Asset Acct': line[51],
                'MYOB Income Acct': line[52],
                'MYOB Expense Acct': line[53],
                'Product Condition': line[54],
                'Event Date Required?': line[55],
                'Event Date Name': line[56],
                'Event Date Is Limited?': line[57],
                'Event Date Start Date': line[58],
                'Event Date End Date': line[59],
                'Sort Order': line[60],
                'Product Tax Class': line[61],
                'Product UPC/EAN': line[62],
                'Stop Processing Rules': line[63],
                'Product URL': line[64],
                'Redirect Old URL?': line[65],
                'GPS Global Trade Item Number': line[66],
                'GPS Manufacturer Part Number': line[67],
                'GPS Gender': line[68],
                'GPS Age Group': line[69],
                'GPS Color': line[70],
                'GPS Size': line[71],
                'GPS Material': line[72],
                'GPS Pattern': line[73],
                'GPS Item Group ID': line[74],
                'GPS Category': line[75],
                'GPS Enabled': line[76],
                'Avalara Product Tax Code': line[77],
                'Product Custom Fields': line[78]
              });
              counterLength++;
              console.log(counterLength + ' of ' + (totalLength - 1));
              if(counterLength == totalLength - 1){
                csvStream.end();
              }
            }
        }
    } )(line));

    callback();
  });
}
);
// fs.createReadStream(inputFile).pipe(parser);
var dir = require('node-dir');

app.get('/getfiles',function(req,res){

  dir.files(__dirname+'/outputfiles', function(err, files) {
    if (err) throw err;

    res.json(files);
    console.log(files);

  });

});

var path = require('path');
var mime = require('mime');

app.get('/download', function(req, res){

  var file = __dirname + '/' + req.query.url;

  var filename = path.basename(file);
  var mimetype = mime.lookup(file);

  res.setHeader('Content-disposition', 'attachment; filename=' + filename);
  res.setHeader('Content-type', mimetype);

  var filestream = fs.createReadStream(file);
  filestream.pipe(res);
});

app.post('/upload',function(req,res){
    upload(req,res,function(err) {
        if(err) {
          console.log(err)
            res.redirect('http://localhost/GMOutletParts.github.io/upload.html?uploaded=false');
        }
        console.log('success...')
        records = [];

        var parser = parse({delimiter: ','}, function (err, data) {
        console.log('Length: ' + data.length);
        totalLength = data.length;
        var datetime = new Date();
        // console.log(datetime);
        var csvStream = csv.createWriteStream({headers: true, quoteColumns: {'Product Description': true}}),
        writableStream = fs.createWriteStream("outputfiles/Output_" + datetime + ".csv");

        writableStream.on("finish", function(){
          console.log("DONE!");
          res.redirect('http://localhost/GMOutletParts.github.io/showfiles.html?uploaded=' + (totalLength - 1));

        });

        csvStream.pipe(writableStream);
        counterLength = 0;

        async.eachSeries(data, function (line, callback) {

          var url = 'http://www.gmoutletparts.com/oe-gm/' + line[4];

          request(url, ( function(line) {
              return function(err, resp, body) {
                  if (err)
                      throw err;
                  $ = cheerio.load(body);
                  // TODO: scraping goes here!
                  var salePrice = '0';
                  var listPrice = '0';

                  $('#product_price').each( function () {
                      salePrice = $(this).text();
                  });

                  $('#product_price2').each( function () {
                      listPrice = $(this).text();
                  });

                  //use old price
                  if(salePrice == '0' || listPrice == '0'){
                    // console.log('old price')
                    salePrice = line[10];
                    listPrice = line[12];
                  }else{
                    salePrice = salePrice.substring(1, salePrice.length);
                    listPrice = listPrice.substring(1, listPrice.length);
                    // console.log('new price::::', salePrice, listPrice);
                  }

                  if(line[0] != 'Item Type'){
                    csvStream.write({
                      'Item Type': line[0],
                      'Product ID': line[1],
                      'Product Name': line[2],
                      'Product Type': line[3],
                      'Product Code/SKU': line[4],
                      'Bin Picking Number': line[5],
                      'Brand Name': line[6],
                      'Option Set': line[7],
                      'Option Set Align': line[8],
                      'Product Description': line[9],
                      'Price': salePrice,
                      'Cost Price': line[11],
                      'Retail Price': listPrice,
                      'Sale Price': line[13],
                      'Fixed Shipping Cost': line[14],
                      'Free Shipping': line[15],
                      'Product Warranty': line[16],
                      'Product Weight': line[17],
                      'Product Width': line[18],
                      'Product Height': line[19],
                      'Product Depth': line[20],
                      'Allow Purchases?': line[21],
                      'Product Visible?': line[22],
                      'Product Availability': line[23],
                      'Track Inventory': line[24],
                      'Current Stock Level': line[25],
                      'Low Stock Level': line[26],
                      'Category': line[27],
                      'Product File - 1': line[28],
                      'Product File Description - 1': line[29],
                      'Product File Max Downloads - 1': line[30],
                      'Product File Expires After - 1': line[31],
                      'Product Image ID - 1': line[32],
                      'Product Image File - 1': line[33],
                      'Product Image Description - 1': line[34],
                      'Product Image Is Thumbnail - 1': line[35],
                      'Product Image Sort - 1': line[36],
                      'Product Image ID - 2': line[37],
                      'Product Image File - 2': line[38],
                      'Product Image Description - 2': line[39],
                      'Product Image Is Thumbnail - 2': line[40],
                      'Product Image Sort - 2': line[41],
                      'Product Image ID - 3': line[42],
                      'Product Image File - 3': line[43],
                      'Product Image Description - 3': line[44],
                      'Product Image Is Thumbnail - 3': line[45],
                      'Product Image Sort - 3': line[46],
                      'Search Keywords': line[47],
                      'Page Title': line[48],
                      'Meta Keywords': line[49],
                      'Meta Description': line[50],
                      'MYOB Asset Acct': line[51],
                      'MYOB Income Acct': line[52],
                      'MYOB Expense Acct': line[53],
                      'Product Condition': line[54],
                      'Event Date Required?': line[55],
                      'Event Date Name': line[56],
                      'Event Date Is Limited?': line[57],
                      'Event Date Start Date': line[58],
                      'Event Date End Date': line[59],
                      'Sort Order': line[60],
                      'Product Tax Class': line[61],
                      'Product UPC/EAN': line[62],
                      'Stop Processing Rules': line[63],
                      'Product URL': line[64],
                      'Redirect Old URL?': line[65],
                      'GPS Global Trade Item Number': line[66],
                      'GPS Manufacturer Part Number': line[67],
                      'GPS Gender': line[68],
                      'GPS Age Group': line[69],
                      'GPS Color': line[70],
                      'GPS Size': line[71],
                      'GPS Material': line[72],
                      'GPS Pattern': line[73],
                      'GPS Item Group ID': line[74],
                      'GPS Category': line[75],
                      'GPS Enabled': line[76],
                      'Avalara Product Tax Code': line[77],
                      'Product Custom Fields': line[78]
                    });
                    counterLength++;
                    console.log(counterLength + ' of ' + (totalLength - 1));
                    if(counterLength == totalLength - 1){
                      csvStream.end();
                    }
                  }
              }
          } )(line));

          callback();
        });

    });
    fs.createReadStream(inputFile).pipe(parser);

  });
});

<commit_msg>extra timeout2<commit_after>var express = require('express');
var http = require('http');
var url = require('url');
var bodyParser = require('body-parser');
var app = express();
var pg = require('pg');
var port = process.env.PORT || 5000
var fs = require('fs');
var parse = require('csv-parse');
var async = require('async');
var multer  =   require('multer');
var csv = require("fast-csv");
var request = require('request');
var cheerio = require('cheerio');

var storage =   multer.diskStorage({
  destination: function (req, file, callback) {
    callback(null, './uploads');
  },
  filename: function (req, file, callback) {
    callback(null, 'lastuploadedfile.csv');
  }
});
var upload = multer({ storage : storage}).single('userPhoto');

app.use(bodyParser.urlencoded({extended:true}));
app.use(bodyParser.json());

app.all('*', function(req, res, next) {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Headers', 'X-Requested-With, Authorization, Content-Type');
  next();
});

app.listen(port);
app.timeout = 100000;
console.log('Listening at ' + port);
var records = [];

var inputFile='uploads/file.csv';
var totalLength = 0;
var counterLength = 0;

var parser = parse({delimiter: ','}, function (err, data) {
  console.log('Length: ' + data.length);
  totalLength = data.length;
  var datetime = new Date();
  // console.log(datetime);
  var csvStream = csv.createWriteStream({headers: true, quoteColumns: {'Product Description': true}}),
  writableStream = fs.createWriteStream("outputfiles/Output_" + datetime + ".csv");

  writableStream.on("finish", function(){
    console.log("DONE!");
  });

  csvStream.pipe(writableStream);
  counterLength = 0;

  async.eachSeries(data, function (line, callback) {

    var url = 'http://www.gmoutletparts.com/oe-gm/' + line[4];

    request(url, ( function(line) {
        return function(err, resp, body) {
            if (err)
                throw err;
            $ = cheerio.load(body);
            // TODO: scraping goes here!
            var salePrice = '0';
            var listPrice = '0';

            $('#product_price').each( function () {
                salePrice = $(this).text();
            });

            $('#product_price2').each( function () {
                listPrice = $(this).text();
            });

            //use old price
            if(salePrice == '0' || listPrice == '0'){
              // console.log('old price')
              salePrice = line[10];
              listPrice = line[12];
            }else{
              salePrice = salePrice.substring(1, salePrice.length);
              listPrice = listPrice.substring(1, listPrice.length);
              // console.log('new price::::', salePrice, listPrice);
            }

            if(line[0] != 'Item Type'){
              csvStream.write({
                'Item Type': line[0],
                'Product ID': line[1],
                'Product Name': line[2],
                'Product Type': line[3],
                'Product Code/SKU': line[4],
                'Bin Picking Number': line[5],
                'Brand Name': line[6],
                'Option Set': line[7],
                'Option Set Align': line[8],
                'Product Description': line[9],
                'Price': salePrice,
                'Cost Price': line[11],
                'Retail Price': listPrice,
                'Sale Price': line[13],
                'Fixed Shipping Cost': line[14],
                'Free Shipping': line[15],
                'Product Warranty': line[16],
                'Product Weight': line[17],
                'Product Width': line[18],
                'Product Height': line[19],
                'Product Depth': line[20],
                'Allow Purchases?': line[21],
                'Product Visible?': line[22],
                'Product Availability': line[23],
                'Track Inventory': line[24],
                'Current Stock Level': line[25],
                'Low Stock Level': line[26],
                'Category': line[27],
                'Product File - 1': line[28],
                'Product File Description - 1': line[29],
                'Product File Max Downloads - 1': line[30],
                'Product File Expires After - 1': line[31],
                'Product Image ID - 1': line[32],
                'Product Image File - 1': line[33],
                'Product Image Description - 1': line[34],
                'Product Image Is Thumbnail - 1': line[35],
                'Product Image Sort - 1': line[36],
                'Product Image ID - 2': line[37],
                'Product Image File - 2': line[38],
                'Product Image Description - 2': line[39],
                'Product Image Is Thumbnail - 2': line[40],
                'Product Image Sort - 2': line[41],
                'Product Image ID - 3': line[42],
                'Product Image File - 3': line[43],
                'Product Image Description - 3': line[44],
                'Product Image Is Thumbnail - 3': line[45],
                'Product Image Sort - 3': line[46],
                'Search Keywords': line[47],
                'Page Title': line[48],
                'Meta Keywords': line[49],
                'Meta Description': line[50],
                'MYOB Asset Acct': line[51],
                'MYOB Income Acct': line[52],
                'MYOB Expense Acct': line[53],
                'Product Condition': line[54],
                'Event Date Required?': line[55],
                'Event Date Name': line[56],
                'Event Date Is Limited?': line[57],
                'Event Date Start Date': line[58],
                'Event Date End Date': line[59],
                'Sort Order': line[60],
                'Product Tax Class': line[61],
                'Product UPC/EAN': line[62],
                'Stop Processing Rules': line[63],
                'Product URL': line[64],
                'Redirect Old URL?': line[65],
                'GPS Global Trade Item Number': line[66],
                'GPS Manufacturer Part Number': line[67],
                'GPS Gender': line[68],
                'GPS Age Group': line[69],
                'GPS Color': line[70],
                'GPS Size': line[71],
                'GPS Material': line[72],
                'GPS Pattern': line[73],
                'GPS Item Group ID': line[74],
                'GPS Category': line[75],
                'GPS Enabled': line[76],
                'Avalara Product Tax Code': line[77],
                'Product Custom Fields': line[78]
              });
              counterLength++;
              console.log(counterLength + ' of ' + (totalLength - 1));
              if(counterLength == totalLength - 1){
                csvStream.end();
              }
            }
        }
    } )(line));

    callback();
  });
}
);
// fs.createReadStream(inputFile).pipe(parser);
var dir = require('node-dir');

app.get('/getfiles',function(req,res){

  dir.files(__dirname+'/outputfiles', function(err, files) {
    if (err) throw err;

    res.json(files);
    console.log(files);

  });

});

var path = require('path');
var mime = require('mime');

app.get('/download', function(req, res){

  var file = __dirname + '/' + req.query.url;

  var filename = path.basename(file);
  var mimetype = mime.lookup(file);

  res.setHeader('Content-disposition', 'attachment; filename=' + filename);
  res.setHeader('Content-type', mimetype);

  var filestream = fs.createReadStream(file);
  filestream.pipe(res);
});

app.post('/upload',function(req,res){
    res.setTimeout(0);
    upload(req,res,function(err) {
        if(err) {
          console.log(err)
            res.redirect('http://localhost/GMOutletParts.github.io/upload.html?uploaded=false');
        }
        console.log('success...')
        records = [];

        var parser = parse({delimiter: ','}, function (err, data) {
        console.log('Length: ' + data.length);
        totalLength = data.length;
        var datetime = new Date();
        // console.log(datetime);
        var csvStream = csv.createWriteStream({headers: true, quoteColumns: {'Product Description': true}}),
        writableStream = fs.createWriteStream("outputfiles/Output_" + datetime + ".csv");

        writableStream.on("finish", function(){
          console.log("DONE!");
          res.redirect('http://localhost/GMOutletParts.github.io/showfiles.html?uploaded=' + (totalLength - 1));

        });

        csvStream.pipe(writableStream);
        counterLength = 0;

        async.eachSeries(data, function (line, callback) {

          var url = 'http://www.gmoutletparts.com/oe-gm/' + line[4];

          request(url, ( function(line) {
              return function(err, resp, body) {
                  if (err)
                      throw err;
                  $ = cheerio.load(body);
                  // TODO: scraping goes here!
                  var salePrice = '0';
                  var listPrice = '0';

                  $('#product_price').each( function () {
                      salePrice = $(this).text();
                  });

                  $('#product_price2').each( function () {
                      listPrice = $(this).text();
                  });

                  //use old price
                  if(salePrice == '0' || listPrice == '0'){
                    // console.log('old price')
                    salePrice = line[10];
                    listPrice = line[12];
                  }else{
                    salePrice = salePrice.substring(1, salePrice.length);
                    listPrice = listPrice.substring(1, listPrice.length);
                    // console.log('new price::::', salePrice, listPrice);
                  }

                  if(line[0] != 'Item Type'){
                    csvStream.write({
                      'Item Type': line[0],
                      'Product ID': line[1],
                      'Product Name': line[2],
                      'Product Type': line[3],
                      'Product Code/SKU': line[4],
                      'Bin Picking Number': line[5],
                      'Brand Name': line[6],
                      'Option Set': line[7],
                      'Option Set Align': line[8],
                      'Product Description': line[9],
                      'Price': salePrice,
                      'Cost Price': line[11],
                      'Retail Price': listPrice,
                      'Sale Price': line[13],
                      'Fixed Shipping Cost': line[14],
                      'Free Shipping': line[15],
                      'Product Warranty': line[16],
                      'Product Weight': line[17],
                      'Product Width': line[18],
                      'Product Height': line[19],
                      'Product Depth': line[20],
                      'Allow Purchases?': line[21],
                      'Product Visible?': line[22],
                      'Product Availability': line[23],
                      'Track Inventory': line[24],
                      'Current Stock Level': line[25],
                      'Low Stock Level': line[26],
                      'Category': line[27],
                      'Product File - 1': line[28],
                      'Product File Description - 1': line[29],
                      'Product File Max Downloads - 1': line[30],
                      'Product File Expires After - 1': line[31],
                      'Product Image ID - 1': line[32],
                      'Product Image File - 1': line[33],
                      'Product Image Description - 1': line[34],
                      'Product Image Is Thumbnail - 1': line[35],
                      'Product Image Sort - 1': line[36],
                      'Product Image ID - 2': line[37],
                      'Product Image File - 2': line[38],
                      'Product Image Description - 2': line[39],
                      'Product Image Is Thumbnail - 2': line[40],
                      'Product Image Sort - 2': line[41],
                      'Product Image ID - 3': line[42],
                      'Product Image File - 3': line[43],
                      'Product Image Description - 3': line[44],
                      'Product Image Is Thumbnail - 3': line[45],
                      'Product Image Sort - 3': line[46],
                      'Search Keywords': line[47],
                      'Page Title': line[48],
                      'Meta Keywords': line[49],
                      'Meta Description': line[50],
                      'MYOB Asset Acct': line[51],
                      'MYOB Income Acct': line[52],
                      'MYOB Expense Acct': line[53],
                      'Product Condition': line[54],
                      'Event Date Required?': line[55],
                      'Event Date Name': line[56],
                      'Event Date Is Limited?': line[57],
                      'Event Date Start Date': line[58],
                      'Event Date End Date': line[59],
                      'Sort Order': line[60],
                      'Product Tax Class': line[61],
                      'Product UPC/EAN': line[62],
                      'Stop Processing Rules': line[63],
                      'Product URL': line[64],
                      'Redirect Old URL?': line[65],
                      'GPS Global Trade Item Number': line[66],
                      'GPS Manufacturer Part Number': line[67],
                      'GPS Gender': line[68],
                      'GPS Age Group': line[69],
                      'GPS Color': line[70],
                      'GPS Size': line[71],
                      'GPS Material': line[72],
                      'GPS Pattern': line[73],
                      'GPS Item Group ID': line[74],
                      'GPS Category': line[75],
                      'GPS Enabled': line[76],
                      'Avalara Product Tax Code': line[77],
                      'Product Custom Fields': line[78]
                    });
                    counterLength++;
                    console.log(counterLength + ' of ' + (totalLength - 1));
                    if(counterLength == totalLength - 1){
                      csvStream.end();
                    }
                  }
              }
          } )(line));

          callback();
        });

    });
    fs.createReadStream(inputFile).pipe(parser);

  });
});

<|endoftext|>


<commit_before>module.exports = Channel;

var _ = require('lodash');
var EventEmitter = require('events').EventEmitter;
var inherits = require('util').inherits;
var path = require('path');

var noop = require('./noop');
var ServiceVdl = require('./chat/vdl/vdl');
var util = require('./util');

function Member(blessings, path) {
  this.name = util.firstShortName(blessings);
  this.path = path;
}

function memberNames(members) {
  return _.map(members, function(member) {
    return member.name;
  }).sort();
}

// Joins the specified channel, creating it if needed.
// Emits 'members', 'message', and 'ready' events.
function Channel(rt, channelName, cb) {
  cb = cb || noop;

  this.channelName_ = path.join('apps/chat', channelName);

  this.namespace_ = rt.namespace();
  this.context_ = rt.getContext();
  this.client_ = rt.newClient();
  this.server_ = rt.newServer();

  this.ee_ = new EventEmitter();
  this.ready_ = false;
  this.members_ = [];
  this.intervalID_ = null;  // initialized below

  var that = this;

  // Create our service implementation, which defines a single method:
  // "SendMessage".  We inherit from ServiceVdl.Chat which causes our defined
  // VDL types to be used when serializing values on the wire.  This is
  // necessary for the web client to be able to communicate with the shell
  // client.
  var Service = function() {
    ServiceVdl.Chat.call(this);
  };
  inherits(Service, ServiceVdl.Chat);

  // TODO(nlacasse): It's strange that I have to define "SendMessage" with a
  // capital "S" when I implement my RPC handler, but I have to call
  // "sendMessage" with a lower-case "s" when I actually make an RPC call.  This
  // should be more consistent.
  // See https://github.com/veyron/release-issues/issues/996
  Service.prototype.SendMessage = function(ctx, text) {
    that.ee_.emit('message', {
      sender: util.firstShortName(ctx.remoteBlessingStrings),
      text: text,
      timestamp: new Date()
    });
  };

  // Choose a random name to mount under.
  // TODO(nlacasse): Use mounttable ACLs to lock the name, and handle the case
  // that our chosen name is already in use (and locked) by choosing different
  // names until we find a free one.
  var serviceName = path.join(this.channelName_, util.randomHex('8'));

  // TODO(nlacasee,sadovsky): Our current authorization policy never returns any
  // errors, i.e. everyone is authorized!
  var openAuthorizer = function(){ return null; };
  var options = {authorizer: openAuthorizer};
  // Note, serve() performs the mount() for us.
  this.server_.serve(serviceName, new Service(), options, function(err) {
    if (err) return cb(err);
    // Use nextTick() for the first updateMembers_() call to give clients a
    // chance to set up their event listeners.
    process.nextTick(that.updateMembers_.bind(that));
    // TODO(sadovsky): Replace with mounttable glob watch.
    that.intervalID_ = setInterval(that.updateMembers_.bind(that), 2000);
    return cb();
  });
}

Channel.prototype.leave = function(cb) {
  cb = cb || noop;
  clearInterval(this.intervalID_);
  // TODO(sadovsky): Provide a public method to stop the server.
  this.server_.stop(cb);
};

Channel.prototype.broadcastMessage = function(messageText, cb) {
  var that = this;
  cb = cb || noop;
  // Schedule all messages to be sent, then return immediately.
  // TODO(sadovsky): Better error handling, perhaps?
  _.forEach(this.members_, function(member) {
    process.nextTick(function() {
      var ctx = that.context_.withTimeout(5000);
      // TODO(nlacasse): Make sure that the server we bindTo has the blessings
      // that we got when we globbed.  This will prevent some other member from
      // sneaking in with the same name as a recently-disconnected member and
      // getting messages meant for the first member.
      that.client_.bindTo(ctx, member.path, function(err, s) {
        if (err) {
          console.error(err);
          ctx.cancel();
        } else {
          s.sendMessage(ctx, messageText, function(err) {
            if (err) console.error(err);
            ctx.cancel();
          });
        }
      });
    });
  });
  return cb();
};

Channel.prototype.updateMembers_ = function() {
  var that = this;

  // We glob on the channel name to find all the members in our channel.  The
  // glob will return a stream of mount entries corresponding to the paths where
  // channel members are mounted.  Then, we get the remote blessings from each
  // member, and use those as the member names.

  var ctx = this.context_.withTimeout(1000);
  var pattern = path.join(this.channelName_, '*');

  // Start the glob rpc.  This returns a promise with a "stream" property.
  // Mount entries are emitted on the stream.
  var globRpc = this.namespace_.glob(ctx, pattern);
  var globStream = globRpc.stream;
  globRpc.catch(function(err) {
    console.error(err);
  });

  var newMembers = [];
  var doneGlobbing = false;
  var globResults = 0;

  function done(err) {
    if (err) console.error(err);
    doneGlobbing = true;
  }

  globStream.on('end', done);
  globStream.on('error', done);

  // Each time we get a mount entry, we request the remote blessings from the
  // server and use those and the path to create a new Member object.
  globStream.on('data', function(mountEntry) {
    globResults++;
    var path = mountEntry.name;

    // Request the remote blessings from the server.  This will make an RPC to
    // the server and return the blessings that the remote server used to
    // authenticate.  These blessings are cryptographically verified and can't
    // be forged by the remote server.
    that.client_.remoteBlessings(ctx, path, function(err, blessings) {
      if (err) {
        // Member has disconnected or is not responding.  Add a null so we can
        // keep track of how many glob results we have resolved.
        newMembers.push(null);
      } else {
        newMembers.push(new Member(blessings, path));
      }

      // If the glob stream is closed and we have constructed a Member object
      // for each glob result, then we are finished.
      if (doneGlobbing && newMembers.length === globResults) {
        // Remove the nulls.
        newMembers = _.filter(newMembers);

        // Get the member names for the old and new members and if they differ
        // emit a "members" event which the UI will use to update the members
        // list.
        var oldMemberNames = memberNames(that.members_);
        that.members_ = newMembers;
        var newMemberNames = memberNames(that.members_);
        if (!_.isEqual(oldMemberNames, newMemberNames)) {
          that.ee_.emit('members', newMemberNames);
        }

        if (!that.ready_) {
          that.ready_ = true;
          that.ee_.emit('ready');
        }
      }
    });
  });
};

Channel.prototype.addEventListener = function(event, listener) {
  this.ee_.addListener(event, listener);
  return this;
};

Channel.prototype.once = function(event, listener) {
  this.ee_.once(event, listener);
  return this;
};

Channel.prototype.on = Channel.prototype.addEventListener;

Channel.prototype.removeEventListener = function(event, listener) {
  this.ee_.removeListener(event, listener);
  return this;
};

Channel.prototype.off = Channel.prototype.removeEventListener;
<commit_msg>chat: lowercase service method name.<commit_after>module.exports = Channel;

var _ = require('lodash');
var EventEmitter = require('events').EventEmitter;
var inherits = require('util').inherits;
var path = require('path');

var noop = require('./noop');
var ServiceVdl = require('./chat/vdl/vdl');
var util = require('./util');

function Member(blessings, path) {
  this.name = util.firstShortName(blessings);
  this.path = path;
}

function memberNames(members) {
  return _.map(members, function(member) {
    return member.name;
  }).sort();
}

// Joins the specified channel, creating it if needed.
// Emits 'members', 'message', and 'ready' events.
function Channel(rt, channelName, cb) {
  cb = cb || noop;

  this.channelName_ = path.join('apps/chat', channelName);

  this.namespace_ = rt.namespace();
  this.context_ = rt.getContext();
  this.client_ = rt.newClient();
  this.server_ = rt.newServer();

  this.ee_ = new EventEmitter();
  this.ready_ = false;
  this.members_ = [];
  this.intervalID_ = null;  // initialized below

  var that = this;

  // Create our service implementation, which defines a single method:
  // "SendMessage".  We inherit from ServiceVdl.Chat which causes our defined
  // VDL types to be used when serializing values on the wire.  This is
  // necessary for the web client to be able to communicate with the shell
  // client.
  var Service = function() {
    ServiceVdl.Chat.call(this);
  };
  inherits(Service, ServiceVdl.Chat);

  Service.prototype.sendMessage = function(ctx, text) {
    that.ee_.emit('message', {
      sender: util.firstShortName(ctx.remoteBlessingStrings),
      text: text,
      timestamp: new Date()
    });
  };

  // Choose a random name to mount under.
  // TODO(nlacasse): Use mounttable ACLs to lock the name, and handle the case
  // that our chosen name is already in use (and locked) by choosing different
  // names until we find a free one.
  var serviceName = path.join(this.channelName_, util.randomHex('8'));

  // TODO(nlacasee,sadovsky): Our current authorization policy never returns any
  // errors, i.e. everyone is authorized!
  var openAuthorizer = function(){ return null; };
  var options = {authorizer: openAuthorizer};
  // Note, serve() performs the mount() for us.
  this.server_.serve(serviceName, new Service(), options, function(err) {
    if (err) return cb(err);
    // Use nextTick() for the first updateMembers_() call to give clients a
    // chance to set up their event listeners.
    process.nextTick(that.updateMembers_.bind(that));
    // TODO(sadovsky): Replace with mounttable glob watch.
    that.intervalID_ = setInterval(that.updateMembers_.bind(that), 2000);
    return cb();
  });
}

Channel.prototype.leave = function(cb) {
  cb = cb || noop;
  clearInterval(this.intervalID_);
  // TODO(sadovsky): Provide a public method to stop the server.
  this.server_.stop(cb);
};

Channel.prototype.broadcastMessage = function(messageText, cb) {
  var that = this;
  cb = cb || noop;
  // Schedule all messages to be sent, then return immediately.
  // TODO(sadovsky): Better error handling, perhaps?
  _.forEach(this.members_, function(member) {
    process.nextTick(function() {
      var ctx = that.context_.withTimeout(5000);
      // TODO(nlacasse): Make sure that the server we bindTo has the blessings
      // that we got when we globbed.  This will prevent some other member from
      // sneaking in with the same name as a recently-disconnected member and
      // getting messages meant for the first member.
      that.client_.bindTo(ctx, member.path, function(err, s) {
        if (err) {
          console.error(err);
          ctx.cancel();
        } else {
          s.sendMessage(ctx, messageText, function(err) {
            if (err) console.error(err);
            ctx.cancel();
          });
        }
      });
    });
  });
  return cb();
};

Channel.prototype.updateMembers_ = function() {
  var that = this;

  // We glob on the channel name to find all the members in our channel.  The
  // glob will return a stream of mount entries corresponding to the paths where
  // channel members are mounted.  Then, we get the remote blessings from each
  // member, and use those as the member names.

  var ctx = this.context_.withTimeout(1000);
  var pattern = path.join(this.channelName_, '*');

  // Start the glob rpc.  This returns a promise with a "stream" property.
  // Mount entries are emitted on the stream.
  var globRpc = this.namespace_.glob(ctx, pattern);
  var globStream = globRpc.stream;
  globRpc.catch(function(err) {
    console.error(err);
  });

  var newMembers = [];
  var doneGlobbing = false;
  var globResults = 0;

  function done(err) {
    if (err) console.error(err);
    doneGlobbing = true;
  }

  globStream.on('end', done);
  globStream.on('error', done);

  // Each time we get a mount entry, we request the remote blessings from the
  // server and use those and the path to create a new Member object.
  globStream.on('data', function(mountEntry) {
    globResults++;
    var path = mountEntry.name;

    // Request the remote blessings from the server.  This will make an RPC to
    // the server and return the blessings that the remote server used to
    // authenticate.  These blessings are cryptographically verified and can't
    // be forged by the remote server.
    that.client_.remoteBlessings(ctx, path, function(err, blessings) {
      if (err) {
        // Member has disconnected or is not responding.  Add a null so we can
        // keep track of how many glob results we have resolved.
        newMembers.push(null);
      } else {
        newMembers.push(new Member(blessings, path));
      }

      // If the glob stream is closed and we have constructed a Member object
      // for each glob result, then we are finished.
      if (doneGlobbing && newMembers.length === globResults) {
        // Remove the nulls.
        newMembers = _.filter(newMembers);

        // Get the member names for the old and new members and if they differ
        // emit a "members" event which the UI will use to update the members
        // list.
        var oldMemberNames = memberNames(that.members_);
        that.members_ = newMembers;
        var newMemberNames = memberNames(that.members_);
        if (!_.isEqual(oldMemberNames, newMemberNames)) {
          that.ee_.emit('members', newMemberNames);
        }

        if (!that.ready_) {
          that.ready_ = true;
          that.ee_.emit('ready');
        }
      }
    });
  });
};

Channel.prototype.addEventListener = function(event, listener) {
  this.ee_.addListener(event, listener);
  return this;
};

Channel.prototype.once = function(event, listener) {
  this.ee_.once(event, listener);
  return this;
};

Channel.prototype.on = Channel.prototype.addEventListener;

Channel.prototype.removeEventListener = function(event, listener) {
  this.ee_.removeListener(event, listener);
  return this;
};

Channel.prototype.off = Channel.prototype.removeEventListener;
<|endoftext|>


<commit_before>/*************************************************************
 *
 *  MathJax/extensions/TeX/mediawiki-texvc.js
 *
 *  Implements macros used by mediawiki with their texvc preprocessor.
 *
 *  ---------------------------------------------------------------------
 *
 *  Copyright (c) 2015-2016 The MathJax Consortium
 *
 *  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.
 */

MathJax.Extension["TeX/mediawiki-texvc"] = {
  version: "2.7.0"
};

MathJax.Hub.Register.StartupHook("TeX Jax Ready", function () {
  MathJax.InputJax.TeX.Definitions.Add({
    macros: {
      AA: ["Macro", "\u00c5"],
      alef: ["Macro", "\\aleph"],
      alefsym: ["Macro", "\\aleph"],
      Alpha: ["Macro", "\\mathrm{A}"],
      and: ["Macro", "\\land"],
      ang: ["Macro", "\\angle"],
      Bbb: ["Macro", "\\mathbb"],
      Beta: ["Macro", "\\mathrm{B}"],
      bold: ["Macro", "\\mathbf"],
      bull: ["Macro", "\\bullet"],
      C: ["Macro", "\\mathbb{C}"],
      Chi: ["Macro", "\\mathrm{X}"],
      clubs: ["Macro", "\\clubsuit"],
      cnums: ["Macro", "\\mathbb{C}"],
      Complex: ["Macro", "\\mathbb{C}"],
      coppa: ["Macro", "\u03D9"],
      Coppa: ["Macro", "\u03D8"],
      Dagger: ["Macro", "\\ddagger"],
      Digamma: ["Macro", "\u03DC"],
      darr: ["Macro", "\\downarrow"],
      dArr: ["Macro", "\\Downarrow"],
      Darr: ["Macro", "\\Downarrow"],
      diamonds: ["Macro", "\\diamondsuit"],
      empty: ["Macro", "\\emptyset"],
      Epsilon: ["Macro", "\\mathrm{E}"],
      Eta: ["Macro", "\\mathrm{H}"],
      euro: ["Macro", "\u20AC"],
      exist: ["Macro", "\\exists"],
      geneuro: ["Macro", "\u20AC"],
      geneuronarrow: ["Macro", "\u20AC"],
      geneurowide: ["Macro", "\u20AC"],
      H: ["Macro", "\\mathbb{H}"],
      hAar: ["Macro", "\\Leftrightarrow"],
      harr: ["Macro", "\\leftrightarrow"],
      Harr: ["Macro", "\\Leftrightarrow"],
      hearts: ["Macro", "\\heartsuit"],
      image: ["Macro", "\\Im"],
      infin: ["Macro", "\\infty"],
      Iota: ["Macro", "\\mathrm{I}"],
      isin: ["Macro", "\\in"],
      Kappa: ["Macro", "\\mathrm{K}"],
      koppa: ["Macro", "\u03DF"],
      Koppa: ["Macro", "\u03DE"],
      lang: ["Macro", "\\langle"],
      larr: ["Macro", "\\leftarrow"],
      Larr: ["Macro", "\\Leftarrow"],
      lArr: ["Macro", "\\Leftarrow"],
      lrarr: ["Macro", "\\leftrightarrow"],
      Lrarr: ["Macro", "\\Leftrightarrow"],
      lrArr: ["Macro", "\\Leftrightarrow"],
      Mu: ["Macro", "\\mathrm{M}"],
      N: ["Macro", "\\mathbb{N}"],
      natnums: ["Macro", "\\mathbb{N}"],
      Nu: ["Macro", "\\mathrm{N}"],
      O: ["Macro", "\\emptyset"],
      officialeuro: ["Macro", "\u20AC"],
      Omicron: ["Macro", "\\mathrm{O}"],
      or: ["Macro", "\\lor"],
      P: ["Macro", "\u00B6"],
      pagecolor: ['Macro','',1],  // ignore \pagecolor{}
      part: ["Macro", "\\partial"],
      plusmn: ["Macro", "\\pm"],
      Q: ["Macro", "\\mathbb{Q}"],
      R: ["Macro", "\\mathbb{R}"],
      rang: ["Macro", "\\rangle"],
      rarr: ["Macro", "\\rightarrow"],
      Rarr: ["Macro", "\\Rightarrow"],
      rArr: ["Macro", "\\Rightarrow"],
      real: ["Macro", "\\Re"],
      reals: ["Macro", "\\mathbb{R}"],
      Reals: ["Macro", "\\mathbb{R}"],
      Rho: ["Macro", "\\mathrm{P}"],
      sdot: ["Macro", "\\cdot"],
      sampi: ["Macro", "\u03E1"],
      Sampi: ["Macro", "\u03E0"],
      sect: ["Macro", "\\S"],
      spades: ["Macro", "\\spadesuit"],
      stigma: ["Macro", "\u03DB"],
      Stigma: ["Macro", "\u03DA"],
      sub: ["Macro", "\\subset"],
      sube: ["Macro", "\\subseteq"],
      supe: ["Macro", "\\supseteq"],
      Tau: ["Macro", "\\mathrm{T}"],
      textvisiblespace: ["Macro", "\u2423"],
      thetasym: ["Macro", "\\vartheta"],
      uarr: ["Macro", "\\uparrow"],
      uArr: ["Macro", "\\Uparrow"],
      Uarr: ["Macro", "\\Uparrow"],
      varcoppa: ["Macro", "\u03D9"],
      varstigma: ["Macro", "\u03DB"],
      vline: ['Macro','\\smash{\\large\\lvert}',0],
      weierp: ["Macro", "\\wp"],
      Z: ["Macro", "\\mathbb{Z}"],
      Zeta: ["Macro", "\\mathrm{Z}"]
    }
  });
});

MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/mediawiki-texvc.js");
<commit_msg>Add all macros currently supported by MediaWiki<commit_after>/*************************************************************
 *
 *  MathJax/extensions/TeX/mediawiki-texvc.js
 *
 *  Implements macros used by mediawiki with their texvc preprocessor.
 *
 *  ---------------------------------------------------------------------
 *
 *  Copyright (c) 2015-2016 The MathJax Consortium
 *
 *  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.
 */

MathJax.Extension["TeX/mediawiki-texvc"] = {
  version: "2.7.0"
};

MathJax.Hub.Register.StartupHook("TeX Jax Ready", function () {
  MathJax.InputJax.TeX.Definitions.Add({
    macros: {
      AA: ["Macro", "\u00c5"],
      alef: ["Macro", "\\aleph"],
      alefsym: ["Macro", "\\aleph"],
      Alpha: ["Macro", "\\mathrm{A}"],
      and: ["Macro", "\\land"],
      ang: ["Macro", "\\angle"],
      Bbb: ["Macro", "\\mathbb"],
      Beta: ["Macro", "\\mathrm{B}"],
      bold: ["Macro", "\\mathbf"],
      bull: ["Macro", "\\bullet"],
      C: ["Macro", "\\mathbb{C}"],
      Chi: ["Macro", "\\mathrm{X}"],
      clubs: ["Macro", "\\clubsuit"],
      cnums: ["Macro", "\\mathbb{C}"],
      Complex: ["Macro", "\\mathbb{C}"],
      coppa: ["Macro", "\u03D9"],
      Coppa: ["Macro", "\u03D8"],
      Dagger: ["Macro", "\\ddagger"],
      Digamma: ["Macro", "\u03DC"],
      darr: ["Macro", "\\downarrow"],
      dArr: ["Macro", "\\Downarrow"],
      Darr: ["Macro", "\\Downarrow"],
      diamonds: ["Macro", "\\diamondsuit"],
      empty: ["Macro", "\\emptyset"],
      Epsilon: ["Macro", "\\mathrm{E}"],
      Eta: ["Macro", "\\mathrm{H}"],
      euro: ["Macro", "\u20AC"],
      exist: ["Macro", "\\exists"],
      geneuro: ["Macro", "\u20AC"],
      geneuronarrow: ["Macro", "\u20AC"],
      geneurowide: ["Macro", "\u20AC"],
      H: ["Macro", "\\mathbb{H}"],
      hAar: ["Macro", "\\Leftrightarrow"],
      harr: ["Macro", "\\leftrightarrow"],
      Harr: ["Macro", "\\Leftrightarrow"],
      hearts: ["Macro", "\\heartsuit"],
      image: ["Macro", "\\Im"],
      infin: ["Macro", "\\infty"],
      Iota: ["Macro", "\\mathrm{I}"],
      isin: ["Macro", "\\in"],
      Kappa: ["Macro", "\\mathrm{K}"],
      koppa: ["Macro", "\u03DF"],
      Koppa: ["Macro", "\u03DE"],
      lang: ["Macro", "\\langle"],
      larr: ["Macro", "\\leftarrow"],
      Larr: ["Macro", "\\Leftarrow"],
      lArr: ["Macro", "\\Leftarrow"],
      lrarr: ["Macro", "\\leftrightarrow"],
      Lrarr: ["Macro", "\\Leftrightarrow"],
      lrArr: ["Macro", "\\Leftrightarrow"],
      Mu: ["Macro", "\\mathrm{M}"],
      N: ["Macro", "\\mathbb{N}"],
      natnums: ["Macro", "\\mathbb{N}"],
      Nu: ["Macro", "\\mathrm{N}"],
      O: ["Macro", "\\emptyset"],
      oint: ["Macro", "\u222E"],
      oiint: ["Macro", "\u222F"],
      oiiint: ["Macro", "\u2230"],
      ointctrclockwise: ["Macro", "\u2233"],
      officialeuro: ["Macro", "\u20AC"],
      Omicron: ["Macro", "\\mathrm{O}"],
      or: ["Macro", "\\lor"],
      P: ["Macro", "\u00B6"],
      pagecolor: ['Macro','',1],  // ignore \pagecolor{}
      part: ["Macro", "\\partial"],
      plusmn: ["Macro", "\\pm"],
      Q: ["Macro", "\\mathbb{Q}"],
      R: ["Macro", "\\mathbb{R}"],
      rang: ["Macro", "\\rangle"],
      rarr: ["Macro", "\\rightarrow"],
      Rarr: ["Macro", "\\Rightarrow"],
      rArr: ["Macro", "\\Rightarrow"],
      real: ["Macro", "\\Re"],
      reals: ["Macro", "\\mathbb{R}"],
      Reals: ["Macro", "\\mathbb{R}"],
      Rho: ["Macro", "\\mathrm{P}"],
      sdot: ["Macro", "\\cdot"],
      sampi: ["Macro", "\u03E1"],
      Sampi: ["Macro", "\u03E0"],
      sect: ["Macro", "\\S"],
      spades: ["Macro", "\\spadesuit"],
      stigma: ["Macro", "\u03DB"],
      Stigma: ["Macro", "\u03DA"],
      sub: ["Macro", "\\subset"],
      sube: ["Macro", "\\subseteq"],
      supe: ["Macro", "\\supseteq"],
      Tau: ["Macro", "\\mathrm{T}"],
      textvisiblespace: ["Macro", "\u2423"],
      thetasym: ["Macro", "\\vartheta"],
      uarr: ["Macro", "\\uparrow"],
      uArr: ["Macro", "\\Uparrow"],
      Uarr: ["Macro", "\\Uparrow"],
      varcoppa: ["Macro", "\u03D9"],
      varstigma: ["Macro", "\u03DB"],
      varointclockwise: ["Macro", "\u2232"],
      vline: ['Macro','\\smash{\\large\\lvert}',0],
      weierp: ["Macro", "\\wp"],
      Z: ["Macro", "\\mathbb{Z}"],
      Zeta: ["Macro", "\\mathrm{Z}"]
    }
  });
});

MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/mediawiki-texvc.js");
<|endoftext|>


<commit_before>
var _         = require("underscore")
, Screen_Name = require("../Screen_Name/model").Screen_Name
, Ok          = require('../Ok/model')
, log         = require("../App/base").log

, Topogo      = require("topogo").Topogo
, River       = require("da_river").River
, Check       = require('da_check').Check
;

var Room_Seat  = exports.Room_Seat = Ok.Model.new(function () {});
var MAX_TIME   = Room_Seat.MAX_TIME = 4;

var TABLE_NAME = exports.Room_Seat.TABLE_NAME = "Chat_Room_Seat";
var TABLE      = Topogo.new(TABLE_NAME);

Room_Seat._new = function () {
  var o = this;
  return o;
};

function null_if_empty(str) {
  if (!str) return null;
  str = str.trim();
  if (!str.length)
    return null;
  return str;
}

Room_Seat.prototype.max_time = function () {
  return MAX_TIME;
};

Room_Seat.prototype.public_data = function (o) {
  return _.pick(this.data, 'chat_room', 'owner', 'last_seen_at', 'is_empty' );
};

// ================================================================
// ================== Create ======================================
// ================================================================

Room_Seat.create_by_chat_room_and_owner = function (room, life, flow) {
  var where = {
    chat_room: room,
    owner    : life
  };

  River.new(flow)
  .job('read screen name', function (j) {
    Screen_Name.read_by_screen_name(room, j);
  })
  .job('create', function (j, screen_name) {
    if (!screen_name)
      return j.finish('invalid', "Chat room does not exist: " + room);

    TABLE
    .on_dup(TABLE_NAME + '_seat', function (name) {
      j.finish(null);
    })
    .create(where, j);
  })
  .job('read', function (j, row) {
    if (row)
      return j.finish(row);
    TABLE.read_one(where, j);
  })
  .job(function (j, row) {
    j.finish(Room_Seat.new(row));
  })
  .run();
};

Room_Seat.create_by_room = function (room, flow) {
  var data = {
    chat_room_id : room.data.id,
    screen_name_id: room.screen_name().customer().data.id
  };

                 // "UPDATE @table " +
              // "SET last_seen_at = $now " +
              // "WHERE chat_room_id = $",
              // "RETURNING * ;",
  River.new(flow)
  .job('update', function (j) {
    TABLE.update(data, {last_seen_at: '$now'}, j);
  })
  .job(function (j, rows) {
    if (rows.length > 0)
      return j.finish(rows[0]);

    TABLE.create(data, j);
  })
  .job(function (j, rec) {
    j.finish(Room_Seat.new(rec));
  })
  .run();
};

// ================================================================
// ================== Read ========================================
// ================================================================

Room_Seat.read_and_require_filled = function (chat_room, user, flow) {
  River.new(flow)
  .job('read', function (j) {
    TABLE
    .read_one({
      chat_room: chat_room,
      owner: user.screen_names(),
      is_empty: 'f'
    }, j);
  })
  .job('new obj', function (j, seat) {
    if (seat)
      return j.finish(Room_Seat.new(seat));
    j.finish('not_found', "You're not in the room: " + chat_room);
  })
  .run();
};

Room_Seat.read_by_room_and_screen_name_id = function (room, sn_id, flow) {
  var data = {
    chat_room_id: room.data.id,
    screen_name_id: sn_id
  };
  River.new(flow)
  .job('read', function (j) {
    TABLE.read_one(data, j);
  })
  .job('new obj', function (j, row) {
    if (!row)
      return j.finish(null);
    j.finish(Room_Seat.new(row));
  })
  .run();
};

Room_Seat.read_list_by_room = function (room, flow) {
  var now = (new Date).getTime();
  var target = now - (1000 * 3);

  var data = {
    chat_room_id: room.data.id
  };

  River.new(flow)

  .job('read seats', function (j) {
    TABLE.read_list(data, j);
  })

  .job('attach screen names', function (j, rows) {
    Screen_Name.replace_screen_names(rows, j);
  })

  .job('set old', function (j, rows) {
    j.finish(_.map(rows, function (r) {
      var is_out = !r.last_seen_at || (r.last_seen_at.getTime() < (target));
      return { screen_name: r.screen_name, is_out: is_out };
    }));
  })
  .run();
};

Room_Seat.read_list_for_customer = function (c, flow) {
  var names = _.map(c.screen_names(), function (n) {
    return {
      owner     : n,
      chat_room : n
    };
  });

  River.new(flow)
  .job('read seats', function (j) {
    TABLE
    .run( "\n\
         SELECT * FROM @table               \n\
         WHERE owner IN @owners             \n\
           AND chat_room NOT IN @owners     \n\
         ;", {owners: c.screen_names()}, j);
  })
  .job('map and reverse', function (j, records){
    j.finish(_.map(records, function (n) {
      return {
        owner     : n.owner,
        chat_room : n.chat_room
      };
    }).reverse());
  })
  .job('combine and return', function (j, rows) {
    j.finish(names.concat(rows));
  })
  .run();
};

// ================================================================
// ================== Update ======================================
// ================================================================
Room_Seat.enter = function (room, life, flow) {
  River.new(flow)
  .job('read', function (j) {
    TABLE
    .update_one({chat_room: room, owner: life},
            {last_seen_at: '$now', is_empty: 'f'}, j);
  })
  .job('create', function (j, row) {
    if (row)
      return j.finish(row);
    if (room !== life)
      return j.finish(null);

    // === If it does not not exist,
    //     leave this flow, create, then enter.
    River.new(flow)
    .job(function (j) {
      Room_Seat.create_by_chat_room_and_owner(room, life, j);
    })
    .job(function (j) {
      Room_Seat.enter(room, life, j);
    })
    .run();

  })
  .job(function (j, row) {
    j.finish(Room_Seat.new(row));
  })
  .run();
};

Room_Seat.leave = function (chat_room, life, flow) {
  River.new(flow)
  .job('update', function (j) {
    TABLE
    .update_one({
      chat_room: chat_room,
      owner: life
    }, {last_seen_at: '$now', is_empty: 't'}, j);
  })
  .run(function (j, row) {
    j.finish(Room_Seat.new(row));
  });
};

// ================================================================
// ================== Trash/Untrash ===============================
// ================================================================

// ================================================================
// ================== Delete ======================================
// ================================================================

<commit_msg>Dev. checkpoint.<commit_after>
var _         = require("underscore")
, Screen_Name = require("../Screen_Name/model").Screen_Name
, Ok          = require('../Ok/model')
, log         = require("../App/base").log

, Topogo      = require("topogo").Topogo
, River       = require("da_river").River
, Check       = require('da_check').Check
;

var Room_Seat  = exports.Room_Seat = Ok.Model.new(function () {});
var MAX_TIME   = Room_Seat.MAX_TIME = 4;

var TABLE_NAME = exports.Room_Seat.TABLE_NAME = "Chat_Room_Seat";
var TABLE      = Topogo.new(TABLE_NAME);

Room_Seat._new = function () {
  var o = this;
  return o;
};

function null_if_empty(str) {
  if (!str) return null;
  str = str.trim();
  if (!str.length)
    return null;
  return str;
}

Room_Seat.prototype.max_time = function () {
  return MAX_TIME;
};

Room_Seat.prototype.public_data = function (o) {
  return _.pick(this.data, 'chat_room', 'owner', 'last_seen_at', 'is_empty' );
};

// ================================================================
// ================== Create ======================================
// ================================================================

Room_Seat.create_by_chat_room_and_owner = function (room, life, flow) {
  var where = {
    chat_room: room,
    owner    : life
  };

  River.new(flow)
  .job('read screen name', function (j) {
    Screen_Name.read_by_screen_name(room, j);
  })
  .job('create', function (j, screen_name) {
    if (!screen_name)
      return j.finish('invalid', "Chat room does not exist: " + room);

    TABLE
    .on_dup(TABLE_NAME + '_seat', function (name) {
      j.finish(null);
    })
    .create(where, j);
  })
  .job('read', function (j, row) {
    if (row)
      return j.finish(row);
    TABLE.read_one(where, j);
  })
  .job(function (j, row) {
    j.finish(Room_Seat.new(row));
  })
  .run();
};

Room_Seat.create_by_room = function (room, flow) {
  var data = {
    chat_room_id : room.data.id,
    screen_name_id: room.screen_name().customer().data.id
  };

                 // "UPDATE @table " +
              // "SET last_seen_at = $now " +
              // "WHERE chat_room_id = $",
              // "RETURNING * ;",
  River.new(flow)
  .job('update', function (j) {
    TABLE.update(data, {last_seen_at: '$now'}, j);
  })
  .job(function (j, rows) {
    if (rows.length > 0)
      return j.finish(rows[0]);

    TABLE.create(data, j);
  })
  .job(function (j, rec) {
    j.finish(Room_Seat.new(rec));
  })
  .run();
};

// ================================================================
// ================== Read ========================================
// ================================================================

Room_Seat.read_and_require_filled = function (chat_room, user, flow) {
  River.new(flow)
  .job('read', function (j) {
    TABLE
    .read_one({
      chat_room: chat_room,
      owner: user.screen_names(),
      is_empty: 'f'
    }, j);
  })
  .job('new obj', function (j, seat) {
    if (seat)
      return j.finish(Room_Seat.new(seat));
    j.finish('not_found', "You're not in the room: " + chat_room);
  })
  .run();
};

Room_Seat.read_by_room_and_screen_name_id = function (room, sn_id, flow) {
  var data = {
    chat_room_id: room.data.id,
    screen_name_id: sn_id
  };
  River.new(flow)
  .job('read', function (j) {
    TABLE.read_one(data, j);
  })
  .job('new obj', function (j, row) {
    if (!row)
      return j.finish(null);
    j.finish(Room_Seat.new(row));
  })
  .run();
};

Room_Seat.read_list_by_room = function (room, flow) {
  var now = (new Date).getTime();
  var target = now - (1000 * 3);

  var data = {
    chat_room_id: room.data.id
  };

  River.new(flow)

  .job('read seats', function (j) {
    TABLE.read_list(data, j);
  })

  .job('set old', function (j, rows) {
    j.finish(_.map(rows, function (r) {
      var is_out = !r.last_seen_at || (r.last_seen_at.getTime() < (target));
      return { screen_name: r.screen_name, is_out: is_out };
    }));
  })
  .run();
};

Room_Seat.read_list_for_customer = function (c, flow) {
  var names = _.map(c.screen_names(), function (n) {
    return {
      owner     : n,
      chat_room : n
    };
  });

  River.new(flow)
  .job('read seats', function (j) {
    TABLE
    .run( "\n\
         SELECT * FROM @table               \n\
         WHERE owner IN @owners             \n\
           AND chat_room NOT IN @owners     \n\
         ;", {owners: c.screen_names()}, j);
  })
  .job('map and reverse', function (j, records){
    j.finish(_.map(records, function (n) {
      return {
        owner     : n.owner,
        chat_room : n.chat_room
      };
    }).reverse());
  })
  .job('combine and return', function (j, rows) {
    j.finish(names.concat(rows));
  })
  .run();
};

// ================================================================
// ================== Update ======================================
// ================================================================
Room_Seat.enter = function (room, life, flow) {
  River.new(flow)
  .job('read', function (j) {
    TABLE
    .update_one({chat_room: room, owner: life},
            {last_seen_at: '$now', is_empty: 'f'}, j);
  })
  .job('create', function (j, row) {
    if (row)
      return j.finish(row);
    if (room !== life)
      return j.finish(null);

    // === If it does not not exist,
    //     leave this flow, create, then enter.
    River.new(flow)
    .job(function (j) {
      Room_Seat.create_by_chat_room_and_owner(room, life, j);
    })
    .job(function (j) {
      Room_Seat.enter(room, life, j);
    })
    .run();

  })
  .job(function (j, row) {
    j.finish(Room_Seat.new(row));
  })
  .run();
};

Room_Seat.leave = function (chat_room, life, flow) {
  River.new(flow)
  .job('update', function (j) {
    TABLE
    .update_one({
      chat_room: chat_room,
      owner: life
    }, {last_seen_at: '$now', is_empty: 't'}, j);
  })
  .run(function (j, row) {
    j.finish(Room_Seat.new(row));
  });
};

// ================================================================
// ================== Trash/Untrash ===============================
// ================================================================

// ================================================================
// ================== Delete ======================================
// ================================================================

<|endoftext|>


<commit_before>import moment from 'moment'

import manager from '../manager'
import auth, {authComplete} from '../auth'
import AlarmAct from '../acts/Alarm'

import Alarm from './Alarm'

const init = async () => {
  await Alarm.clearAll()

  const {hours: hour, minutes: minute, seconds: second} = moment().add(2, 's').toObject()
  // const [hour, minute, second] = [7, 30, 0]

  const testAlarm = new Alarm({
    name: 'Test 1',
    scheduleDescriptor: {hour, minute, second}
  })
  await testAlarm.save()

  const alarms = await Alarm.fromDB()
  const scheduledAlarms = alarms.map(alarm => alarm.schedule(() => manager.connect(new AlarmAct(alarm))))

  console.log('Alarms will trigger at', scheduledAlarms.map(alarm => alarm.scheduleDescriptor))
}

// If auth was blocking, init alarms once complete
auth.once(authComplete, init())

export default init
export {Alarm}
<commit_msg>🐛 Only init once<commit_after>import moment from 'moment'

import manager from '../manager'
import auth, {authComplete} from '../auth'
import AlarmAct from '../acts/Alarm'

import Alarm from './Alarm'

let hasInit = false

const init = async () => {
  // Ensure only triggered once
  if(hasInit) return
  hasInit = true

  await Alarm.clearAll()

  const {hours: hour, minutes: minute, seconds: second} = moment().add(2, 's').toObject()
  // const [hour, minute, second] = [7, 30, 0]

  const testAlarm = new Alarm({
    name: 'Test 1',
    scheduleDescriptor: {hour, minute, second}
  })
  await testAlarm.save()

  const alarms = await Alarm.fromDB()
  const scheduledAlarms = alarms.map(alarm => alarm.schedule(() => manager.connect(new AlarmAct(alarm))))

  console.log('Alarms will trigger at', scheduledAlarms.map(alarm => alarm.scheduleDescriptor))
}

// If auth was blocking, init alarms once complete
auth.once(authComplete, init())

export default init
export {Alarm}
<|endoftext|>


<commit_before>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?",
  "Merge in master",
  "Fast-forwarding changes"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (inFile == outFile) {
    console.error("Aborted: infile and outfile must be different")
    return(-1);
  }
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  if (process.argv [ 5 ]) step = parseInt(process.argv [ 5 ])
  console.info("Writing from %s to %s, with up to %s seconds between commits of %s bytes", inFile, outFile, max_sleep, step)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    var commit_count = Math.ceil(length / step)
    var commit_time = commit_count * max_sleep / 2
    var commit_time_hour = Math.floor(commit_time / 3600)
    var commit_time_rem = commit_time - (commit_time_hour * 3600)
    var commit_time_min = Math.floor(commit_time_rem / 60)
    var commit_time_sec = commit_time_rem - (commit_time_min * 60)
    console.info("Input file is %s Bytes, this will generate %s commits and take approximately %s hours %s minutes %s seconds", length, commit_count, commit_time_hour, commit_time_min, commit_time_sec)
    var t_offset = 0
    if (process.env.FAKETIME) {
      // 20% buffer, to reduce the likelihood of going in to the future
      t_offset = commit_time * -1.2;
      faketime(t_offset);
    }
    try {
      child_process.execFileSync('git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile, e)
    }
    var counter = 0
    process.stdout.write("Queueing up the first commit...\r");
    var timeout;
    if (process.env.FAKETIME) {
      faketime(t_offset);
      timeout = 20;
    } else {
      timeout = randomIntFromInterval(0, max_sleep) * 1000
    }
    setTimeout(commit, timeout, t_offset, outFD, outFile, data, counter, length);
  })
} else {
  console.info("Usage:")
  console.info("node commit.js infile outfile [max_time_in_seconds] <commit_msg>Fast-forwarding changes<commit_after>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?",
  "Merge in master",
  "Fast-forwarding changes"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (inFile == outFile) {
    console.error("Aborted: infile and outfile must be different")
    return(-1);
  }
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  if (process.argv [ 5 ]) step = parseInt(process.argv [ 5 ])
  console.info("Writing from %s to %s, with up to %s seconds between commits of %s bytes", inFile, outFile, max_sleep, step)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    var commit_count = Math.ceil(length / step)
    var commit_time = commit_count * max_sleep / 2
    var commit_time_hour = Math.floor(commit_time / 3600)
    var commit_time_rem = commit_time - (commit_time_hour * 3600)
    var commit_time_min = Math.floor(commit_time_rem / 60)
    var commit_time_sec = commit_time_rem - (commit_time_min * 60)
    console.info("Input file is %s Bytes, this will generate %s commits and take approximately %s hours %s minutes %s seconds", length, commit_count, commit_time_hour, commit_time_min, commit_time_sec)
    var t_offset = 0
    if (process.env.FAKETIME) {
      // 20% buffer, to reduce the likelihood of going in to the future
      t_offset = commit_time * -1.2;
      faketime(t_offset);
    }
    try {
      child_process.execFileSync('git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile, e)
    }
    var counter = 0
    process.stdout.write("Queueing up the first commit...\r");
    var timeout;
    if (process.env.FAKETIME) {
      faketime(t_offset);
      timeout = 20;
    } else {
      timeout = randomIntFromInterval(0, max_sleep) * 1000
    }
    setTimeout(commit, timeout, t_offset, outFD, outFile, data, counter, length);
  })
} else {
  console.info("Usage:")
  console.info("node commit.js infile outfile [max_time_in_seconds] [<|endoftext|>


<commit_before>/* Webconverger.com
*/

pref("browser.startup.homepage", "http://portal.webconverger.com");
pref("accessibility.typeaheadfind.flashBar", 0);
pref("app.update.enabled", false);
pref("browser.download.dir", "/tmp");
pref("browser.download.downloadDir", "/tmp");
pref("browser.download.folderList", 2);
pref("browser.download.lastDir", "/tmp");
pref("browser.history_expire_days.mirror", 1);
pref("browser.preferences.advanced.selectedTabIndex", 2);
pref("browser.startup.homepage_override.mstone", "rv:1.8.1.3");
pref("browser.startup.page", 3);
pref("browser.tabs.autoHide", false);
pref("browser.tabs.closeButtons", 3);
pref("browser.tabs.tabMinWidth", 0);
pref("browser.tabs.warnOnClose", false);
pref("browser.tabs.warnOnOpen", false);
pref("browser.urlbar.hideGoButton", true);
pref("network.cookie.prefsMigrated", true);
pref("pref.advanced.javascript.disable_button.advanced", false);
pref("pref.privacy.disable_button.view_cookies", false);
pref("security.warn_entering_secure", false);
pref("security.warn_leaving_secure", false);
pref("security.warn_submit_insecure", false);
pref("signon.rememberSignons", false);

// This is the Webconverger specific preferences file for Iceweasel
// You can make any change in here, it is the purpose of this file.
// You can, with this file and all files present in the
// /etc/iceweasel/pref directory, override any preference that is
// present in /usr/lib/iceweasel/defaults/pref directory.
// While your changes will be kept on upgrade if you modify files in
// /etc/iceweasel/pref, please note that they won't be kept if you
// do them in /usr/lib/iceweasel/defaults/pref.

// Update via APT
pref("extensions.update.enabled", false);

// Use LANG environment variable to choose locale
pref("intl.locale.matchOS", true);

// Disable default browser checking.
pref("browser.shell.checkDefaultBrowser", false);

// Make sure new windows open in a tab
pref("browser.link.open_newwindow", 3);
pref("browser.link.open_external",3);
pref("browser.link.open_newwindow.restriction", 0);

// COMMENT OUT to disable print dialog
// pref("print.always_print_silent",true);
// pref("print.show_print_progress",false);

// This should be set at /etc/iceweasel/pref/iceweasel.js
//pref("rkiosk.navbar", true);

// BETA Spell check all fields
pref("layout.spellcheck.default", 2)
<commit_msg>Ignore update screens<commit_after>/* Webconverger.com
*/

pref("browser.startup.homepage", "http://portal.webconverger.com");
pref("accessibility.typeaheadfind.flashBar", 0);
pref("app.update.enabled", false);
pref("browser.download.dir", "/tmp");
pref("browser.download.downloadDir", "/tmp");
pref("browser.download.folderList", 2);
pref("browser.download.lastDir", "/tmp");
pref("browser.history_expire_days.mirror", 1);
pref("browser.preferences.advanced.selectedTabIndex", 2);
pref("browser.startup.homepage_override.mstone", "ignore");
pref("browser.startup.page", 3);
pref("browser.tabs.autoHide", false);
pref("browser.tabs.closeButtons", 3);
pref("browser.tabs.tabMinWidth", 0);
pref("browser.tabs.warnOnClose", false);
pref("browser.tabs.warnOnOpen", false);
pref("browser.urlbar.hideGoButton", true);
pref("network.cookie.prefsMigrated", true);
pref("pref.advanced.javascript.disable_button.advanced", false);
pref("pref.privacy.disable_button.view_cookies", false);
pref("security.warn_entering_secure", false);
pref("security.warn_leaving_secure", false);
pref("security.warn_submit_insecure", false);
pref("signon.rememberSignons", false);

// This is the Webconverger specific preferences file for Iceweasel
// You can make any change in here, it is the purpose of this file.
// You can, with this file and all files present in the
// /etc/iceweasel/pref directory, override any preference that is
// present in /usr/lib/iceweasel/defaults/pref directory.
// While your changes will be kept on upgrade if you modify files in
// /etc/iceweasel/pref, please note that they won't be kept if you
// do them in /usr/lib/iceweasel/defaults/pref.

// Update via APT
pref("extensions.update.enabled", false);

// Use LANG environment variable to choose locale
pref("intl.locale.matchOS", true);

// Disable default browser checking.
pref("browser.shell.checkDefaultBrowser", false);

// Make sure new windows open in a tab
pref("browser.link.open_newwindow", 3);
pref("browser.link.open_external",3);
pref("browser.link.open_newwindow.restriction", 0);

// COMMENT OUT to disable print dialog
// pref("print.always_print_silent",true);
// pref("print.show_print_progress",false);

// This should be set at /etc/iceweasel/pref/iceweasel.js
//pref("rkiosk.navbar", true);

// BETA Spell check all fields
pref("layout.spellcheck.default", 2)
<|endoftext|>


<commit_before>OpenSprites.models = {};

OpenSprites.models.BaseModel = function(_target){
	var modelObj = {};
	modelObj._target = _target;
	modelObj.loadJson = function(json){

	};
	return modelObj;
};

OpenSprites.models.AssetList = function(_target){
	var modelObj = OpenSprites.models.BaseModel(_target); // attempting a java-class-like structure
	modelObj.loadJson = function(json){
		modelObj._target.html("");
		for(var i = 0;i<json.length;i++) {
			var html = $("
").addClass("file").addClass(json[i].type).attr("data-name", json[i].name).attr("data-utime", json[i].upload_time);
			if(json[i].type == "image"){
				html.css("background-image", "url("+OpenSprites.domain + json[i].url+")");
			}
        		modelObj._target.append(html);
		}
	};
	return modelObj;
};

OpenSprites.models.SortableAssetList = function(_target){
	var modelObj = OpenSprites.models.BaseModel(_target);

	var listing = $('
Loading...
);
	var subModel = OpenSprites.models.AssetList(listing);
	function loadAssetList(sort, max, type){
		$.get(OpenSprites.domain + "/site-api/list.php?sort="+sort+"&max="+max+"&type="+type, function(data){
			subModel.loadJson(data);
		});
	}
	loadAssetList("popularity", 15, "all");

	var orderBy = {
		popularity: "Popularity",
		alphabetical: "A-Z",
		newest: "Newest",
		oldest: "Oldest"
	};
	var types = {
		all: "All",
		image: "Costumes",
		sound: "Sounds",
		script: "Scripts"
	};

	var buttonSetClick = function(){
		$(this).parent().find("button").removeClass("selected");
		$(this).addClass("selected");
	};

	var sortButtons = $('
Sort by:
');
	for(key in orderBy){
		var button = $("<button>").attr("data-for", key).click(function(){
			listing.attr("data-sort", key);
			loadAssetList(key, 15, listing.attr("data-type"));
		}).click(buttonSetClick);
		button.text(orderBy[key]);
		if(key == "popularity") button.addClass("selected");
		sortButtons.append(button);
	}
	var typesByttons = $('
Types:
');
	for(key in types){
		var button = $("<button>").attr("data-for", key).click(function(){
			listing.attr("data-type", key);
			loadAssetList(listing.attr("data-sort"), 15, key);
		}).click(buttonSetClick);
		button.text(types[key]);
		if(key == "all") button.addClass("selected");
		typesButtons.append(button);
	}

	_target.html('').append(sortButtons).append(typesButtons).append("
").append(listing);

	return modelObj;
};
<commit_msg>Update models.js<commit_after>OpenSprites.models = {};

OpenSprites.models.BaseModel = function(_target){
	var modelObj = {};
	modelObj._target = _target;
	modelObj.loadJson = function(json){

	};
	return modelObj;
};

OpenSprites.models.AssetList = function(_target){
	var modelObj = OpenSprites.models.BaseModel(_target); // attempting a java-class-like structure
	modelObj.loadJson = function(json){
		modelObj._target.html("");
		console.log(modelObj._target);
		for(var i = 0;i<json.length;i++) {
			var html = $("
").addClass("file").addClass(json[i].type).attr("data-name", json[i].name).attr("data-utime", json[i].upload_time);
			if(json[i].type == "image"){
				html.css("background-image", "url("+OpenSprites.domain + json[i].url+")");
			}
        		modelObj._target.append(html);
		}
	};
	return modelObj;
};

OpenSprites.models.SortableAssetList = function(_target){
	var modelObj = OpenSprites.models.BaseModel(_target);

	var listing = $('
Loading...
);
	var subModel = OpenSprites.models.AssetList(listing);
	function loadAssetList(sort, max, type){
		$.get(OpenSprites.domain + "/site-api/list.php?sort="+sort+"&max="+max+"&type="+type, function(data){
			subModel.loadJson(data);
		});
	}
	loadAssetList("popularity", 15, "all");

	var orderBy = {
		popularity: "Popularity",
		alphabetical: "A-Z",
		newest: "Newest",
		oldest: "Oldest"
	};
	var types = {
		all: "All",
		image: "Costumes",
		sound: "Sounds",
		script: "Scripts"
	};

	var buttonSetClick = function(){
		$(this).parent().find("button").removeClass("selected");
		$(this).addClass("selected");
	};

	var sortButtons = $('
Sort by:
');
	for(key in orderBy){
		var button = $("<button>").attr("data-for", key).click(function(){
			listing.attr("data-sort", key);
			loadAssetList(key, 15, listing.attr("data-type"));
		}).click(buttonSetClick);
		button.text(orderBy[key]);
		if(key == "popularity") button.addClass("selected");
		sortButtons.append(button);
	}
	var typesByttons = $('
Types:
');
	for(key in types){
		var button = $("<button>").attr("data-for", key).click(function(){
			listing.attr("data-type", key);
			loadAssetList(listing.attr("data-sort"), 15, key);
		}).click(buttonSetClick);
		button.text(types[key]);
		if(key == "all") button.addClass("selected");
		typesButtons.append(button);
	}

	_target.html('').append(sortButtons).append(typesButtons).append("
").append(listing);

	return modelObj;
};
<|endoftext|>


<commit_before>import fs from 'fs';
import path from 'path';
import { promisify } from 'util';
import gzipSize from 'gzip-size';
import prettyBytes from 'pretty-bytes';
import cheerio from 'cheerio';
import highlight from 'highlight.js';
import metalsmith from 'metalsmith';
import ignore from 'metalsmith-ignore';
import markdown from 'metalsmith-markdown';
import handlebars from 'handlebars';
import pkg from '../../package.json';

// Configure Highlight.js
highlight.configure({ classPrefix: '' });
const hljs = (code, lang) => !lang ? highlight.highlightAuto(code).value : highlight.highlight(lang, code).value;

function concatFiles(files, metalsmith, done) {
  setImmediate(done);

  const regexMatch = /^(\d+)-/i
      , fileNames = Object.keys(files).filter(name => regexMatch.test(name)).sort()

  let combined = fileNames
    .map(name => ({ name, file: files[name] }))
    .reduce(({ name, file }, { file: nextFile }) => {
      file.contents = new Buffer([file.contents.toString(), `<section>${nextFile.contents.toString()}</section>`].join('\n'));
      return { name, file };
    });

  let { name, file } = combined;
  files[name.replace(regexMatch, '')] = file;

  fileNames.forEach(name => {
    delete files[name];
  });
}

function tableOfContents(files) {
  Object.keys(files).forEach(name => {
    let file = files[name]
      , toc = '';

    if(!file.toc) return;

    let $ = cheerio.load(file.contents.toString())
      , sections = $('h3[id]');

    sections.each(function() {
      let $that = $(this);
      toc += `<li><a href="#${$that.attr('id')}">${$that.text()}</a></li>`;
    });

    file.toc = `<ul>${toc}</ul>`;
  });
}

async function layout(files, metadata) {
  let layout = await promisify(fs.readFile)(path.resolve(__dirname, './layouts/index.hbs'))
    , compiledLayout = handlebars.compile(layout.toString());

  Object.keys(files).forEach(name => files[name].contents = new Buffer(compiledLayout(Object.assign({}, metadata, { contents: files[name].contents }))));
}

async function hbs(files, metalsmith) {
  let metadata = metalsmith.metadata();

  Object.keys(files).forEach(name => {
    let file = files[name]
      , compiled = handlebars.compile(file.contents.toString());
    files[name].contents = new Buffer(compiled(Object.assign({}, metadata, file)));
  });
}

(async () => {
  metalsmith(path.resolve(__dirname, '../'))
    .source('.')
    .use(ignore('src/**/*'))
    .metadata({
      title: 'currency.js',
      description: pkg.description,
      version: pkg.version,
      dist: pkg.browser,
      size: prettyBytes(await gzipSize.file(path.resolve(__dirname, '../../', pkg.browser)))
    })
    .use(markdown({
      highlight: hljs
    }))
    .use(tableOfContents)
    .use(hbs)
    .use(concatFiles)
    .use(layout)
    .build(err => {
      if(err) throw err;
    });
})();<commit_msg>fix linting<commit_after>import fs from 'fs';
import path from 'path';
import { promisify } from 'util';
import gzipSize from 'gzip-size';
import prettyBytes from 'pretty-bytes';
import cheerio from 'cheerio';
import highlight from 'highlight.js';
import metalsmith from 'metalsmith';
import ignore from 'metalsmith-ignore';
import markdown from 'metalsmith-markdown';
import handlebars from 'handlebars';
import pkg from '../../package.json';

// Configure Highlight.js
highlight.configure({ classPrefix: '' });
const hljs = (code, lang) => !lang ? highlight.highlightAuto(code).value : highlight.highlight(lang, code).value;

function concatFiles(files, metalsmith, done) {
  setImmediate(done);

  const regexMatch = /^(\d+)-/i
      , fileNames = Object.keys(files).filter(name => regexMatch.test(name)).sort();

  let combined = fileNames
    .map(name => ({ name, file: files[name] }))
    .reduce(({ name, file }, { file: nextFile }) => {
      file.contents = new Buffer([file.contents.toString(), `<section>${nextFile.contents.toString()}</section>`].join('\n'));
      return { name, file };
    });

  let { name, file } = combined;
  files[name.replace(regexMatch, '')] = file;

  fileNames.forEach(name => {
    delete files[name];
  });
}

function tableOfContents(files) {
  Object.keys(files).forEach(name => {
    let file = files[name]
      , toc = '';

    if(!file.toc) {
      return;
    }

    let $ = cheerio.load(file.contents.toString())
      , sections = $('h3[id]');

    sections.each(function() {
      let $that = $(this);
      toc += `<li><a href="#${$that.attr('id')}">${$that.text()}</a></li>`;
    });

    file.toc = `<ul>${toc}</ul>`;
  });
}

async function layout(files, metadata) {
  let layout = await promisify(fs.readFile)(path.resolve(__dirname, './layouts/index.hbs'))
    , compiledLayout = handlebars.compile(layout.toString());

  Object.keys(files).forEach(name => files[name].contents = new Buffer(compiledLayout(Object.assign({}, metadata, { contents: files[name].contents }))));
}

async function hbs(files, metalsmith) {
  let metadata = metalsmith.metadata();

  Object.keys(files).forEach(name => {
    let file = files[name]
      , compiled = handlebars.compile(file.contents.toString());
    files[name].contents = new Buffer(compiled(Object.assign({}, metadata, file)));
  });
}

(async () => {
  metalsmith(path.resolve(__dirname, '../'))
    .source('.')
    .use(ignore('src/**/*'))
    .metadata({
      title: 'currency.js',
      description: pkg.description,
      version: pkg.version,
      dist: pkg.browser,
      size: prettyBytes(await gzipSize.file(path.resolve(__dirname, '../../', pkg.browser)))
    })
    .use(markdown({
      highlight: hljs
    }))
    .use(tableOfContents)
    .use(hbs)
    .use(concatFiles)
    .use(layout)
    .build(err => {
      if(err) {
        throw err;
      }
    });
})();<|endoftext|>


<commit_before>module.exports = function (parsers) {
    parsers.all.frame = function () {
    }

    parsers.all.frame.prototype.parse = function (buffer, start) {

        var object

        object = {
            packet: null,
            length: null
        }

        object.packet =
            buffer[start++] * 0x1000000 +
            buffer[start++] * 0x10000 +
            buffer[start++] * 0x100 +
            buffer[start++]

        object.length =
            buffer[start++] * 0x1000000 +
            buffer[start++] * 0x10000 +
            buffer[start++] * 0x100 +
            buffer[start++]

        return { start: start, object: object, parser: null }
    }

    parsers.all.descriptor = function () {
    }

    parsers.all.descriptor.prototype.parse = function (buffer, start) {

        var index
        var object
        var terminator

        object = {
            uuid: null,
            name: null,
            manufacturerNumber: null,
            productType: null,
            productNumber: null
        }

        var terminator = [0]
        var index = buffer.indexOf(new Buffer(terminator), start)
        object.uuid = buffer.toString(undefined, start, index)
        start = index + terminator.length

        var terminator = [0]
        var index = buffer.indexOf(new Buffer(terminator), start)
        object.name = buffer.toString(undefined, start, index)
        start = index + terminator.length

        object.manufacturerNumber =
            buffer[start++] * 0x1000000 +
            buffer[start++] * 0x10000 +
            buffer[start++] * 0x100 +
            buffer[start++]

        object.productType =
            buffer[start++] * 0x1000000 +
            buffer[start++] * 0x10000 +
            buffer[start++] * 0x100 +
            buffer[start++]

        object.productNumber =
            buffer[start++] * 0x1000000 +
            buffer[start++] * 0x10000 +
            buffer[start++] * 0x100 +
            buffer[start++]

        return { start: start, object: object, parser: null }
    }

    parsers.all.device = function () {
    }

    parsers.all.device.prototype.parse = function (buffer, start) {

        var i
        var index
        var length
        var object
        var object1
        var terminator

        object = {
            attributes: new Array
        }

        length =
            buffer[start++] * 0x1000000 +
            buffer[start++] * 0x10000 +
            buffer[start++] * 0x100 +
            buffer[start++]

        for (i = 0; i < length; i++) {
            object1 = {
                attributeId: null,
                value: null
            }

            object1.attributeId =
                buffer[start++] * 0x1000000 +
                buffer[start++] * 0x10000 +
                buffer[start++] * 0x100 +
                buffer[start++]

            var terminator = [0]
            var index = buffer.indexOf(new Buffer(terminator), start)
            object1.value = buffer.toString(undefined, start, index)
            start = index + terminator.length

            object.attributes.push(object1)
        }

        return { start: start, object: object, parser: null }
    }
}
<commit_msg>Remove sketch of embedded parsers.<commit_after><|endoftext|>