<commit_before>var Utils = require("../util"),
    Constants = Utils.Constants;

/* The central directory file header */
module.exports = function () {
    var _verMade = 0x0A,
        _version = 0x0A,
        _flags = 0,
        _method = 0,
        _time = 0,
        _crc = 0,
        _compressedSize = 0,
        _size = 0,
        _fnameLen = 0,
        _extraLen = 0,

        _comLen = 0,
        _diskStart = 0,
        _inattr = 0,
        _attr = 0,
        _offset = 0;

    var _dataHeader = {};

    function setTime(val) {
        val = new Date(val);
        _time = (val.getFullYear() - 1980 & 0x7f) << 25  // b09-16 years from 1980
            | (val.getMonth() + 1) << 21                 // b05-08 month
            | val.getDate() << 16                        // b00-04 hour

            // 2 bytes time
            | val.getHours() << 11    // b11-15 hour
            | val.getMinutes() << 5   // b05-10 minute
            | val.getSeconds() >> 1;  // b00-04 seconds divided by 2
    }

    setTime(+new Date());

    return {
        get made () { return _verMade; },
        set made (val) { _verMade = val; },

        get version () { return _version; },
        set version (val) { _version = val },

        get flags () { return _flags },
        set flags (val) { _flags = val; },

        get method () { return _method; },
        set method (val) { _method = val; },

        get time () { return new Date(
            ((_time >> 25) & 0x7f) + 1980,
            ((_time >> 21) & 0x0f) - 1,
            (_time >> 16) & 0x1f,
            (_time >> 11) & 0x1f,
            (_time >> 5) & 0x3f,
            (_time & 0x1f) << 1
        );
        },
        set time (val) {
            setTime(val);
        },

        get crc () { return _crc; },
        set crc (val) { _crc = val; },

        get compressedSize () { return _compressedSize; },
        set compressedSize (val) { _compressedSize = val; },

        get size () { return _size; },
        set size (val) { _size = val; },

        get fileNameLength () { return _fnameLen; },
        set fileNameLength (val) { _fnameLen = val; },

        get extraLength () { return _extraLen },
        set extraLength (val) { _extraLen = val; },

        get commentLength () { return _comLen },
        set commentLength (val) { _comLen = val },

        get diskNumStart () { return _diskStart },
        set diskNumStart (val) { _diskStart = val },

        get inAttr () { return _inattr },
        set inAttr (val) { _inattr = val },

        get attr () { return _attr },
        set attr (val) { _attr = val },

        get offset () { return _offset },
        set offset (val) { _offset = val },

        get encripted () { return (_flags & 1) === 1 },

        get entryHeaderSize () {
            return Constants.CENHDR + _fnameLen + _extraLen + _comLen;
        },

        get realDataOffset () {
            return _offset + Constants.LOCHDR + _dataHeader.fnameLen + _dataHeader.extraLen;
        },

        get dataHeader () {
            return _dataHeader;
        },

        loadDataHeaderFromBinary : function(/*Buffer*/input) {
            var data = input.slice(_offset, _offset + Constants.LOCHDR);
            // 30 bytes and should start with "PK\003\004"
            if (data.readUInt32LE(0) !== Constants.LOCSIG) {
                throw Utils.Errors.INVALID_LOC;
            }
            _dataHeader = {
                // version needed to extract
                version : data.readUInt16LE(Constants.LOCVER),
                // general purpose bit flag
                flags : data.readUInt16LE(Constants.LOCFLG),
                // compression method
                method : data.readUInt16LE(Constants.LOCHOW),
                // modification time (2 bytes time, 2 bytes date)
                time : data.readUInt32LE(Constants.LOCTIM),
                // uncompressed file crc-32 value
                crc : data.readUInt32LE(Constants.LOCCRC),
                // compressed size
                compressedSize : data.readUInt32LE(Constants.LOCSIZ),
                // uncompressed size
                size : data.readUInt32LE(Constants.LOCLEN),
                // filename length
                fnameLen : data.readUInt16LE(Constants.LOCNAM),
                // extra field length
                extraLen : data.readUInt16LE(Constants.LOCEXT)
            }
        },

        loadFromBinary : function(/*Buffer*/data) {
            // data should be 46 bytes and start with "PK 01 02"
            if (data.length !== Constants.CENHDR || data.readUInt32LE(0) !== Constants.CENSIG) {
                throw Utils.Errors.INVALID_CEN;
            }
            // version made by
            _verMade = data.readUInt16LE(Constants.CENVEM);
            // version needed to extract
            _version = data.readUInt16LE(Constants.CENVER);
            // encrypt, decrypt flags
            _flags = data.readUInt16LE(Constants.CENFLG);
            // compression method
            _method = data.readUInt16LE(Constants.CENHOW);
            // modification time (2 bytes time, 2 bytes date)
            _time = data.readUInt32LE(Constants.CENTIM);
            // uncompressed file crc-32 value
            _crc = data.readUInt32LE(Constants.CENCRC);
            // compressed size
            _compressedSize = data.readUInt32LE(Constants.CENSIZ);
            // uncompressed size
            _size = data.readUInt32LE(Constants.CENLEN);
            // filename length
            _fnameLen = data.readUInt16LE(Constants.CENNAM);
            // extra field length
            _extraLen = data.readUInt16LE(Constants.CENEXT);
            // file comment length
            _comLen = data.readUInt16LE(Constants.CENCOM);
            // volume number start
            _diskStart = data.readUInt16LE(Constants.CENDSK);
            // internal file attributes
            _inattr = data.readUInt16LE(Constants.CENATT);
            // external file attributes
            _attr = data.readUInt32LE(Constants.CENATX);
            // LOC header offset
            _offset = data.readUInt32LE(Constants.CENOFF);
        },

        dataHeaderToBinary : function() {
            // LOC header size (30 bytes)
            var data = Buffer.alloc(Constants.LOCHDR);
            // "PK\003\004"
            data.writeUInt32LE(Constants.LOCSIG, 0);
            // version needed to extract
            data.writeUInt16LE(_version, Constants.LOCVER);
            // general purpose bit flag
            data.writeUInt16LE(_flags, Constants.LOCFLG);
            // compression method
            data.writeUInt16LE(_method, Constants.LOCHOW);
            // modification time (2 bytes time, 2 bytes date)
            data.writeUInt32LE(_time, Constants.LOCTIM);
            // uncompressed file crc-32 value
            data.writeUInt32LE(_crc, Constants.LOCCRC);
            // compressed size
            data.writeUInt32LE(_compressedSize, Constants.LOCSIZ);
            // uncompressed size
            data.writeUInt32LE(_size, Constants.LOCLEN);
            // filename length
            data.writeUInt16LE(_fnameLen, Constants.LOCNAM);
            // extra field length
            data.writeUInt16LE(_extraLen, Constants.LOCEXT);
            return data;
        },

        entryHeaderToBinary : function() {
            // CEN header size (46 bytes)
            var data = Buffer.alloc(Constants.CENHDR + _fnameLen + _extraLen + _comLen);
            // "PK\001\002"
            data.writeUInt32LE(Constants.CENSIG, 0);
            // version made by
            data.writeUInt16LE(_verMade, Constants.CENVEM);
            // version needed to extract
            data.writeUInt16LE(_version, Constants.CENVER);
            // encrypt, decrypt flags
            data.writeUInt16LE(_flags, Constants.CENFLG);
            // compression method
            data.writeUInt16LE(_method, Constants.CENHOW);
            // modification time (2 bytes time, 2 bytes date)
            data.writeUInt32LE(_time, Constants.CENTIM);
            // uncompressed file crc-32 value
            data.writeUInt32LE(_crc, Constants.CENCRC);
            // compressed size
            data.writeUInt32LE(_compressedSize, Constants.CENSIZ);
            // uncompressed size
            data.writeUInt32LE(_size, Constants.CENLEN);
            // filename length
            data.writeUInt16LE(_fnameLen, Constants.CENNAM);
            // extra field length
            data.writeUInt16LE(_extraLen, Constants.CENEXT);
            // file comment length
            data.writeUInt16LE(_comLen, Constants.CENCOM);
            // volume number start
            data.writeUInt16LE(_diskStart, Constants.CENDSK);
            // internal file attributes
            data.writeUInt16LE(_inattr, Constants.CENATT);
            // external file attributes
            data.writeUInt32LE(_attr, Constants.CENATX);
            // LOC header offset
            data.writeUInt32LE(_offset, Constants.CENOFF);
            // fill all with
            data.fill(0x00, Constants.CENHDR);
            return data;
        },

        toString : function() {
            return '{\n' +
                '\t"made" : ' + _verMade + ",\n" +
                '\t"version" : ' + _version + ",\n" +
                '\t"flags" : ' + _flags + ",\n" +
                '\t"method" : ' + Utils.methodToString(_method) + ",\n" +
                '\t"time" : ' + this.time + ",\n" +
                '\t"crc" : 0x' + _crc.toString(16).toUpperCase() + ",\n" +
                '\t"compressedSize" : ' + _compressedSize + " bytes,\n" +
                '\t"size" : ' + _size + " bytes,\n" +
                '\t"fileNameLength" : ' + _fnameLen + ",\n" +
                '\t"extraLength" : ' + _extraLen + " bytes,\n" +
                '\t"commentLength" : ' + _comLen + " bytes,\n" +
                '\t"diskNumStart" : ' + _diskStart + ",\n" +
                '\t"inAttr" : ' + _inattr + ",\n" +
                '\t"attr" : ' + _attr + ",\n" +
                '\t"offset" : ' + _offset + ",\n" +
                '\t"entryHeaderSize" : ' + (Constants.CENHDR + _fnameLen + _extraLen + _comLen) + " bytes\n" +
                '}';
        }
    }
};
<commit_msg>Fix <commit_after>var Utils = require("../util"),
    Constants = Utils.Constants;

/* The central directory file header */
module.exports = function () {
    var _verMade = 0x0A,
        _version = 0x0A,
        _flags = 0,
        _method = 0,
        _time = 0,
        _crc = 0,
        _compressedSize = 0,
        _size = 0,
        _fnameLen = 0,
        _extraLen = 0,

        _comLen = 0,
        _diskStart = 0,
        _inattr = 0,
        _attr = 0,
        _offset = 0;

    var _dataHeader = {};

    function setTime(val) {
        val = new Date(val);
        _time = (val.getFullYear() - 1980 & 0x7f) << 25  // b09-16 years from 1980
            | (val.getMonth() + 1) << 21                 // b05-08 month
            | val.getDate() << 16                        // b00-04 hour

            // 2 bytes time
            | val.getHours() << 11    // b11-15 hour
            | val.getMinutes() << 5   // b05-10 minute
            | val.getSeconds() >> 1;  // b00-04 seconds divided by 2
    }

    setTime(+new Date());

    return {
        get made () { return _verMade; },
        set made (val) { _verMade = val; },

        get version () { return _version; },
        set version (val) { _version = val },

        get flags () { return _flags },
        set flags (val) { _flags = val; },

        get method () { return _method; },
        set method (val) { _method = val; },

        get time () { return new Date(
            ((_time >> 25) & 0x7f) + 1980,
            ((_time >> 21) & 0x0f) - 1,
            (_time >> 16) & 0x1f,
            (_time >> 11) & 0x1f,
            (_time >> 5) & 0x3f,
            (_time & 0x1f) << 1
        );
        },
        set time (val) {
            setTime(val);
        },

        get crc () { return _crc; },
        set crc (val) { _crc = val; },

        get compressedSize () { return _compressedSize; },
        set compressedSize (val) { _compressedSize = val; },

        get size () { return _size; },
        set size (val) { _size = val; },

        get fileNameLength () { return _fnameLen; },
        set fileNameLength (val) { _fnameLen = val; },

        get extraLength () { return _extraLen },
        set extraLength (val) { _extraLen = val; },

        get commentLength () { return _comLen },
        set commentLength (val) { _comLen = val },

        get diskNumStart () { return _diskStart },
        set diskNumStart (val) { _diskStart = val },

        get inAttr () { return _inattr },
        set inAttr (val) { _inattr = val },

        get attr () { return _attr },
        set attr (val) { _attr = val },

        get offset () { return _offset },
        set offset (val) { _offset = val },

        get encripted () { return (_flags & 1) === 1 },

        get entryHeaderSize () {
            return Constants.CENHDR + _fnameLen + _extraLen + _comLen;
        },

        get realDataOffset () {
            return _offset + Constants.LOCHDR + _dataHeader.fnameLen + _dataHeader.extraLen;
        },

        get dataHeader () {
            return _dataHeader;
        },

        loadDataHeaderFromBinary : function(/*Buffer*/input) {
            var data = input.slice(_offset, _offset + Constants.LOCHDR);
            // 30 bytes and should start with "PK\003\004"
            if (data.readUInt32LE(0) !== Constants.LOCSIG) {
                throw Utils.Errors.INVALID_LOC;
            }
            _dataHeader = {
                // version needed to extract
                version : data.readUInt16LE(Constants.LOCVER),
                // general purpose bit flag
                flags : data.readUInt16LE(Constants.LOCFLG),
                // compression method
                method : data.readUInt16LE(Constants.LOCHOW),
                // modification time (2 bytes time, 2 bytes date)
                time : data.readUInt32LE(Constants.LOCTIM),
                // uncompressed file crc-32 value
                crc : data.readUInt32LE(Constants.LOCCRC),
                // compressed size
                compressedSize : data.readUInt32LE(Constants.LOCSIZ),
                // uncompressed size
                size : data.readUInt32LE(Constants.LOCLEN),
                // filename length
                fnameLen : data.readUInt16LE(Constants.LOCNAM),
                // extra field length
                extraLen : data.readUInt16LE(Constants.LOCEXT)
            }
        },

        loadFromBinary : function(/*Buffer*/data) {
            // data should be 46 bytes and start with "PK 01 02"
            if (data.length !== Constants.CENHDR || data.readUInt32LE(0) !== Constants.CENSIG) {
                throw Utils.Errors.INVALID_CEN;
            }
            // version made by
            _verMade = data.readUInt16LE(Constants.CENVEM);
            // version needed to extract
            _version = data.readUInt16LE(Constants.CENVER);
            // encrypt, decrypt flags
            _flags = data.readUInt16LE(Constants.CENFLG);
            // compression method
            _method = data.readUInt16LE(Constants.CENHOW);
            // modification time (2 bytes time, 2 bytes date)
            _time = data.readUInt32LE(Constants.CENTIM);
            // uncompressed file crc-32 value
            _crc = data.readUInt32LE(Constants.CENCRC);
            // compressed size
            _compressedSize = data.readUInt32LE(Constants.CENSIZ);
            // uncompressed size
            _size = data.readUInt32LE(Constants.CENLEN);
            // filename length
            _fnameLen = data.readUInt16LE(Constants.CENNAM);
            // extra field length
            _extraLen = data.readUInt16LE(Constants.CENEXT);
            // file comment length
            _comLen = data.readUInt16LE(Constants.CENCOM);
            // volume number start
            _diskStart = data.readUInt16LE(Constants.CENDSK);
            // internal file attributes
            _inattr = data.readUInt16LE(Constants.CENATT);
            // external file attributes
            _attr = data.readUInt32LE(Constants.CENATX);
            // LOC header offset
            _offset = data.readUInt32LE(Constants.CENOFF);
        },

        dataHeaderToBinary : function() {
            // LOC header size (30 bytes)
            var data = Buffer.alloc(Constants.LOCHDR);
            // "PK\003\004"
            data.writeUInt32LE(Constants.LOCSIG, 0);
            // version needed to extract
            data.writeUInt16LE(_version, Constants.LOCVER);
            // general purpose bit flag
            data.writeUInt16LE(_flags, Constants.LOCFLG);
            // compression method
            data.writeUInt16LE(_method, Constants.LOCHOW);
            // modification time (2 bytes time, 2 bytes date)
            data.writeUInt32LE(_time, Constants.LOCTIM);
            // uncompressed file crc-32 value
            data.writeUInt32LE(_crc, Constants.LOCCRC);
            // compressed size
            data.writeUInt32LE(_compressedSize, Constants.LOCSIZ);
            // uncompressed size
            data.writeUInt32LE(_size, Constants.LOCLEN);
            // filename length
            data.writeUInt16LE(_fnameLen, Constants.LOCNAM);
            // extra field length
            data.writeUInt16LE(_extraLen, Constants.LOCEXT);
            return data;
        },

        entryHeaderToBinary : function() {
            // CEN header size (46 bytes)
            var data = Buffer.alloc(Constants.CENHDR + _fnameLen + _extraLen + _comLen);
            // "PK\001\002"
            data.writeUInt32LE(Constants.CENSIG, 0);
            // version made by
            data.writeUInt16LE(_verMade, Constants.CENVEM);
            // version needed to extract
            data.writeUInt16LE(_version, Constants.CENVER);
            // encrypt, decrypt flags
            data.writeUInt16LE(_flags, Constants.CENFLG);
            // compression method
            data.writeUInt16LE(_method, Constants.CENHOW);
            // modification time (2 bytes time, 2 bytes date)
            data.writeUInt32LE(_time, Constants.CENTIM);
            // uncompressed file crc-32 value
            data.writeInt32LE(_crc & 0xFFFF, Constants.CENCRC, true);
            // compressed size
            data.writeUInt32LE(_compressedSize, Constants.CENSIZ);
            // uncompressed size
            data.writeUInt32LE(_size, Constants.CENLEN);
            // filename length
            data.writeUInt16LE(_fnameLen, Constants.CENNAM);
            // extra field length
            data.writeUInt16LE(_extraLen, Constants.CENEXT);
            // file comment length
            data.writeUInt16LE(_comLen, Constants.CENCOM);
            // volume number start
            data.writeUInt16LE(_diskStart, Constants.CENDSK);
            // internal file attributes
            data.writeUInt16LE(_inattr, Constants.CENATT);
            // external file attributes
            data.writeUInt32LE(_attr, Constants.CENATX);
            // LOC header offset
            data.writeUInt32LE(_offset, Constants.CENOFF);
            // fill all with
            data.fill(0x00, Constants.CENHDR);
            return data;
        },

        toString : function() {
            return '{\n' +
                '\t"made" : ' + _verMade + ",\n" +
                '\t"version" : ' + _version + ",\n" +
                '\t"flags" : ' + _flags + ",\n" +
                '\t"method" : ' + Utils.methodToString(_method) + ",\n" +
                '\t"time" : ' + this.time + ",\n" +
                '\t"crc" : 0x' + _crc.toString(16).toUpperCase() + ",\n" +
                '\t"compressedSize" : ' + _compressedSize + " bytes,\n" +
                '\t"size" : ' + _size + " bytes,\n" +
                '\t"fileNameLength" : ' + _fnameLen + ",\n" +
                '\t"extraLength" : ' + _extraLen + " bytes,\n" +
                '\t"commentLength" : ' + _comLen + " bytes,\n" +
                '\t"diskNumStart" : ' + _diskStart + ",\n" +
                '\t"inAttr" : ' + _inattr + ",\n" +
                '\t"attr" : ' + _attr + ",\n" +
                '\t"offset" : ' + _offset + ",\n" +
                '\t"entryHeaderSize" : ' + (Constants.CENHDR + _fnameLen + _extraLen + _comLen) + " bytes\n" +
                '}';
        }
    }
};
<|endoftext|>


<commit_before>/**
 * Created by Abhinav on 05-03-2017.
 */
var express = require('express');
var fs = require('fs');
var async=require('async');
var MongoClient = require('mongodb').MongoClient;
var readline = require('readline');
var google = require('googleapis');
var googleAuth = require('google-auth-library');
var type = require('type-of-is');
var base64url = require('base64-url');
var historyid;
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/gmail-nodejs-quickstart.json
var SCOPES = ['https://mail.google.com'];
var TOKEN_DIR = (process.env.HOME || process.env.HOMEPATH ||
    process.env.USERPROFILE) + '/.credentials/';
var TOKEN_PATH = TOKEN_DIR + 'gmail-nodejs-quickstart.json';
var HISTORY_PATH = TOKEN_DIR + 'History_id.txt';
var gcredentials="";
var mongo=require("./setupmongo.js");
var app=express();
app.listen(3000);
//mongo();
var url = 'mongodb://localhost:27017/automated';
// Use connect method to connect to the Server
var db;
    MongoClient.connect(url, function (err, dbs) {

        console.log("Connected correctly to server");
        db=dbs;
    });

app.get('/users/google/callback', function(req, res) {
    console.log(req.query.code);
    res.end("");
});

fs.readFile('../client_secret.json', function processClientSecrets(err, content) {
    if (err) {
        console.log('Error loading client secret file: ' + err);
        return;
    }
    // Authorize a client with the loaded credentials, then call the
    // Gmail API.
    gcredentials=JSON.parse(content);
    authorize(JSON.parse(content), start);
});

// Load client secrets from a local file.

/**
 * Create an OAuth2 client with the given credentials, and then execute the
 * given callback function.
 *
 * @param {Object} credentials The authorization client credentials.
 * @param {function} callback The callback to call with the authorized client.
 */
function authorize(credentials,callback) {

    var clientSecret = credentials.web.client_secret;
    var clientId = credentials.web.client_id;
    var redirectUrl = credentials.web.redirect_uris[0];

    var auth = new googleAuth();
    var oauth2Client = new auth.OAuth2(clientId, clientSecret, redirectUrl);

    google.options({
        auth: oauth2Client
    });

    // Check if we have previously stored a token.
    fs.readFile(TOKEN_PATH, function(err, token) {
        if (err) {
            getNewToken(oauth2Client, callback);
        } else {
            oauth2Client.credentials = JSON.parse(token);
            callback(oauth2Client,list);
        }
    });
}

/**
 * Get and store new token after prompting for user authorization, and then
 * execute the given callback with the authorized OAuth2 client.
 *
 * @param {google.auth.OAuth2} oauth2Client The OAuth2 client to get token for.
 * @param {getEventsCallback} callback The callback to call with the authorized
 *     client.
 */

function getNewToken(oauth2Client, callback) {
    var authUrl = oauth2Client.generateAuthUrl({
        access_type: 'offline',
        scope: SCOPES
    });
    console.log('Authorize this app by visiting this url: ', authUrl);
    var rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout
    });
    rl.question('Enter the code that appears here and press enter: ', function(code) {
        rl.close();
        oauth2Client.getToken(code, function(err, token) {
            if (err) {
                console.log('Error while trying to retrieve access token', err);
                return;
            }
            oauth2Client.credentials = token;
            storeToken(token);
            callback(oauth2Client,list);
        });
    });
}

/**
 * Store token to disk be used in later program executions.
 *
 * @param {Object} token The token to store to disk.
 */
function storeToken(token) {
    try {
        fs.mkdirSync(TOKEN_DIR);
    } catch (err) {
        if (err.code != 'EEXIST') {
            throw err;
        }
    }
    fs.writeFile(TOKEN_PATH, JSON.stringify(token));
    console.log('Token stored to ' + TOKEN_PATH);
}
function storehistoryid(token) {
    try {
        fs.mkdirSync(HISTORY_PATH);
    } catch (err) {
        if (err.code != 'EEXIST') {
            throw err;
        }
    }
    fs.writeFile(HISTORY_PATH, JSON.stringify(token));
    console.log('Token stored to ' + HISTORY_PATH);
}

function start(auth,list){
    fs.readFile(HISTORY_PATH,function(err, hId) {
        if (err) {
            console.log(err);
        } else {
            historyid=JSON.parse(hId);

            list(auth);
        }
    });

}

function list(auth){
    console.log(historyid);
    var gmail = google.gmail('v1');
    gmail.users.history.list({
        auth: auth,
        userId: 'me',
        startHistoryId: historyid,
        historyTypes:'messageAdded',
        labelId:'INBOX'

    },  function (err, response) {
        if (err) {
            console.log('The API returned an error: ' + err);
            getNewToken(auth,start);

          /* auth.refreshAccessToken(function(err, tokens) {
           storeToken(tokens)
           });*/
        }
        else{
        try
        {var id = response.history;
            historyid=response.historyId;
            storehistoryid(historyid);
           // console.log(response);
            console.log(id.length);
            for(var i=0;id[i];i++){
                // console.log(id[i].messages[0].id);

               // async.waterfall([getmessage(id[i].messages[0].id,auth,gmail,send),send(subject,gmail,auth,mailto,body)]);
                getmessage(id[i].messages[0].id,auth,gmail);
                if(i==id.length-1){
                setTimeout(function (auth){
                    list(auth);
                },5000);}
            }
        }
        catch(err) {
            //console.log(collection);
            console.log("no new messages");
            setTimeout(function (auth){
            list(auth);
        },5000);}}
    });

}

function getmessage(id,auth,gmail) {console.log(id);
    gmail.users.messages.get({
        auth: auth,
        userId: 'me',
        id: id,
    },function (err,response){
        if (err){console.log("here take a error ");
            return;}
        else
        {   for(var i=0;response.payload.headers[i];i++){
            if(response.payload.headers[i].name=="From"){
                var mailto=response.payload.headers[i].value;
                console.log(mailto);}
            else if(response.payload.headers[i].name=="Subject")
                var inputsubject=response.payload.headers[i].value;
        }
            var inputbody=response.payload.parts[0].body.data;
            inputbody =base64url.unescape(inputbody);
            inputbody=base64url.decode(inputbody);
            if(inputbody.lastIndexOf("\n")>0) {
                inputbody= inputbody.substring(0, inputbody.lastIndexOf("\n"));
               // inputbody=inputbody.replace(/\s/g,'').toLowerCase();
            }
            makesubject(auth,gmail,mailto,inputsubject,inputbody);
            }

    })
return;
}
function makesubject(auth,gmail,mailto,inputsubject,inputbody){
    console.log(inputbody);

    //console.log(mailto,inputsubject);
    var subject;
    var body="Subject or query is invalid.";
    if(inputsubject.replace(/\s/g,'').toLowerCase()=="search_database")
    {
        //setTimeout(function(){subject="Here is the requested query";},500);
        var collection=db.collection("dishes");
        var search = inputbody.split('\n')[0].replace(/\s/g,'').toLowerCase();
        inputbody=inputbody.split('\n')[1].replace(/\s/g,'').toLowerCase();
        if(search=="firstname"){
        collection.find({firstname:inputbody}).toArray(function(err, docs) {
            body="";
            subject="Here is the requested query";
            for(var i=0;docs[i];i++){
           // body.concat(docs[i].name)
            body=body+(i+1)+".
";
            body=body+"Name:"+docs[i].firstname+" "+docs[i].lastname+"
";
            body=body+"Id:"+docs[i]._id+"

";
            //console.log(docs[i].name);
            }

            send(subject,gmail,auth,mailto,body);
        });

    }
        else if(search=="lastname"){
            collection.find({lastname:inputbody}).toArray(function(err, docs) {
                body="";
                subject="Here is the requested query";
                for(var i=0;docs[i];i++){
                    // body.concat(docs[i].name)
                    body=body+(i+1)+".
";
                    body=body+"Name:"+docs[i].firstname+" "+docs[i].lastname+"
";
                    body=body+"Id:"+docs[i]._id+"

";
                    //console.log(docs[i].name);
                }

                send(subject,gmail,auth,mailto,body);
            });

        }
        else if(search=="phoneno"){
            collection.find({phoneno:inputbody}).toArray(function(err, docs) {
                body="";
                subject="Here is the requested query";
                for(var i=0;docs[i];i++){
                    // body.concat(docs[i].name)
                    body=body+(i+1)+".
";
                    body=body+"Name:"+docs[i].firstname+" "+docs[i].lastname+"
";
                    body=body+"Id:"+docs[i]._id+"

";
                    //console.log(docs[i].name);
                }

                send(subject,gmail,auth,mailto,body);
            });

        }
    }
    else{
        subject="Invalid Query!!";
        send(subject,gmail,auth,mailto,body);
    }
    }

function yo(subject,gmail,auth,mailto,body){console.log(subject);};
function send(subject,gmail,auth,mailto,body) { var string="To:"+mailto+"\n" +
    "From:Automated bot <automatedquery@gmail.com>\n"+
    "Content-type: text/html;charset=UTF-8\n"+
    "MIME-Version: 1.0\n"+
    "Subject:"+subject+"\n\n"+
    "
"+body+"
\n";

    var r=base64url.escape(base64url.encode(string));
    console.log(r);
    gmail.users.messages.send({
        auth: auth,
        userId: 'me',
        resource: {raw:r}}
    )}
/**
 * Lists the labels in the user's account.
 *
 * @param {google.auth.OAuth2} auth An authorized OAuth2 client.
 */
function listLabels1(auth) {
    var gmail = google.gmail('v1');
    gmail.users.messages.list({
        auth: auth,
        userId: 'me',
        maxResults: 5,
        labelIds: "INBOX"

    }, function (err, response) {
        if (err) {
            console.log('The API returned an error: ' + err);
            return;
        }
        var id = response.messages;
        {
            console.log(id);
            getmessage(id[0].id,auth,gmail);
        }
    });
}

<commit_msg>all callback except history<commit_after>/**
 * Created by Abhinav on 05-03-2017.
 */
var express = require('express');
var fs = require('fs');
var async=require('async');
var MongoClient = require('mongodb').MongoClient;
var readline = require('readline');
var google = require('googleapis');
var googleAuth = require('google-auth-library');
var type = require('type-of-is');
var base64url = require('base64-url');
var historyid;
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/gmail-nodejs-quickstart.json
var SCOPES = ['https://mail.google.com'];
var TOKEN_DIR = (process.env.HOME || process.env.HOMEPATH ||
    process.env.USERPROFILE) + '/.credentials/';
var TOKEN_PATH = TOKEN_DIR + 'gmail-nodejs-quickstart.json';
var HISTORY_PATH = TOKEN_DIR + 'History_id.txt';
var gcredentials="";
var mongo=require("./setupmongo.js");
var app=express();
app.listen(3000);
//mongo();
var url = 'mongodb://localhost:27017/automated';
// Use connect method to connect to the Server
var db;
    MongoClient.connect(url, function (err, dbs) {

        console.log("Connected correctly to server");
        db=dbs;
    });

app.get('/users/google/callback', function(req, res) {
    console.log(req.query.code);
    res.end("");
});

fs.readFile('../client_secret.json', function processClientSecrets(err, content) {
    if (err) {
        console.log('Error loading client secret file: ' + err);
        return;
    }
    // Authorize a client with the loaded credentials, then call the
    // Gmail API.
    gcredentials=JSON.parse(content);
    authorize(JSON.parse(content), start);
});

// Load client secrets from a local file.

/**
 * Create an OAuth2 client with the given credentials, and then execute the
 * given callback function.
 *
 * @param {Object} credentials The authorization client credentials.
 * @param {function} callback The callback to call with the authorized client.
 */
function authorize(credentials,callback) {

    var clientSecret = credentials.web.client_secret;
    var clientId = credentials.web.client_id;
    var redirectUrl = credentials.web.redirect_uris[0];

    var auth = new googleAuth();
    var oauth2Client = new auth.OAuth2(clientId, clientSecret, redirectUrl);

    google.options({
        auth: oauth2Client
    });

    // Check if we have previously stored a token.
    fs.readFile(TOKEN_PATH, function(err, token) {
        if (err) {
            getNewToken(oauth2Client, callback);
        } else {
            oauth2Client.credentials = JSON.parse(token);
            callback(oauth2Client,list);
        }
    });
}

/**
 * Get and store new token after prompting for user authorization, and then
 * execute the given callback with the authorized OAuth2 client.
 *
 * @param {google.auth.OAuth2} oauth2Client The OAuth2 client to get token for.
 * @param {getEventsCallback} callback The callback to call with the authorized
 *     client.
 */

function getNewToken(oauth2Client, callback) {
    var authUrl = oauth2Client.generateAuthUrl({
        access_type: 'offline',
        scope: SCOPES
    });
    console.log('Authorize this app by visiting this url: ', authUrl);
    var rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout
    });
    rl.question('Enter the code that appears here and press enter: ', function(code) {
        rl.close();
        oauth2Client.getToken(code, function(err, token) {
            if (err) {
                console.log('Error while trying to retrieve access token', err);
                return;
            }
            oauth2Client.credentials = token;
            storeToken(token);
            callback(oauth2Client,list);
        });
    });
}

/**
 * Store token to disk be used in later program executions.
 *
 * @param {Object} token The token to store to disk.
 */
function storeToken(token) {
    try {
        fs.mkdirSync(TOKEN_DIR);
    } catch (err) {
        if (err.code != 'EEXIST') {
            throw err;
        }
    }
    fs.writeFile(TOKEN_PATH, JSON.stringify(token));
    console.log('Token stored to ' + TOKEN_PATH);
}
function storehistoryid(token) {
    try {
        fs.mkdirSync(HISTORY_PATH);
    } catch (err) {
        if (err.code != 'EEXIST') {
            throw err;
        }
    }
    fs.writeFile(HISTORY_PATH, JSON.stringify(token));
    console.log('Token stored to ' + HISTORY_PATH);
}

function start(auth,list){
    fs.readFile(HISTORY_PATH,function(err, hId) {
        if (err) {
            console.log(err);
        } else {
            historyid=JSON.parse(hId);

            list(auth,getmessage);
        }
    });

}

function list(auth,getmessage){
    console.log(historyid);
    var gmail = google.gmail('v1');
    gmail.users.history.list({
        auth: auth,
        userId: 'me',
        startHistoryId: historyid,
        historyTypes:'messageAdded',
        labelId:'INBOX'

    },  function (err, response) {
        if (err) {
            console.log('The API returned an error: ' + err);
            getNewToken(auth,start);

          /* auth.refreshAccessToken(function(err, tokens) {
           storeToken(tokens)
           });*/
        }
        else{
        try
        {var id = response.history;
            historyid=response.historyId;
            storehistoryid(historyid);
           // console.log(response);
            console.log(id.length);
            for(var i=0;id[i];i++){
                // console.log(id[i].messages[0].id);

               // async.waterfall([getmessage(id[i].messages[0].id,auth,gmail,send),send(subject,gmail,auth,mailto,body)]);
                getmessage(id[i].messages[0].id,auth,gmail,makesubject);
                if(i==id.length-1){
                setTimeout(function (auth){
                    list(auth,getmessage);
                },5000);}
            }
        }
        catch(err) {
            //console.log(collection);
            console.log("no new messages");
            setTimeout(function (auth){
            list(auth,getmessage);
        },5000);}}
    });

}

function getmessage(id,auth,gmail,makesubject) {console.log(id);
    gmail.users.messages.get({
        auth: auth,
        userId: 'me',
        id: id,
    },function (err,response){
        if (err){console.log("here take a error ");
            return;}
        else
        {   for(var i=0;response.payload.headers[i];i++){
            if(response.payload.headers[i].name=="From"){
                var mailto=response.payload.headers[i].value;
                console.log(mailto);}
            else if(response.payload.headers[i].name=="Subject")
                var inputsubject=response.payload.headers[i].value;
        }
            var inputbody=response.payload.parts[0].body.data;
            inputbody =base64url.unescape(inputbody);
            inputbody=base64url.decode(inputbody);
            if(inputbody.lastIndexOf("\n")>0) {
                inputbody= inputbody.substring(0, inputbody.lastIndexOf("\n"));
               // inputbody=inputbody.replace(/\s/g,'').toLowerCase();
            }
            makesubject(auth,gmail,mailto,inputsubject,inputbody,send);
            }

    })
return;
}
function makesubject(auth,gmail,mailto,inputsubject,inputbody,send){
    console.log(inputbody);

    //console.log(mailto,inputsubject);
    var subject;
    var body="Subject or query is invalid.";
    if(inputsubject.replace(/\s/g,'').toLowerCase()=="search_database")
    {
        //setTimeout(function(){subject="Here is the requested query";},500);
        var collection=db.collection("dishes");
        var search = inputbody.split('\n')[0].replace(/\s/g,'').toLowerCase();
        inputbody=inputbody.split('\n')[1].replace(/\s/g,'').toLowerCase();
        if(search=="firstname"){
        collection.find({firstname:inputbody}).toArray(function(err, docs) {
            body="";
            subject="Here is the requested query";
            for(var i=0;docs[i];i++){
           // body.concat(docs[i].name)
            body=body+(i+1)+".
";
            body=body+"Name:"+docs[i].firstname+" "+docs[i].lastname+"
";
            body=body+"Id:"+docs[i]._id+"

";
            //console.log(docs[i].name);
            }

            send(subject,gmail,auth,mailto,body);
        });

    }
        else if(search=="lastname"){
            collection.find({lastname:inputbody}).toArray(function(err, docs) {
                body="";
                subject="Here is the requested query";
                for(var i=0;docs[i];i++){
                    // body.concat(docs[i].name)
                    body=body+(i+1)+".
";
                    body=body+"Name:"+docs[i].firstname+" "+docs[i].lastname+"
";
                    body=body+"Id:"+docs[i]._id+"

";
                    //console.log(docs[i].name);
                }

                send(subject,gmail,auth,mailto,body);
            });

        }
        else if(search=="phoneno"){
            collection.find({phoneno:inputbody}).toArray(function(err, docs) {
                body="";
                subject="Here is the requested query";
                for(var i=0;docs[i];i++){
                    // body.concat(docs[i].name)
                    body=body+(i+1)+".
";
                    body=body+"Name:"+docs[i].firstname+" "+docs[i].lastname+"
";
                    body=body+"Id:"+docs[i]._id+"

";
                    //console.log(docs[i].name);
                }

                send(subject,gmail,auth,mailto,body);
            });

        }
    }
    else{
        subject="Invalid Query!!";
        send(subject,gmail,auth,mailto,body);
    }
    }

function yo(subject,gmail,auth,mailto,body){console.log(subject);};
function send(subject,gmail,auth,mailto,body) { var string="To:"+mailto+"\n" +
    "From:Automated bot <automatedquery@gmail.com>\n"+
    "Content-type: text/html;charset=UTF-8\n"+
    "MIME-Version: 1.0\n"+
    "Subject:"+subject+"\n\n"+
    "
"+body+"
\n";

    var r=base64url.escape(base64url.encode(string));
    console.log(r);
    gmail.users.messages.send({
        auth: auth,
        userId: 'me',
        resource: {raw:r}}
    )}
/**
 * Lists the labels in the user's account.
 *
 * @param {google.auth.OAuth2} auth An authorized OAuth2 client.
 */
function listLabels1(auth) {
    var gmail = google.gmail('v1');
    gmail.users.messages.list({
        auth: auth,
        userId: 'me',
        maxResults: 5,
        labelIds: "INBOX"

    }, function (err, response) {
        if (err) {
            console.log('The API returned an error: ' + err);
            return;
        }
        var id = response.messages;
        {
            console.log(id);
            getmessage(id[0].id,auth,gmail);
        }
    });
}

<|endoftext|>


<commit_before>var c3d = { };

var gl, glExtFragDepth;

function initGL(canvas) {
  try {
    gl = canvas.getContext("experimental-webgl");
    gl.viewportWidth = canvas.width;
    gl.viewportHeight = canvas.height;
  } catch (e) {
  }
  if (!gl) {
    alert("Could not initialise WebGL, sorry :-(");
  }
  glExtFragDepth = gl.getExtension("EXT_frag_depth");
}

var shaderProgram;

function initShaders() {
  var fs = "precision mediump float;\n\n" + c3d.resources.lighting + "\n" + c3d.resources.sphere_frag;
  var vs = "precision mediump float;\n\n" + c3d.resources.sphere_vert;
  if (glExtFragDepth)
    fs = "#extension GL_EXT_frag_depth : enable\n" + fs;
  // console.log([fs,vs]);
  fs = new glObj.ShaderObject(gl, gl.FRAGMENT_SHADER, fs);
  vs = new glObj.ShaderObject(gl, gl.VERTEX_SHADER, vs);
  shaderProgram = new glObj.ShaderProgram([fs, vs]);
  shaderProgram.use();

  gl.enableVertexAttribArray(shaderProgram.attrib["aVertex"].location);
}

var projectionMatrix;
var mvMatrix;

function setUniforms() {
  var u = shaderProgram.uniform;
  u.uProjectionMatrix(projectionMatrix);
  u.materialShininess([60]);
  u.materialAmbient([0.2, 0.2, 0.2, 0.2]);
  u.materialSpecular([0.5, 0.5, 0.5, 0.5]);
  u.lightSource[0].position([0.0, 0.0, 0.0, 1.0]);
  u.lightSource[0].ambient([0.0, 0.0, 0.0, 1.0]);
  u.lightSource[0].diffuse([1.0, 1.0, 1.0, 1.0]);
  u.lightSource[0].specular([0.0, 0.0, 0.0, 1.0]);
}

var squareVertexPositionBuffer;

function initBuffers() {
  squareVertexPositionBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);
  vertices = [
     1.0,  1.0, 0.0,
    -1.0,  1.0, 0.0,
     1.0, -1.0, 0.0,
    -1.0, -1.0, 0.0
  ];
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
  squareVertexPositionBuffer.itemSize = 3;
  squareVertexPositionBuffer.numItems = 4;
}

function drawSphere(pos, radius, rgba) {
  var u = shaderProgram.uniform;
  u.sphereCenter(transform4to3(mvMatrix, pos));
  u.sphereRadius([radius]);
  u.materialDiffuse(rgba);
  gl.drawArrays(gl.TRIANGLE_STRIP, 0, squareVertexPositionBuffer.numItems);
}

var spheres = [
  [[Math.cos(2*Math.PI/3), Math.sin(2*Math.PI/3), 0, 1], 1, [1, 0, 0, 0.85]],
  [[Math.cos(4*Math.PI/3), Math.sin(4*Math.PI/3), 0, 1], 1, [0, 1, 0, 0.85]],
  [[Math.cos(6*Math.PI/3), Math.sin(6*Math.PI/3), 0, 1], 1, [0, 0, 1, 0.85]]
];

function drawScene() {
  gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

  //mat4.perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0, pMatrix);

  //mat4.identity(mvMatrix);

  //mat4.translate(mvMatrix, [0, 0.0, -7.0]);
  gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);
  gl.vertexAttribPointer(shaderProgram.attrib["aVertex"].location, squareVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
  setUniforms();
  gl.enable(gl.BLEND);
  gl.depthMask(false);
  renderPrimitives(false);
  renderPrimitives(false);
  gl.depthMask(true);
  /*
  gl.disable(gl.BLEND);
  renderPrimitives(true);
  gl.enable(gl.BLEND);
  */
  renderPrimitives(false);
  gl.disable(gl.BLEND);
}

function renderPrimitives(opaque) {
  if (!opaque) {
    shaderProgram.uniform.sphereMode([0]);
    spheres.forEach(drawSphere.apply.bind(drawSphere, null));
  }
  shaderProgram.uniform.sphereMode([1]);
  spheres.forEach(drawSphere.apply.bind(drawSphere, null));
}

function setPerspective(fieldOfView, width, height, zNear, zFar) {
  var f = 1.0/Math.tan(fieldOfView * (Math.PI / 360.));
  var nearMinusFar = zNear - zFar;
  projectionMatrix = [
    f*height/width, 0, 0, 0,
    0, f, 0, 0,
    0, 0, (zFar + zNear)/nearMinusFar, -1,
    0, 0, 2*zFar*zNear/nearMinusFar, 0
  ];
}

function norm(v) {
  var x = v[0], y = v[1], z = v[2];
  return Math.sqrt(x*x + y*y + z*z);
}

function normalized(v) {
  var x = v[0], y = v[1], z = v[2];
  var f = 1/Math.sqrt(x*x + y*y + z*z);
  return [f*x, f*y, f*z];
}

function transpose(m) {
  return [
    m[0], m[3], m[6],
    m[1], m[4], m[7],
    m[2], m[5], m[8]
  ];
};

function adj3(m) {
  return [
    m[4]*m[8] - m[5]*m[7], m[2]*m[7] - m[1]*m[8], m[1]*m[5] - m[2]*m[4],
    m[5]*m[6] - m[3]*m[8], m[0]*m[8] - m[2]*m[6], m[2]*m[3] - m[0]*m[5],
    m[3]*m[7] - m[4]*m[6], m[1]*m[6] - m[0]*m[7], m[0]*m[4] - m[1]*m[3]
  ];
}

function sub3(a, b) {
  return [a[0]-b[0], a[1]-b[1], a[2]-b[2]];
}

function cross3(a, b) {
  return [a[1]*b[2]-a[2]*b[1], a[2]*b[0]-a[0]*b[2], a[0]*b[1]-a[1]*b[0]];
}

function mul4mm(a, b) {
  return [
    a[0]*b[0] + a[1]*b[4] + a[2]*b[8] + a[3]*b[12],
    a[0]*b[1] + a[1]*b[5] + a[2]*b[9] + a[3]*b[13],
    a[0]*b[2] + a[1]*b[6] + a[2]*b[10] + a[3]*b[14],
    a[0]*b[3] + a[1]*b[7] + a[2]*b[11] + a[3]*b[15],
    a[4]*b[0] + a[5]*b[4] + a[6]*b[8] + a[7]*b[12],
    a[4]*b[1] + a[5]*b[5] + a[6]*b[9] + a[7]*b[13],
    a[4]*b[2] + a[5]*b[6] + a[6]*b[10] + a[7]*b[14],
    a[4]*b[3] + a[5]*b[7] + a[6]*b[11] + a[7]*b[15],
    a[8]*b[0] + a[9]*b[4] + a[10]*b[8] + a[11]*b[12],
    a[8]*b[1] + a[9]*b[5] + a[10]*b[9] + a[11]*b[13],
    a[8]*b[2] + a[9]*b[6] + a[10]*b[10] + a[11]*b[14],
    a[8]*b[3] + a[9]*b[7] + a[10]*b[11] + a[11]*b[15],
    a[12]*b[0] + a[13]*b[4] + a[14]*b[8] + a[15]*b[12],
    a[12]*b[1] + a[13]*b[5] + a[14]*b[9] + a[15]*b[13],
    a[12]*b[2] + a[13]*b[6] + a[14]*b[10] + a[15]*b[14],
    a[12]*b[3] + a[13]*b[7] + a[14]*b[11] + a[15]*b[15]
  ];
}

function mul3mv(m, v) {
  return [
    m[0]*v[0] + m[1]*v[1] + m[2]*v[2],
    m[3]*v[0] + m[4]*v[1] + m[5]*v[2],
    m[6]*v[0] + m[7]*v[1] + m[8]*v[2]
  ];
}

function transform4to3(m, v) {
  var x = m[0]*v[0] + m[1]*v[1] + m[2]*v[2] + m[3]*v[3];
  var y = m[4]*v[0] + m[5]*v[1] + m[6]*v[2] + m[7]*v[3];
  var z = m[8]*v[0] + m[9]*v[1] + m[10]*v[2] + m[11]*v[3];
  var f = 1/(m[12]*v[0] + m[13]*v[1] + m[14]*v[2] + m[15]*v[3]);
  return [x*f, y*f, z*f];
}

var viewDist;

function setCamera(position, lookAt, up) {
  var viewDir = sub3(position, lookAt);
  viewDist = norm(viewDir);
  var z2 = normalized(viewDir);
  var y2 = normalized(up);
  var x2 = cross3(y2, z2);
  var m1 = [
    x2[0], y2[0], z2[0],
    x2[1], y2[1], z2[1],
    x2[2], y2[2], z2[2]
  ];
  var m2 = adj3(m1);
  var t = mul3mv(m2, position);
  mvMatrix = [
    m2[0], m2[1], m2[2], -t[0],
    m2[3], m2[4], m2[5], -t[1],
    m2[6], m2[7], m2[8], -t[2],
    0, 0, 0, 1
  ];
  //console.log(mvMatrix);
}

var ROTATE_SENSITIVITY = 0.01;

function mouseRotate(dx, dy) {
  var ax = ROTATE_SENSITIVITY*dx, ay = ROTATE_SENSITIVITY*dy;
  var cx = Math.cos(ax), cy = Math.cos(ay);
  var sx = Math.sin(ax), sy = Math.sin(ay);
  var mx = [
    cx, 0, sx, 0,
    0, 1, 0, 0,
    -sx, 0, cx, 0,
    0, 0, 0, 1];
  var my = [
    1, 0, 0, 0,
    0, cy, -sy, 0,
    0, sy, cy, 0,
    0, 0, 0, 1];
  var mz1 = [
    1, 0, 0, 0,
    0, 1, 0, 0,
    0, 0, 1, viewDist,
    0, 0, 0, 1];
  var mz2 = [
    1, 0, 0, 0,
    0, 1, 0, 0,
    0, 0, 1, -viewDist,
    0, 0, 0, 1];
  mvMatrix = mul4mm(mz2, mul4mm(mul4mm(mx, my), mul4mm(mz1, mvMatrix)));
  drawScene();
}

function webGLStart() {
  var canvas = document.getElementById("canvas");
  var mx, my, mdown = false;
  canvas.addEventListener("mousedown", function(evnt) {
    if (evnt.button === 0) {
      mdown = true;
    }
    if (evnt.buttons === undefined ? mdown : (evnt.buttons & 1)) {
      mx = evnt.screenX;
      my = evnt.screenY;
    }
  });
  canvas.addEventListener("mousemove", function(evnt) {
    if (evnt.buttons === undefined ? mdown : (evnt.buttons & 1)) {
      if (evnt.movementX !== undefined) {
        mouseRotate(evnt.movementX, evnt.movementY);
      }
      else {
        mouseRotate(evnt.screenX - mx, evnt.screenY - my);
      }
      mx = evnt.screenX;
      my = evnt.screenY;
    }
  });
  canvas.addEventListener("mouseup", function(evnt) {
    if (evnt.button === 0) mdown = false;
  });
  initGL(canvas);
  initShaders();
  initBuffers();

  gl.clearColor(0.0, 0.0, 0.0, 1.0);
  gl.enable(gl.DEPTH_TEST);
  gl.depthFunc(gl.LEQUAL);
  gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);

  setPerspective(45.0, 632, 452, 0.1, 100.0);
  setCamera([0,0,5], [0,0,0], [0,1,0]);
  drawScene();
}
<commit_msg>Drop testing file, was left over from earlier experiments.<commit_after><|endoftext|>


<commit_before>/** @babel */

import _ from 'lodash'
import fs from 'fs-plus'
import path from 'path'

export default class OpenerRegistry {
  constructor () {
    this.createOpeners()
  }

  async createOpeners () {
    const moduleDir = path.join(__dirname, 'openers')
    const entries = fs.readdirSync(moduleDir)
    this.openers = entries.map(entry => {
      const OpenerImpl = require(path.join(moduleDir, entry))
      return new OpenerImpl()
    })
    // Sort the openers into decreasing priority
    this.openers = _.orderBy(this.openers, [opener => opener.hasSynctex(), opener => opener.canOpenInBackground()], ['desc', 'desc'])
  }

  async open (filePath, texPath, lineNumber) {
    let openers = _.filter(this.openers, opener => opener.canOpen(filePath))

    if (!openers.length) {
      latex.log.warning(`No opener found that can open ${filePath}.`)
      return
    }

    let opener

    const name = atom.config.get('latex.opener')
    if (name !== 'automatic') {
      opener = _.find(openers, opener => opener.getName() === name)
    }

    if (!opener) opener = openers[0]

    return await opener.open(filePath, texPath, lineNumber)
  }
}
<commit_msg>Add feature matching logic<commit_after>/** @babel */

import _ from 'lodash'
import fs from 'fs-plus'
import path from 'path'

export default class OpenerRegistry {
  constructor () {
    this.createOpeners()
  }

  async createOpeners () {
    const moduleDir = path.join(__dirname, 'openers')
    const entries = fs.readdirSync(moduleDir)
    this.openers = entries.map(entry => {
      const OpenerImpl = require(path.join(moduleDir, entry))
      return new OpenerImpl()
    })
    // Sort the openers into decreasing priority
    this.openers = _.orderBy(this.openers, [opener => opener.hasSynctex(), opener => opener.canOpenInBackground()], ['desc', 'desc'])
  }

  async open (filePath, texPath, lineNumber) {
    const name = atom.config.get('latex.opener')
    const openResultInBackground = atom.config.get('latex.openResultInBackground')
    const enableSynctex = atom.config.get('latex.enableSynctex')

    let openers = _.filter(this.openers, opener => opener.canOpen(filePath))

    if (!openers.length) {
      latex.log.warning(`No opener found that can open ${filePath}.`)
      return
    }

    let opener

    if (name !== 'automatic') {
      opener = _.find(openers, opener => opener.getName() === name)
    }

    if (!opener && enableSynctex) {
      // If the user wants openResultInBackground also and there is an opener
      // that supports that and SyncTeX it will be the first one because of
      // the priority sort.
      opener = _.find(openers, opener => opener.hasSynctex())
    }

    if (!opener && openResultInBackground) {
      opener = _.find(openers, opener => opener.canOpenInBackground())
    }

    if (!opener) opener = openers[0]

    return await opener.open(filePath, texPath, lineNumber)
  }
}
<|endoftext|>


<commit_before>import React from 'react';
import { connect } from 'react-redux';
import {
  StyleSheet,
  View,
  Text,
  FlatList,
  TouchableHighlight,
  Image,
} from 'react-native';
import { List, ListItem } from 'react-native-elements';
import LinearGradient from 'react-native-linear-gradient';

import { colors, fonts } from 'config';

const mapStateToProps = state => ({
  authUser: state.auth.user,
});

type Props = {
  title: string,
  members: Array,
  noMembersMessage: string,
  containerStyle: Object,
  smallTitle: string,
  navigation: Object,
  authUser: Object,
};

const avatarSize = 30;

const styles = StyleSheet.create({
  container: {
    marginTop: 30,
  },
  avatarContainer: {
    backgroundColor: colors.greyLight,
    borderRadius: avatarSize / 2,
    width: avatarSize,
    height: avatarSize,
  },
  avatar: {
    borderRadius: avatarSize / 2,
    height: avatarSize,
    width: avatarSize,
  },
  list: {
    marginTop: 0,
  },
  sectionTitle: {
    color: colors.black,
    ...fonts.fontPrimaryBold,
    marginBottom: 10,
    paddingLeft: 15,
  },
  sectionTitleSmall: {
    color: colors.primaryDark,
    ...fonts.fontPrimarySemiBold,
    marginBottom: 10,
    paddingLeft: 15,
  },
  flatList: {
    paddingHorizontal: 15,
  },
  scrollGradient: {
    position: 'absolute',
    width: 15,
    height: avatarSize,
  },
});

const MembersListComponent = ({
  title,
  members,
  noMembersMessage,
  containerStyle,
  smallTitle,
  navigation,
  authUser,
}: Props) => (
  <View style={[styles.container, containerStyle && containerStyle]}>
    <Text style={smallTitle ? styles.sectionTitleSmall : styles.sectionTitle}>
      {title}
    </Text>

    {noMembersMessage &&
      !members.length && (
        <List containerStyle={styles.list}>
          <ListItem
            title={noMembersMessage}
            titleStyle={styles.listTitle}
            hideChevron
          />
        </List>
      )}
    <View>
      <FlatList
        contentContainerStyle={styles.flatList}
        data={members}
        showsHorizontalScrollIndicator={false}
        renderItem={({ item, index }) => (
          <TouchableHighlight
            onPress={() => {
              navigation.navigate(
                authUser.login === item.login ? 'AuthProfile' : 'Profile',
                {
                  user: item,
                }
              );
            }}
            underlayColor="transparent"
            style={[
              styles.avatarContainer,
              { marginRight: index < members.length - 1 ? 5 : 0 },
            ]}
          >
            <Image
              style={styles.avatar}
              source={{
                uri: item.avatar_url,
              }}
            />
          </TouchableHighlight>
        )}
        keyExtractor={item => item.id}
        horizontal
      />

      <LinearGradient
        style={[styles.scrollGradient, { left: 0 }]}
        colors={['white', 'rgba(255, 255, 255, 0)']}
        start={{ x: 0, y: 0.5 }}
        end={{ x: 1, y: 0.5 }}
      />

      <LinearGradient
        style={[styles.scrollGradient, { right: 0 }]}
        colors={['rgba(255, 255, 255, 0)', 'white']}
        start={{ x: 0, y: 0.5 }}
        end={{ x: 1, y: 0.5 }}
      />
    </View>
  </View>
);

export const MembersList = connect(mapStateToProps)(MembersListComponent);
<commit_msg>refactor: members to styled components (#606)<commit_after>import React from 'react';
import { connect } from 'react-redux';
import { View, FlatList } from 'react-native';
import { List, ListItem } from 'react-native-elements';
import LinearGradient from 'react-native-linear-gradient';
import styled from 'styled-components/native';

import { colors, fonts } from 'config';

const mapStateToProps = state => ({
  authUser: state.auth.user,
});

type Props = {
  title: string,
  members: Array,
  noMargin: boolean,
  noMembersMessage: string,
  smallTitle: string,
  navigation: Object,
  authUser: Object,
};

const avatarSize = 30;

const Container = styled.View`
  margin-top: ${props => (props.noMargin ? 0 : 30)};
  ${props =>
    props.noMargin
      ? {
          paddingTop: 0,
          paddingLeft: 0,
        }
      : null};
`;

const AvatarContainer = styled.TouchableHighlight.attrs({
  underlayColor: 'transparent',
  onPress: props => props.onPress,
})`
  background-color: ${colors.greyLight};
  border-radius: ${avatarSize / 2};
  width: ${avatarSize};
  height: ${avatarSize};
  margin-right: ${props => (props.addMarginRight ? 5 : 0)};
`;

const Avatar = styled.Image`
  border-radius: ${avatarSize / 2};
  height: ${avatarSize};
  width: ${avatarSize};
`;

const NoMembersList = styled(List).attrs({
  containerStyle: {
    marginTop: 0,
  },
})``;

const SectionTitle = styled.Text`
  color: ${props => (props.isTitleSmall ? colors.primaryDark : colors.black)};
  ${props =>
    props.isTitleSmall ? fonts.fontPrimarySemiBold : fonts.fontPrimaryBold};
  margin-bottom: 10;
  padding-left: 15;
`;

const MembersFlatList = styled(FlatList).attrs({
  contentContainerStyle: {
    paddingLeft: 15,
    paddingRight: 15,
  },
  data: props => props.data,
  showsHorizontalScrollIndicator: false,
  renderItem: props => props.renderItem,
  keyExtractor: props => props.keyExtractor,
  horizontal: true,
})``;

type GradientProps = {
  style: Object,
  gradientColors: Array,
};

const Gradient = ({ style, gradientColors }: GradientProps) => (
  <LinearGradient
    style={style}
    colors={gradientColors}
    start={{ x: 0, y: 0.5 }}
    end={{ x: 1, y: 0.5 }}
  />
);

const ScrollGradient = styled(Gradient)`
  position: absolute;
  width: 15;
  height: ${avatarSize};
  ${props => props.position};
`;

const MembersListComponent = ({
  title,
  members,
  noMembersMessage,
  noMargin,
  smallTitle,
  navigation,
  authUser,
}: Props) => (
  <Container noMargin={noMargin}>
    <SectionTitle isTitleSmall={smallTitle}>{title}</SectionTitle>

    {noMembersMessage &&
      !members.length && (
        <NoMembersList>
          <ListItem title={noMembersMessage} hideChevron />
        </NoMembersList>
      )}
    <View>
      <MembersFlatList
        data={members}
        renderItem={({ item, index }) => (
          <AvatarContainer
            onPress={() => {
              navigation.navigate(
                authUser.login === item.login ? 'AuthProfile' : 'Profile',
                {
                  user: item,
                }
              );
            }}
            addMarginRight={index < members.length - 1}
          >
            <Avatar
              source={{
                uri: item.avatar_url,
              }}
            />
          </AvatarContainer>
        )}
        keyExtractor={item => item.id}
      />

      <ScrollGradient
        position={{ left: 0 }}
        gradientColors={['white', 'rgba(255, 255, 255, 0)']}
      />

      <ScrollGradient
        position={{ right: 0 }}
        gradientColors={['rgba(255, 255, 255, 0)', 'white']}
      />
    </View>
  </Container>
);

export const MembersList = connect(mapStateToProps)(MembersListComponent);
<|endoftext|>


<commit_before>(function () {
    'use strict';
    const userNameInput = document.getElementById('user-name');
    const assessmentButton = document.getElementById('assessment');
    const resultDivided = document.getElementById('result-area');
    const tweetDivided = document.getElementById('tweet-area');

    /**
    * 指定した要素の子どもを全て除去する
    * @param {HTMLElement} element HTMLの要素
    */
    function removeAllChildren(element) {
        while (element.firstChild) { // 子どもの要素があるかぎり削除
            element.removeChild(element.firstChild);
        }
    }

    assessmentButton.onclick = () => {
        const userName = userNameInput.value;
        if (userName.length === 0) { // 名前が空の時は処理を終了する
            return;
        }

        // 診断結果表示エリアの作成
        removeAllChildren(resultDivided);
        const header = document.createElement('h3');
        header.innerText = '診断結果';
        resultDivided.appendChild(header);

        const paragraph = document.createElement('p');
        const result = assessment(userName);
        paragraph.innerText = result;
        resultDivided.appendChild(paragraph);

        // ツイートエリアの作成
        removeAllChildren(tweetDivided);
        const anchor = document.createElement('a');
        const hrefValue = 'https://twitter.com/intent/tweet?button_hashtag=%E3%81%82%E3%81%AA%E3%81%9F%E3%81%AE%E3%81%84%E3%81%84%E3%81%A8%E3%81%93%E3%82%8D&text='
        + encodeURIComponent(result);
        anchor.setAttribute('href', hrefValue);
        anchor.className = 'twitter-hashtag-button';
        anchor.innerText = 'Tweet #%E3%81%82%E3%81%AA%E3%81%9F%E3%81%AE%E3%81%84%E3%81%84%E3%81%A8%E3%81%93%E3%82%8D';
        tweetDivided.appendChild(anchor);

        twttr.widgets.load();
    };

    userNameInput.onkeydown = (event) => {
        if (event.keyCode === 13) {
            assessmentButton.onclick();
        }
    };

    const answers = [
        '{userName}のいいところは声です。{userName}の特徴的な声はみなを惹きつけ、心に残ります。',
        '{userName}のいいところはまなざしです。{userName}に見つめられた人は、気になって仕方がないでしょう。',
        '{userName}のいいところは情熱です。{userName}の情熱に周りの人は感化されます。',
        '{userName}のいいところは厳しさです。{userName}の厳しさがものごとをいつも成功に導きます。',
        '{userName}のいいところは知識です。博識な{userName}を多くの人が頼りにしています。',
        '{userName}のいいところはユニークさです。{userName}だけのその特徴が皆を楽しくさせます。',
        '{userName}のいいところは用心深さです。{userName}の洞察に、多くの人が助けられます。',
        '{userName}のいいところは見た目です。内側から溢れ出る{userName}の良さに皆が気を惹かれます。',
        '{userName}のいいところは決断力です。{userName}がする決断にいつも助けられる人がいます。',
        '{userName}のいいところは思いやりです。{userName}に気をかけてもらった多くの人が感謝しています。',
        '{userName}のいいところは感受性です。{userName}が感じたことに皆が共感し、わかりあうことができます。',
        '{userName}のいいところは節度です。強引すぎない{userName}の考えに皆が感謝しています。',
        '{userName}のいいところは好奇心です。新しいことに向かっていく{userName}の心構えが多くの人に魅力的に映ります。',
        '{userName}のいいところは気配りです。{userName}の配慮が多くの人を救っています。',
        '{userName}のいいところはその全てです。ありのままの{userName}自身がいいところなのです。',
        '{userName}のいいところは自制心です。やばいと思ったときにしっかりと衝動を押さえられる{userName}が皆から評価されています。'
    ];

    /**
    * 名前の文字列を渡すと診断結果を返す関数
    * @param {string} userName ユーザーの名前
    * @return {string} 診断結果
    */
    function assessment(userName) {
        // 全文字のコード番号を取得してそれを足し合わせる
        let sumOfcharCode = 0;
        for (let i = 0; i < userName.length; i++) {
            sumOfcharCode = sumOfcharCode + userName.charCodeAt(i);
        }

        // 文字のコード番号の合計を回答の数で割って添字の数値を求める
        const index = sumOfcharCode % answers.length;
        let result = answers[index];

        result = result.replace(/{userName}/g, userName);
        return result;
    }

    // テストコード
    console.assert(
        assessment('太郎') === '太郎のいいところは決断力です。太郎がする決断にいつも助けられる人がいます。',
        '診断結果の文言の特定の部分を名前に置き換える処理が正しくありません。'
    );
    console.assert(
        assessment('太郎') === assessment('太郎'),
        '入力が同じ名前なら同じ診断結果を出力する処理が正しくありません。'
    );
})();
<commit_msg>#1 に対する対応を行いました。<commit_after>(function () {
    'use strict';
    const userNameInput = document.getElementById('user-name');
    const assessmentButton = document.getElementById('assessment');
    const resultDivided = document.getElementById('result-area');
    const tweetDivided = document.getElementById('tweet-area');

    /**
    * 指定した要素の子どもを全て除去する
    * @param {HTMLElement} element HTMLの要素
    */
    function removeAllChildren(element) {
        while (element.firstChild) { // 子どもの要素があるかぎり削除
            element.removeChild(element.firstChild);
        }
    }

    assessmentButton.onclick = () => {
        const userName = userNameInput.value;
        if (userName.length === 0) { // 名前が空の時は処理を終了する
            return;
        }

        // 診断結果表示エリアの作成
        removeAllChildren(resultDivided);
        const header = document.createElement('h3');
        header.innerText = '診断結果';
        resultDivided.appendChild(header);

        const paragraph = document.createElement('p');
        const result = assessment(userName);
        paragraph.innerText = result;
        resultDivided.appendChild(paragraph);

        // ツイートエリアの作成
        removeAllChildren(tweetDivided);
        const anchor = document.createElement('a');
        const hrefValue = 'https://twitter.com/intent/tweet?button_hashtag=%E3%81%82%E3%81%AA%E3%81%9F%E3%81%AE%E3%81%84%E3%81%84%E3%81%A8%E3%81%93%E3%82%8D&text='
        + encodeURIComponent(result);
        anchor.setAttribute('href', hrefValue);
        anchor.className = 'twitter-hashtag-button';
        anchor.innerText = 'Tweet #%E3%81%82%E3%81%AA%E3%81%9F%E3%81%AE%E3%81%84%E3%81%84%E3%81%A8%E3%81%93%E3%82%8D';
        tweetDivided.appendChild(anchor);

        twttr.widgets.load();
    };

    userNameInput.onkeydown = (event) => {
        if (event.keyCode === 13) {
            assessmentButton.onclick();
        }
    };

    const answers = [
        '{userName}のいいところは声です。{userName}の特徴的な声はみなを惹きつけ、心に残ります。',
        '{userName}のいいところはまなざしです。{userName}に見つめられた人は、気になって仕方がないでしょう。',
        '{userName}のいいところは情熱です。{userName}の情熱に周りの人は感化されます。',
        '{userName}のいいところは厳しさです。{userName}の厳しさがものごとをいつも成功に導きます。',
        '{userName}のいいところは知識です。博識な{userName}を多くの人が頼りにしています。',
        '{userName}のいいところはユニークさです。{userName}だけのその特徴が皆を楽しくさせます。',
        '{userName}のいいところは用心深さです。{userName}の洞察に、多くの人が助けられます。',
        '{userName}のいいところは見た目です。内側から溢れ出る{userName}の良さに皆が気を惹かれます。',
        '{userName}のいいところは決断力です。{userName}がする決断にいつも助けられる人がいます。',
        '{userName}のいいところは思いやりです。{userName}に気をかけてもらった多くの人が感謝しています。',
        '{userName}のいいところは感受性です。{userName}が感じたことに皆が共感し、わかりあうことができます。',
        '{userName}のいいところは節度です。強引すぎない{userName}の考えに皆が感謝しています。',
        '{userName}のいいところは好奇心です。新しいことに向かっていく{userName}の心構えが多くの人に魅力的に映ります。',
        '{userName}のいいところは気配りです。{userName}の配慮が多くの人を救っています。',
        '{userName}のいいところはその全てです。ありのままの{userName}自身がいいところなのです。',
        '{userName}のいいところは自制心です。やばいと思ったときにしっかりと衝動を押さえられる{userName}が皆から評価されています。'
        '{userName}のいいところは優しさです。あなたの優しい雰囲気や立ち振舞に多くの人が癒やされています。'
    ];

    /**
    * 名前の文字列を渡すと診断結果を返す関数
    * @param {string} userName ユーザーの名前
    * @return {string} 診断結果
    */
    function assessment(userName) {
        // 全文字のコード番号を取得してそれを足し合わせる
        let sumOfcharCode = 0;
        for (let i = 0; i < userName.length; i++) {
            sumOfcharCode = sumOfcharCode + userName.charCodeAt(i);
        }

        // 文字のコード番号の合計を回答の数で割って添字の数値を求める
        const index = sumOfcharCode % answers.length;
        let result = answers[index];

        result = result.replace(/{userName}/g, userName);
        return result;
    }

    // テストコード
    console.assert(
        assessment('太郎') === '太郎のいいところは決断力です。太郎がする決断にいつも助けられる人がいます。',
        '診断結果の文言の特定の部分を名前に置き換える処理が正しくありません。'
    );
    console.assert(
        assessment('太郎') === assessment('太郎'),
        '入力が同じ名前なら同じ診断結果を出力する処理が正しくありません。'
    );
})();
<|endoftext|>


<commit_before>console.log('succynct:content_twitter.js');
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-2706568-45']);
_gaq.push(['_trackPageview']);

$('input.submit').before('<input class="button selected submit succynct-submit" value="Post to ADN">');
$('.succynct-submit').click(function() {
  chrome.extension.sendMessage({
    method: 'post',
    action: 'posts',
    data: { status: $('#status').val() }
  }, function(response) { });
});<commit_msg>disabled tweet intent until it can get refactored to work<commit_after>console.log('succynct:content_twitter.js');
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-2706568-45']);
_gaq.push(['_trackPageview']);

$('input.submit').before('<input class="button selected submit succynct-submit" value="Post to ADN">');
$('.succynct-submit').click(function() {
  alert('@abraham was lazy and broke that. Yell at him to fix it.');
  return false;
  chrome.extension.sendMessage({
    method: 'post',
    action: 'posts',
    data: { status: $('#status').val() }
  }, function(response) { });
});<|endoftext|>


<commit_before>const kProtoHopOpts  = 0;   ///< IPv6 Hop-by-Hop Option
const kProtoTcp      = 6;   ///< Transmission Control Protocol
const kProtoUdp      = 17;  ///< User Datagram
const kProtoIp6      = 41;  ///< IPv6 encapsulation
const kProtoRouting  = 43;  ///< Routing Header for IPv6
const kProtoFragment = 44;  ///< Fragment Header for IPv6
const kProtoIcmp6    = 58;  ///< ICMP for IPv6
const kProtoNone     = 59;  ///< No Next Header for IPv6
const kProtoDstOpts  = 60;  ///< Destination Options for IPv6

class ExtensionHeader {
  constructor(type, length, value) {
    this.type = type;
    this.length = length;
    this.value = value;
  }
}

function parse(buf, packet)
{
  let header = {
    version: buf[0] >> 4,
    trafficClass: (((buf[0] & 0x0f) << 4) | (buf[1] >> 4)),
    flowLabel: ((buf[1] & 0x0f) << 16) | buf.readUInt16BE(2),
    length: buf.readUInt16BE(4),
    nextHeader: buf[6],
    hopLimit: buf[7],
    src: buf.slice(8, 8 + 16),
    dst: buf.slice(24, 40)
  };

  let offset = 40;
  let payload = null;
  let headers = [];

  for (let nextHeader = header.nextHeader; nextHeader !== false;) {
    switch (nextHeader) {
    case kProtoTcp:
    case kProtoUdp:
    case kProtoIcmp6:
    case kProtoIp6:
      payload = buf.slice(offset);
      nextHeader = false;
      break;

    default:
      length = buf[offset + 1];
      value = buf.slice(offset + 2, offset + (length + 1) * 8);
      headers.push(new ExtensionHeader(nextHeader, length, value));
      nextHeader = buf[offset];
      offset += (length + 1) * 8;
      break;
    }
  }

  return {
    header: header,
    headers: headers,
    payload: payload
  };
}

exports.parse = parse;
<commit_msg>ip6 link to udp<commit_after>const kProtoHopOpts  = 0;   ///< IPv6 Hop-by-Hop Option
const kProtoTcp      = 6;   ///< Transmission Control Protocol
const kProtoUdp      = 17;  ///< User Datagram
const kProtoIp6      = 41;  ///< IPv6 encapsulation
const kProtoRouting  = 43;  ///< Routing Header for IPv6
const kProtoFragment = 44;  ///< Fragment Header for IPv6
const kProtoIcmp6    = 58;  ///< ICMP for IPv6
const kProtoNone     = 59;  ///< No Next Header for IPv6
const kProtoDstOpts  = 60;  ///< Destination Options for IPv6

class ExtensionHeader {
  constructor(type, length, value) {
    this.type = type;
    this.length = length;
    this.value = value;
  }
}

function parse(buf, packet)
{
  let header = {
    version: buf[0] >> 4,
    trafficClass: (((buf[0] & 0x0f) << 4) | (buf[1] >> 4)),
    flowLabel: ((buf[1] & 0x0f) << 16) | buf.readUInt16BE(2),
    length: buf.readUInt16BE(4),
    nextHeader: buf[6],
    hopLimit: buf[7],
    src: buf.slice(8, 8 + 16),
    dst: buf.slice(24, 40)
  };

  let offset = 40;
  let payload = null;
  let headers = [];

  for (let nextHeader = header.nextHeader; nextHeader !== false;) {
    switch (nextHeader) {
    case kProtoTcp:
    case kProtoUdp:
    case kProtoIcmp6:
    case kProtoIp6:
      payload = buf.slice(offset);
      nextHeader = false;
      break;

    default:
      length = buf[offset + 1];
      value = buf.slice(offset + 2, offset + (length + 1) * 8);
      headers.push(new ExtensionHeader(nextHeader, length, value));
      nextHeader = buf[offset];
      offset += (length + 1) * 8;
      break;
    }
  }

  return {
    header: header,
    headers: headers,
    payload: payload
  };
}

let nexts = [{
    id: 'net/udp',
}];

exports.parse = parse;
exports.nexts = nexts;
<|endoftext|>


<commit_before>import resources from './loader.js'
import config from './config.js'
import * as levels from './levels.js'
import * as Cars from './Cars.js';
import {key} from './Input.js'
import {screenShake} from './ScreenShake.js'

//TODO: Refactor this so there is less repeated text
class Menu extends PIXI.Container {
  constructor() {
    super()
    this._options = [];
    this.selectedOption = 0;

    this._background = new PIXI.Sprite(resources.Default.texture)
    this._background.width = config.renderer.width
    this._background.height = config.renderer.height
    this._background.tint = 0x040404
    this.addChild(this._background)

    this._text = new PIXI.Text('MEGA ALPHA EDITION',{font : '24px Arial', fill : 0xFFFFFF, align : 'center'})
    this._text.x = 20
    this._text.y = 20
    this.addChild(this._text)

    this._pointer = new PIXI.Sprite(resources.MenuArrow.texture)
    this._pointer.width = 16
    this._pointer.height = 16
    this._pointer.visible = false
    this.addChild(this._pointer)
  }

  // XXX(Fishrock123) onInputChange MUST be a *regular* function so it can inherit scope
  addOption(text, opts={}){
    let i = this._options.length;

    if (typeof opts === 'function') {
      opts = { callback: opts }
    }

    this._options.push(new Option(opts.callback, opts.onInputChange, opts.update, opts.state));
    this._options[i].textObj = new PIXI.Text(text,{font : '24px Arial', fill : 0xFFFFFF, align : 'center'});
    this._options[i].textObj.x = config.renderer.width/2 - this._options[i].textObj.width/2;
    this._options[i].textObj.y = 400 + 50*i;
    this.addChild(this._options[i].textObj);

    // Load pointer
    if (i === 0) {
      this._pointer.visible = true
      this._pointer.x = this._options[0].textObj.x - 20
      this.menuSpriteY = this._pointer.y = this._options[0].textObj.y + 5
    }
  }

  // Can be implemented in submenus
  // Return API:
  //
  // Do nothing: `return`
  // Prevent inputChange from reaching other menus (below, earlier in `menus`):
  //   `return { done: true }``
  // Tell the game it should (Boolean) playing: `return { _playing: <boolean> }`
  //
  onInputChange(menus){
    if (key('down')) {
      this.selectedOption += 1;
      if(this.selectedOption == this._options.length){
        this.selectedOption = 0;
      }
      const option = this._options[this.selectedOption]
      this._pointer.x = option.textObj.x - 20
      this.menuSpriteY = this._pointer.y = option.textObj.y + 5
      return { done: true }
    }

    if (key('up')) {
      this.selectedOption -= 1;
      if(this.selectedOption == -1){
        this.selectedOption = this._options.length-1;
      }
      const option = this._options[this.selectedOption]
      this._pointer.x = option.textObj.x - 20
      this.menuSpriteY = this._pointer.y = option.textObj.y + 5
      return { done: true }
    }

    const option = this._options[this.selectedOption]
    if (key('enter') && option.callback) {
      return option.callback(menus);
    }

    if (option.onInputChange) {
      option.onInputChange()
    }

    return
  }

  update(now, delta) {
    const option = this._options[this.selectedOption]
    if (option.update) {
      option.update(now, delta)
    }

    const menuSpriteThing = (now / 25) % 28

    if (menuSpriteThing < 14) {
      this._pointer.height = 16 - menuSpriteThing
      this._pointer.y = this.menuSpriteY + menuSpriteThing / 2
    } else {
      this._pointer.height = 2 + menuSpriteThing - 14
      this._pointer.y = this.menuSpriteY + 14 - menuSpriteThing / 2
    }
  }
}

export class KeyMapMenu extends Menu {
  constructor(){
    super()
    this.addOption('Back', (menus) => {
      menus.splice(menus.indexOf(this))
      config.stage.removeChild(this)

      return { done: true };
    })
  }
}

export class OptionsMenu extends Menu {
  constructor(){
    super()
    this.addOption(`Master Volume: ${config.masterVolume * 100}%`, {
      state: {
        accumulator: 0
      },
      update(now, delta) {
        this.state.accumulator += delta
        if (this.state.accumulator < 100) return
        this.state.accumulator = 0

        /// "this" scope is the actual Option
        if (key('left')) {
          if ((config.masterVolume -= 0.05) < 0) config.masterVolume = 0

          if (config.masterVolume === 0) {
            this.textObj.text = 'Master Volume: 0%'
          } else {
            this.textObj.text = `Master Volume: ${Math.round(config.masterVolume * 100)}%`
          }
        }
        if (key('right')) {
          if ((config.masterVolume += 0.05) > 1) config.masterVolume = 1
            this.textObj.text = `Master Volume: ${Math.round(config.masterVolume * 100)}%`
        }
      }
    })
    this.addOption(`Screen Shake: ${config.screenShake * 100}%`, {
      state: {
        accumulator: 0
      },
      update(now, delta) {
        this.state.accumulator += delta
        if (this.state.accumulator < 100) return
        this.state.accumulator = 0

        /// "this" scope is the actual Option
        if (key('left')) {
          if ((config.screenShake -= 0.05) < 0) config.screenShake = 0

          if (config.screenShake === 0) {
            this.textObj.text = 'Screen Shake: None'
          } else {
            this.textObj.text = `Screen Shake: ${Math.round(config.screenShake * 100)}%`
          }
          screenShake()
        }
        if (key('right')) {
          if ((config.screenShake += 0.05) > 2) config.screenShake = 2

          if (config.screenShake === 2) {
            this.textObj.text = 'Screen Shake: Vlambeer'
          } else {
            this.textObj.text = `Screen Shake: ${Math.round(config.screenShake * 100)}%`
          }
          screenShake()
        }
      }
    })
    this.addOption('Key Mapping', (menus) => {
      const newMenu = new KeyMapMenu()
      menus.push(newMenu)
      config.stage.addChild(newMenu)

      return { done: true }
    })

    this.addOption('Back', (menus) => {
      menus.splice(menus.indexOf(this))
      config.stage.removeChild(this)

      return { done: true };
    })
  }
}

export class MainMenu extends Menu {
  constructor() {
    super()

    const renderer = config.renderer

    this._options = [];
    this.selectedOption = 0;

    this.addOption("Play", (menus) => {
      menus.splice(menus.indexOf(this))
      config.stage.removeChild(this)

      return { _playing: true, _level: levels.test };
    });

    this.addOption("Options", (menus) => {

      const newMenu = new OptionsMenu()
      menus.push(newMenu)
      config.stage.addChild(newMenu)

      return
    });

    this._title = new PIXI.Text('Parky Park Park',{font : '24px Arial', fill : 0xFFFFFF, align : 'center'})
    this._title.x = renderer.width/2 - this._title.width/2
    this._title.y = 200
    this.addChild(this._title)

    this._splash = new PIXI.Text('Wow',{font : '30px Arial', fill : 0xFFFF00, align : 'center'})
    this._splash.x = this._title.x + this._title.width - this._splash.width/2
    this._splash.y = this._title.y + this._title.height
    this._splash.rotation = 100
    this.addChild(this._splash)
  }

  update(now, delta) {
    super.update(now, delta)

    if ((now / 2000) % 1 <= 0.5) {
      this._splash.scale.x = 1.5 - (now / 2000) % 1
      this._splash.scale.y = 1.5 - (now / 2000) % 1
    } else {
      this._splash.scale.x = 0.5 + (now / 2000) % 1
      this._splash.scale.y = 0.5 + (now / 2000) % 1
    }
  }
}

// Let the compiler optimize a bit
function Option(callback, onInputChange, update, state) {
  this.callback = callback
  this.onInputChange = onInputChange
  this.update = update
  this.state = state
  this.textObj = null
}
<commit_msg>fix(menus): always display rounded option %'s<commit_after>import resources from './loader.js'
import config from './config.js'
import * as levels from './levels.js'
import * as Cars from './Cars.js';
import {key} from './Input.js'
import {screenShake} from './ScreenShake.js'

//TODO: Refactor this so there is less repeated text
class Menu extends PIXI.Container {
  constructor() {
    super()
    this._options = [];
    this.selectedOption = 0;

    this._background = new PIXI.Sprite(resources.Default.texture)
    this._background.width = config.renderer.width
    this._background.height = config.renderer.height
    this._background.tint = 0x040404
    this.addChild(this._background)

    this._text = new PIXI.Text('MEGA ALPHA EDITION',{font : '24px Arial', fill : 0xFFFFFF, align : 'center'})
    this._text.x = 20
    this._text.y = 20
    this.addChild(this._text)

    this._pointer = new PIXI.Sprite(resources.MenuArrow.texture)
    this._pointer.width = 16
    this._pointer.height = 16
    this._pointer.visible = false
    this.addChild(this._pointer)
  }

  // XXX(Fishrock123) onInputChange MUST be a *regular* function so it can inherit scope
  addOption(text, opts={}){
    let i = this._options.length;

    if (typeof opts === 'function') {
      opts = { callback: opts }
    }

    this._options.push(new Option(opts.callback, opts.onInputChange, opts.update, opts.state));
    this._options[i].textObj = new PIXI.Text(text,{font : '24px Arial', fill : 0xFFFFFF, align : 'center'});
    this._options[i].textObj.x = config.renderer.width/2 - this._options[i].textObj.width/2;
    this._options[i].textObj.y = 400 + 50*i;
    this.addChild(this._options[i].textObj);

    // Load pointer
    if (i === 0) {
      this._pointer.visible = true
      this._pointer.x = this._options[0].textObj.x - 20
      this.menuSpriteY = this._pointer.y = this._options[0].textObj.y + 5
    }
  }

  // Can be implemented in submenus
  // Return API:
  //
  // Do nothing: `return`
  // Prevent inputChange from reaching other menus (below, earlier in `menus`):
  //   `return { done: true }``
  // Tell the game it should (Boolean) playing: `return { _playing: <boolean> }`
  //
  onInputChange(menus){
    if (key('down')) {
      this.selectedOption += 1;
      if(this.selectedOption == this._options.length){
        this.selectedOption = 0;
      }
      const option = this._options[this.selectedOption]
      this._pointer.x = option.textObj.x - 20
      this.menuSpriteY = this._pointer.y = option.textObj.y + 5
      return { done: true }
    }

    if (key('up')) {
      this.selectedOption -= 1;
      if(this.selectedOption == -1){
        this.selectedOption = this._options.length-1;
      }
      const option = this._options[this.selectedOption]
      this._pointer.x = option.textObj.x - 20
      this.menuSpriteY = this._pointer.y = option.textObj.y + 5
      return { done: true }
    }

    const option = this._options[this.selectedOption]
    if (key('enter') && option.callback) {
      return option.callback(menus);
    }

    if (option.onInputChange) {
      option.onInputChange()
    }

    return
  }

  update(now, delta) {
    const option = this._options[this.selectedOption]
    if (option.update) {
      option.update(now, delta)
    }

    const menuSpriteThing = (now / 25) % 28

    if (menuSpriteThing < 14) {
      this._pointer.height = 16 - menuSpriteThing
      this._pointer.y = this.menuSpriteY + menuSpriteThing / 2
    } else {
      this._pointer.height = 2 + menuSpriteThing - 14
      this._pointer.y = this.menuSpriteY + 14 - menuSpriteThing / 2
    }
  }
}

export class KeyMapMenu extends Menu {
  constructor(){
    super()
    this.addOption('Back', (menus) => {
      menus.splice(menus.indexOf(this))
      config.stage.removeChild(this)

      return { done: true };
    })
  }
}

export class OptionsMenu extends Menu {
  constructor(){
    super()
    this.addOption(`Master Volume: ${Math.round(config.masterVolume * 100)}%`, {
      state: {
        accumulator: 0
      },
      update(now, delta) {
        // "this" scope is the actual Option
        this.state.accumulator += delta
        if (this.state.accumulator < 100) return
        this.state.accumulator = 0

        if (key('left')) {
          if ((config.masterVolume -= 0.05) < 0) config.masterVolume = 0

          if (config.masterVolume === 0) {
            this.textObj.text = 'Master Volume: 0%'
          } else {
            this.textObj.text = `Master Volume: ${Math.round(config.masterVolume * 100)}%`
          }
        }
        if (key('right')) {
          if ((config.masterVolume += 0.05) > 1) config.masterVolume = 1
            this.textObj.text = `Master Volume: ${Math.round(config.masterVolume * 100)}%`
        }
      }
    })
    this.addOption(`Screen Shake: ${Math.round(config.screenShake * 100)}%`, {
      state: {
        accumulator: 0
      },
      update(now, delta) {
        // "this" scope is the actual Option
        this.state.accumulator += delta
        if (this.state.accumulator < 100) return
        this.state.accumulator = 0

        if (key('left')) {
          if ((config.screenShake -= 0.05) < 0) config.screenShake = 0

          if (config.screenShake === 0) {
            this.textObj.text = 'Screen Shake: None'
          } else {
            this.textObj.text = `Screen Shake: ${Math.round(config.screenShake * 100)}%`
          }
          screenShake()
        }
        if (key('right')) {
          if ((config.screenShake += 0.05) > 2) config.screenShake = 2

          if (config.screenShake === 2) {
            this.textObj.text = 'Screen Shake: Vlambeer'
          } else {
            this.textObj.text = `Screen Shake: ${Math.round(config.screenShake * 100)}%`
          }
          screenShake()
        }
      }
    })
    this.addOption('Key Mapping', (menus) => {
      const newMenu = new KeyMapMenu()
      menus.push(newMenu)
      config.stage.addChild(newMenu)

      return { done: true }
    })

    this.addOption('Back', (menus) => {
      menus.splice(menus.indexOf(this))
      config.stage.removeChild(this)

      return { done: true }
    })
  }
}

export class MainMenu extends Menu {
  constructor() {
    super()

    const renderer = config.renderer

    this._options = [];
    this.selectedOption = 0;

    this.addOption("Play", (menus) => {
      menus.splice(menus.indexOf(this))
      config.stage.removeChild(this)

      return { _playing: true, _level: levels.test };
    });

    this.addOption("Options", (menus) => {

      const newMenu = new OptionsMenu()
      menus.push(newMenu)
      config.stage.addChild(newMenu)

      return
    });

    this._title = new PIXI.Text('Parky Park Park',{font : '24px Arial', fill : 0xFFFFFF, align : 'center'})
    this._title.x = renderer.width/2 - this._title.width/2
    this._title.y = 200
    this.addChild(this._title)

    this._splash = new PIXI.Text('Wow',{font : '30px Arial', fill : 0xFFFF00, align : 'center'})
    this._splash.x = this._title.x + this._title.width - this._splash.width/2
    this._splash.y = this._title.y + this._title.height
    this._splash.rotation = 100
    this.addChild(this._splash)
  }

  update(now, delta) {
    super.update(now, delta)

    if ((now / 2000) % 1 <= 0.5) {
      this._splash.scale.x = 1.5 - (now / 2000) % 1
      this._splash.scale.y = 1.5 - (now / 2000) % 1
    } else {
      this._splash.scale.x = 0.5 + (now / 2000) % 1
      this._splash.scale.y = 0.5 + (now / 2000) % 1
    }
  }
}

// Let the compiler optimize a bit
function Option(callback, onInputChange, update, state) {
  this.callback = callback
  this.onInputChange = onInputChange
  this.update = update
  this.state = state
  this.textObj = null
}
<|endoftext|>