<commit_before>/*

index.js - "tart-tracing": Tracing configuration implementation

The MIT License (MIT)

Copyright (c) 2013 Dale Schumacher, Tristan Slominski

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

*/
"use strict";

var tart = require('tart');

/*
  * `options`: _Object_ _(Default: undefined)_ Optional overrides.  WARNING:
      Implementation of `enqueue` and `dequeue` are tightly coupled and should
      be overridden together.
    * `constructConfig`: _Function_ _(Default: `function (options) {}`)_
        `function (options) {}` Configuration creation function that
        is given `options`. It should return a capability `function (behavior) {}`
        to create new actors.
    * `enqueue`: _Function_ `function (eventQueue, events){}` Function that
        enqueues the new `events` onto the `eventQueue` in place, causing
        side-effects _(Example: `function (eventQueue, events){
        Array.prototype.push.apply(eventQueue, events); }`)_.
    * `dequeue`: _Function_ `function (eventQueue){}` Function that returns next
        event to be dispatched given an `eventQueue`
        _(Example: `function (eventQueue){ return eventQueue.shift(); }`)_.
  * Return: _Object_ The tracing control object.
    * `dispatch`: _Function_ `function () {}` Function to call in order to
        dispatch a single event.
    * `history`: _Array_ An array of effects that represents the history of
        execution.
    * `effect`: _Object_ Accumulated effects not yet committed to history.
    * `sponsor`: _Function_ `function (behavior) {}` A capability to create
        new actors.
*/
module.exports.tracing = function tracing(options) {
    options = options || {};

    var events = [];
    var history = [];

    options.enqueue = options.enqueue || function enqueue(eventQueue, events) {
        eventQueue.push(events.slice());  // clone event batch
    };

    options.dequeue = options.dequeue || function dequeue(eventQueue) {
        while (eventQueue.length > 0) {
            var batch = eventQueue[0];
            if (batch.length > 0) {
                return batch.shift();  // return next event
            }
            eventQueue.shift();
        }
        return false;
    };

    /*
    Conditionally apply accumulated external effects.
    */
    var applyExternalEffect = function applyExternalEffect(effect) {
        var record = false;
        if (effect.sent.length > 0) {
            options.enqueue(events, effect.sent);
            record = true;
        }
        if (effect.created.length > 0) {
            record = true;
        }
        if (record) {
            recordEffect(effect);
        }
    };

    /*
    Apply effects from executing an actor behavior.
    */
    var applyBehaviorEffect = function applyBehaviorEffect(effect) {
        if (effect.sent.length > 0) {
            options.enqueue(events, effect.sent);
        }
        recordEffect(effect);
    };

    /*
    Record `effect` in `exports.history`
    and initialize a new `export.effect` object.
    */
    var recordEffect = function recordEffect(effect) {
        history.push(effect);
        options.effect = {
            created: [],
            sent: []
        };
    };

    /*
      * Return: _Effect_ or `false`. Effect of dispatching the next `event` or
          `false` if no events exists for dispatch.
    */
    var tracingDispatch = function tracingDispatch() {
        applyExternalEffect(options.effect);  // WARNING: may change `options.effect`
        var event = options.dequeue(events);
        if (!event) {
            return false;
        }
        var effect = options.effect;
        effect.event = event;
        try {
            var behavior = event.context.behavior;
            effect.behavior = behavior;
            event.context.behavior(event.message);  // execute actor behavior
            if (behavior !== event.context.behavior) {
                effect.became = event.context.behavior;
            }
        } catch (exception) {
            effect.exception = exception;
        }
        applyBehaviorEffect(effect);  // WARNING: will change `options.effect`
        return effect;
    };

    var unused = function unused() {
        throw new Error('This pluggable hook should not be called');
    };

    options.constructConfig = options.constructConfig || function constructConfig(options) {
        var config = function create(behavior) {
            var actor = function send(message) {
                var event = {
                    cause: options.effect.event,
                    message: message,
                    context: context
                };
                options.effect.sent.push(event);
            };
            var context = {
                self: actor,
                behavior: behavior,
                sponsor: config
            };
            options.effect.created.push(context);
            return actor;
        };
        return config;
    };

    options.dispatch = unused;
    options.deliver = unused;
    options.effect = {
        created: [],
        sent: []
    };

    var exports = {
        effect: options.effect,
        history: history,
        dispatch: tracingDispatch,
        sponsor: tart.pluggable(options)
    };

    return exports;
};<commit_msg>'exports' is no longer necessary.<commit_after>/*

index.js - "tart-tracing": Tracing configuration implementation

The MIT License (MIT)

Copyright (c) 2013 Dale Schumacher, Tristan Slominski

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

*/
"use strict";

var tart = require('tart');

/*
  * `options`: _Object_ _(Default: undefined)_ Optional overrides.  WARNING:
      Implementation of `enqueue` and `dequeue` are tightly coupled and should
      be overridden together.
    * `constructConfig`: _Function_ _(Default: `function (options) {}`)_
        `function (options) {}` Configuration creation function that
        is given `options`. It should return a capability `function (behavior) {}`
        to create new actors.
    * `enqueue`: _Function_ `function (eventQueue, events){}` Function that
        enqueues the new `events` onto the `eventQueue` in place, causing
        side-effects _(Example: `function (eventQueue, events){
        Array.prototype.push.apply(eventQueue, events); }`)_.
    * `dequeue`: _Function_ `function (eventQueue){}` Function that returns next
        event to be dispatched given an `eventQueue`
        _(Example: `function (eventQueue){ return eventQueue.shift(); }`)_.
  * Return: _Object_ The tracing control object.
    * `dispatch`: _Function_ `function () {}` Function to call in order to
        dispatch a single event.
    * `history`: _Array_ An array of effects that represents the history of
        execution.
    * `effect`: _Object_ Accumulated effects not yet committed to history.
    * `sponsor`: _Function_ `function (behavior) {}` A capability to create
        new actors.
*/
module.exports.tracing = function tracing(options) {
    options = options || {};

    var events = [];
    var history = [];

    options.enqueue = options.enqueue || function enqueue(eventQueue, events) {
        eventQueue.push(events.slice());  // clone event batch
    };

    options.dequeue = options.dequeue || function dequeue(eventQueue) {
        while (eventQueue.length > 0) {
            var batch = eventQueue[0];
            if (batch.length > 0) {
                return batch.shift();  // return next event
            }
            eventQueue.shift();
        }
        return false;
    };

    /*
    Conditionally apply accumulated external effects.
    */
    var applyExternalEffect = function applyExternalEffect(effect) {
        var record = false;
        if (effect.sent.length > 0) {
            options.enqueue(events, effect.sent);
            record = true;
        }
        if (effect.created.length > 0) {
            record = true;
        }
        if (record) {
            recordEffect(effect);
        }
    };

    /*
    Apply effects from executing an actor behavior.
    */
    var applyBehaviorEffect = function applyBehaviorEffect(effect) {
        if (effect.sent.length > 0) {
            options.enqueue(events, effect.sent);
        }
        recordEffect(effect);
    };

    /*
    Record `effect` in `history`
    and initialize a new `options.effect` object.
    */
    var recordEffect = function recordEffect(effect) {
        history.push(effect);
        options.effect = {
            created: [],
            sent: []
        };
    };

    /*
      * Return: _Effect_ or `false`. Effect of dispatching the next `event` or
          `false` if no events exists for dispatch.
    */
    var tracingDispatch = function tracingDispatch() {
        applyExternalEffect(options.effect);  // WARNING: may change `options.effect`
        var event = options.dequeue(events);
        if (!event) {
            return false;
        }
        var effect = options.effect;
        effect.event = event;
        try {
            var behavior = event.context.behavior;
            effect.behavior = behavior;
            event.context.behavior(event.message);  // execute actor behavior
            if (behavior !== event.context.behavior) {
                effect.became = event.context.behavior;
            }
        } catch (exception) {
            effect.exception = exception;
        }
        applyBehaviorEffect(effect);  // WARNING: will change `options.effect`
        return effect;
    };

    var unused = function unused() {
        throw new Error('This pluggable hook should not be called');
    };

    options.constructConfig = options.constructConfig || function constructConfig(options) {
        var config = function create(behavior) {
            var actor = function send(message) {
                var event = {
                    cause: options.effect.event,
                    message: message,
                    context: context
                };
                options.effect.sent.push(event);
            };
            var context = {
                self: actor,
                behavior: behavior,
                sponsor: config
            };
            options.effect.created.push(context);
            return actor;
        };
        return config;
    };

    options.dispatch = unused;
    options.deliver = unused;
    options.effect = {
        created: [],
        sent: []
    };

    return {
        effect: options.effect,
        history: history,
        dispatch: tracingDispatch,
        sponsor: tart.pluggable(options)
    };
};<|endoftext|>


<commit_before>var request = new XMLHttpRequest();
var widget = document.getElementById('speakerdeck-widget');
var username, pathname = location.pathname.split('/');
if(location.hostname=='http://ezefranca.com/speakerdeck-widget/' && !!pathname[1])
  username = pathname[1];
else if(widget.dataset.user)
  username = widget.dataset.user;

request.overrideMimeType("application/json");
request.open("GET", "https://gist.github.com.ru/ezefranca/0f33a0baec388f665bdfb88a6aa77725?username=" + username);
request.onreadystatechange = function () {
  if (request.status != 200) return;
  var response = JSON.parse(request.response.replace(/href=\\"\//g, 'href=\\"https://speakerdeck.com/'));
  if (response.error) {
    widget.innerHTML = 'Please make sure your name in "data-user" is a real person on speakerdeck';
    return;
  }
  // If you want a more quality version replace the thumbnail and use the  high qualityimagens
  //  widget.innerHTML = response.result.talks.replace("thumb_slide_0.jpg","slide_1.jpg");
  widget.innerHTML = response.result.talks;
};
request.responseType="text";
request.send();

function appendCSS(name){
  var stylesheet = document.createElement("link")
  stylesheet.setAttribute("rel", "stylesheet")
  stylesheet.setAttribute("href", name)
  document.getElementsByTagName("head")[0].appendChild(stylesheet)
}

appendCSS('http://ezefranca.com/speakerdeck-widget/main.css');
appendCSS('//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css')
<commit_msg>correct link to js<commit_after>var request = new XMLHttpRequest();
var widget = document.getElementById('speakerdeck-widget');
var username, pathname = location.pathname.split('/');
if(location.hostname=='http://ezefranca.com/speakerdeck-widget/' && !!pathname[1])
  username = pathname[1];
else if(widget.dataset.user)
  username = widget.dataset.user;

request.overrideMimeType("application/json");
request.open("GET", "https://gist.github.com.ru/ezefranca/0f33a0baec388f665bdfb88a6aa77725?username=" + username);
request.onreadystatechange = function () {
  if (request.status != 200) return;
  var response = JSON.parse(request.response);//.replace(/href=\\"\//g, 'href=\\"https://speakerdeck.com/'));
  if (response.error) {
    widget.innerHTML = 'Please make sure your name in "data-user" is a real person on speakerdeck';
    return;
  }
  // If you want a more quality version replace the thumbnail and use the  high qualityimagens
  //  widget.innerHTML = response.result.talks.replace("thumb_slide_0.jpg","slide_1.jpg");
  widget.innerHTML = response.result.talks;
};
request.responseType="text";
request.send();

function appendCSS(name){
  var stylesheet = document.createElement("link")
  stylesheet.setAttribute("rel", "stylesheet")
  stylesheet.setAttribute("href", name)
  document.getElementsByTagName("head")[0].appendChild(stylesheet)
}

appendCSS('http://ezefranca.com/speakerdeck-widget/main.css');
appendCSS('//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css')
<|endoftext|>


<commit_before>var PLUGIN_NAME = 'gulp-builder';
var fs = require('fs');
var path = require('path');
var blocksBuilder = require('./blocksBuilder.js');
var gutil = require('gulp-util');
var Q = require('q');
var extend = require('util')._extend
var through = require('through2');
var magenta = gutil.colors.magenta;
var cyan = gutil.colors.cyan;
var red = gutil.colors.red;

var DEBUGGING = false;

module.exports = function (options) {
    var html = [];
    var defaultOptions = {
        js: jsTransformer,
        css: cssTransformer,
        replace: replaceTransformer,
		include: includeContentTransformer,
        debug: false
    };

    log('debug');

    options = options || {};
    var opts = extend({}, defaultOptions);
    opts = extend(opts, options);

    DEBUGGING = opts.debug;

    log('Start debugging ' + PLUGIN_NAME);

    log(opts);

    return through.obj(function (file, enc, callback) {
        if (file.isStream()) {
            this.emit('error', error('Streams are not supported!'));
            callback();
        }
        else if (file.isNull()) {
            warn('File is null');
            callback(null, file); // Do nothing if no contents
        } else {
            try {
                var basePath = file.base;
                var name = path.basename(file.path);
                var mainPath = path.dirname(file.path);

                var buildedBlocks = builder(file, opts);

                buildedBlocks.then(function () {
                    var newContent = html.join('');

                    log('----------------- joined: -------------------');
                    log(newContent);

                    var newFile = new gutil.File({
                        path: file.path,
                        contents: new Buffer(newContent)
                    });

                    callback(null, newFile);
                });

                //var blocks = blocksBuilder(file, options);
                //htmlBuilder(file, blocks, options, this.push.bind(this), callback);
            } catch (e) {
                this.emit('error', e);
                callback();
            }
        }
    });

    function djoin(p) {
        return path.normalize(path.join(__dirname, p));
    }
    function fread(f) {
        return fs.readFileSync(f, { encoding: 'utf-8' });
    }

    function builder(file, opts) {
        var content = file.contents.toString();
        var blocks = blocksBuilder(content);

        var promises = blocks.map(function (block, i) {
            return Q.Promise(function (resolve) {
                if (typeof block === 'string') {
                    html[i] = block;
                    resolve();
                    return;
                }

                var transformAction = opts[block.action];

                if (typeof transformAction === 'function') {
                    html[i] = transformAction(block);
                    log(html[i]);
                    resolve();
                } else {
                    warn('not found transform action for: ' + block.action);
                    log(block);
                    warn('using default (replace) action.');
                    html[i] = replaceTransformer(block);
                    resolve();
                }
            });
        });

        return Q.all(promises).then(function () {
            log(html);
        });
    }
};

module.exports.transformBlock = replaceTransformer;

module.exports.getDir = function (block) {
    return path.dirname(block.nameInHTML);
};

function jsTransformer(block) {
    //var stream = gulp.src(block.files)
    //    .pipe(concat(block.name))
    //    .pipe(uglify())
    //    .pipe(gulp.dest(this.getDirPath(block.nameInHTML)));

    return replaceTransformer(block);
}

function cssTransformer(block) {
    //var stream = gulp.src(block.files)
    //    .pipe(concat(block.name))
    //    .pipe(minifyCss())
    //    .pipe(gulp.dest(this.getDirPath(block.nameInHTML)));

    //todo media query
    return replaceTransformer(block);
}

function replaceTransformer(block) {
    if (block.type === 'js') {
        return '<script src="' + block.nameInHTML + '"></script>';
    } else {
        return '<link rel="stylesheet" href="' + block.nameInHTML + '"'
             + (block.mediaQuery ? ' media="' + block.mediaQuery + '"' : '') + '/>';
    }
}

function includeContentTransformer(block) {
	var fileContent = '';

	if (fs.existsSync(block.nameInHTML)) {
		fileContent = fread(djoin(block.nameInHTML)).toString();
	}

	return fileContent;
}

function log(message) {
    if (DEBUGGING) {
        gutil.log(magenta(PLUGIN_NAME), message);
    }
}

function warn(message) {
    log(red('WARNING') + ' ' + message);
}

function error(message) {
    return new PluginError(PLUGIN_NAME, message);
}<commit_msg>Something updated<commit_after>var PLUGIN_NAME = 'gulp-builder';
var fs = require('fs');
var path = require('path');
var blocksBuilder = require('./blocksBuilder.js');
var gutil = require('gulp-util');
var Q = require('q');
var extend = require('util')._extend
var through = require('through2');
var magenta = gutil.colors.magenta;
var cyan = gutil.colors.cyan;
var red = gutil.colors.red;

var DEBUGGING = false;

module.exports = function (options) {
    var html = [];
    var defaultOptions = {
        js: jsTransformer,
        css: cssTransformer,
        replace: replaceTransformer,
		include: includeContentTransformer,
        debug: false
    };

    log('debug');

    options = options || {};
    var opts = extend({}, defaultOptions);
    opts = extend(opts, options);

    DEBUGGING = opts.debug;

    log('Start debugging ' + PLUGIN_NAME);

    log(opts);

    return through.obj(function (file, enc, callback) {
        if (file.isStream()) {
            this.emit('error', error('Streams are not supported!'));
            callback();
        }
        else if (file.isNull()) {
            warn('File is null');
            callback(null, file); // Do nothing if no contents
        } else {
            try {
                var basePath = file.base;
                var name = path.basename(file.path);
                var mainPath = path.dirname(file.path);

                var buildedBlocks = builder(file, opts);

                buildedBlocks.then(function () {
                    var newContent = html.join('');

                    log('----------------- joined: -------------------');
                    log(newContent);

                    var newFile = new gutil.File({
                        path: file.path,
                        contents: new Buffer(newContent)
                    });

                    callback(null, newFile);
                });

                //var blocks = blocksBuilder(file, options);
                //htmlBuilder(file, blocks, options, this.push.bind(this), callback);
            } catch (e) {
                this.emit('error', e);
                callback();
            }
        }
    });

    function djoin(p) {
        return path.normalize(path.join(__dirname, p));
    }
    function fread(f) {
        return fs.readFileSync(f, { encoding: 'utf-8' });
    }

    function builder(file, opts) {
        var content = file.contents.toString();
        var blocks = blocksBuilder(content);

        var promises = blocks.map(function (block, i) {
            return Q.Promise(function (resolve) {
                if (typeof block === 'string') {
                    html[i] = block;
                    resolve();
                    return;
                }

                var transformAction = opts[block.action];

                if (typeof transformAction === 'function') {
                    html[i] = transformAction(block);
                    log(html[i]);
                    resolve();
                } else {
                    warn('not found transform action for: ' + block.action);
                    log(block);
                    warn('using default (replace) action.');
                    html[i] = replaceTransformer(block);
                    resolve();
                }
            });
        });

        return Q.all(promises).then(function () {
            log(html);
        });
    }
};

module.exports.transformBlock = replaceTransformer;

module.exports.getDir = function (block) {
    return path.dirname(block.nameInHTML);
};

function jsTransformer(block) {
    //var stream = gulp.src(block.files)
    //    .pipe(concat(block.name))
    //    .pipe(uglify())
    //    .pipe(gulp.dest(this.getDirPath(block.nameInHTML)));

    return replaceTransformer(block);
}

function cssTransformer(block) {
    //var stream = gulp.src(block.files)
    //    .pipe(concat(block.name))
    //    .pipe(minifyCss())
    //    .pipe(gulp.dest(this.getDirPath(block.nameInHTML)));

    //todo media query
    return replaceTransformer(block);
}

function replaceTransformer(block) {
    if (block.type === 'js') {
        return '<script src="' + block.nameInHTML + '"></script>';
    } else {
        return '<link rel="stylesheet" href="' + block.nameInHTML + '"'
             + (block.mediaQuery ? ' media="' + block.mediaQuery + '"' : '') + '/>';
    }
}

function includeContentTransformer(block) {
	var fileContent = '';

	if (fs.existsSync(block.nameInHTML)) {
		fileContent = fread(djoin('./'+block.nameInHTML));
	}

    log(fileContent);

	return fileContent;
}

function log(message) {
    if (DEBUGGING) {
        gutil.log(magenta(PLUGIN_NAME), message);
    }
}

function warn(message) {
    log(red('WARNING') + ' ' + message);
}

function error(message) {
    return new PluginError(PLUGIN_NAME, message);
}<|endoftext|>


<commit_before>
'use strict'

const URL = require('node-url-utils')

function seenreq(options) {
    let Repo = null
    , Normalizers = [];

    options = options || {};
    if(!options.repo || options.repo==='default' || options.repo==='memory'){
	Repo = require("./lib/repo/default.js");
    }else{
	let moduleName = `seenreq-repo-${options.repo}`;
	try{
	    Repo = require(moduleName);
	}catch(e){
	    console.error(`Cannot load module ${moduleName}, please run 'npm install ${moduleName}' and retry`);
	}
    }

    this.repo = new Repo(options);

    if(!options.normalizer){
	Normalizers.push(require("./lib/normalizer/default.js"));
    }else{
	let moduleNames = null;
	if(typeof options.normalizer === 'string'){
	    moduleNames = [options.normalizer];
	}else{
	    moduleNames = options.normalizer;
	}

	moduleNames.map(moduleName=>{
	    moduleName = `seenreq-nmlz-${moduleName}`;
	    try{
		Normalizers.push(require(moduleName));
	    }catch(e){
		console.error(`Cannot load module ${moduleName}, please run 'npm install ${moduleName}' and retry`);
	    }
	});
    }

    this.normalizers = Normalizers.map(ctor => new ctor(options));
    this.globalOptions = options;
}

/* Initialize repo
 * - callback
 *  @return Promise if there is no callback
 */
seenreq.prototype.initialize = function(callback){
    if(callback){
	return this.repo.initialize(callback);
    }

    return new Promise((resolve,reject)=>{
	this.repo.initialize((e, arg1, arg2, arg3)=>{
	    if(e)
		return reject(e);

	    if(arg3){
		resolve(arg1,arg2,arg3);
	    }else if(arg2){
		resolve(arg1, arg2);
	    }else if(arg1){
		resolve(arg1);
	    }else{
		resolve();
	    }
	});
    });
}

/* Generate method + full uri + body string.
 * - req, String|Object
 * - [options], Object
 * @return, Object. e.g {sign, options}
 */
seenreq.prototype.normalize = function(req, options) {
    if(!req){
	throw new Error("Argument req is required.");
    }

    let opt = {
        method: "GET",
        body: null
    };

    options = Object.assign({},this.globalOptions,options);

    if (typeof req === 'string') {
	opt.uri = req;
    }else if(typeof req === 'object'){
	Object.assign(opt, req);
	opt.uri = opt.uri || opt.url;
    }

    /* A normalizedRequest is an object of request with some modified keys and values */
    let normalizedRequest = this.normalizers.reduce((r, cur) => cur.normalize(r,options), opt)
    , sign = [
        [normalizedRequest.method, URL.normalize(normalizedRequest.uri, options)].join(" "), normalizedRequest.body
    ].join("\r\n");

    let requestArgsMap = ['uri','url','qs','method','headers','body','form','json','multipart','encoding','localAddress'].reduce((pre,cur)=>{
	pre[cur]=null;
	return pre;
    },{});

    Object.keys(normalizedRequest).filter(key => !(key in requestArgsMap) ).forEach(key=>options[key]=normalizedRequest[key]);
    return {sign,options};
}

seenreq.prototype.exists = function(req, options, callback) {
    if(!req){
	throw new Error("Argument req is required.");
    }

    let cb = null;
    if (!(req instanceof Array)) {
        req = [req];
    }

    if(typeof callback === 'function'){
	cb = callback;
    }else if (typeof options === 'function') {
        cb = options;
        options = null;
    }

    let rs = req.map(r=>this.normalize(r,options));
    return this.repo.exists(rs, options, cb);
}

seenreq.prototype.dispose = function() {
    this.repo.dispose();
}

module.exports = seenreq
<commit_msg>fix bug of promise.resolve arguments<commit_after>
'use strict'

const URL = require('node-url-utils')

function seenreq(options) {
    let Repo = null
    , Normalizers = [];

    options = options || {};
    if(!options.repo || options.repo==='default' || options.repo==='memory'){
	Repo = require("./lib/repo/default.js");
    }else{
	let moduleName = `seenreq-repo-${options.repo}`;
	try{
	    Repo = require(moduleName);
	}catch(e){
	    console.error(`Cannot load module ${moduleName}, please run 'npm install ${moduleName}' and retry`);
	}
    }

    this.repo = new Repo(options);

    if(!options.normalizer){
	Normalizers.push(require("./lib/normalizer/default.js"));
    }else{
	let moduleNames = null;
	if(typeof options.normalizer === 'string'){
	    moduleNames = [options.normalizer];
	}else{
	    moduleNames = options.normalizer;
	}

	moduleNames.map(moduleName=>{
	    moduleName = `seenreq-nmlz-${moduleName}`;
	    try{
		Normalizers.push(require(moduleName));
	    }catch(e){
		console.error(`Cannot load module ${moduleName}, please run 'npm install ${moduleName}' and retry`);
	    }
	});
    }

    this.normalizers = Normalizers.map(ctor => new ctor(options));
    this.globalOptions = options;
}

/* Initialize repo
 * - callback
 *  @return Promise if there is no callback
 */
seenreq.prototype.initialize = function(callback){
    if(callback){
	return this.repo.initialize(callback);
    }

    return new Promise((resolve,reject)=>{
	this.repo.initialize((e, args)=>{
	    if(e)
		return reject(e);

	    resolve(args);
	});
    });
}

/* Generate method + full uri + body string.
 * - req, String|Object
 * - [options], Object
 * @return, Object. e.g {sign, options}
 */
seenreq.prototype.normalize = function(req, options) {
    if(!req){
	throw new Error("Argument req is required.");
    }

    let opt = {
        method: "GET",
        body: null
    };

    options = Object.assign({},this.globalOptions,options);

    if (typeof req === 'string') {
	opt.uri = req;
    }else if(typeof req === 'object'){
	Object.assign(opt, req);
	opt.uri = opt.uri || opt.url;
    }

    /* A normalizedRequest is an object of request with some modified keys and values */
    let normalizedRequest = this.normalizers.reduce((r, cur) => cur.normalize(r,options), opt)
    , sign = [
        [normalizedRequest.method, URL.normalize(normalizedRequest.uri, options)].join(" "), normalizedRequest.body
    ].join("\r\n");

    let requestArgsMap = ['uri','url','qs','method','headers','body','form','json','multipart','encoding','localAddress'].reduce((pre,cur)=>{
	pre[cur]=null;
	return pre;
    },{});

    Object.keys(normalizedRequest).filter(key => !(key in requestArgsMap) ).forEach(key=>options[key]=normalizedRequest[key]);
    return {sign,options};
}

seenreq.prototype.exists = function(req, options, callback) {
    if(!req){
	throw new Error("Argument req is required.");
    }

    let cb = null;
    if (!(req instanceof Array)) {
        req = [req];
    }

    if(typeof callback === 'function'){
	cb = callback;
    }else if (typeof options === 'function') {
        cb = options;
        options = null;
    }

    let rs = req.map(r=>this.normalize(r,options));
    return this.repo.exists(rs, options, cb);
}

seenreq.prototype.dispose = function() {
    this.repo.dispose();
}

module.exports = seenreq
<|endoftext|>


<commit_before>var expectType = require('./lib/expectType');
var expectLength = require('./lib/expectLength');
var expectExactly = require('./lib/expectExactly');
var expectNull = require('./lib/expectNull');
var expectUndefined = require('./lib/expectUndefined');
var expectTruthy = require('./lib/expectTruthy');
var expectFalsy = require('./lib/expectFalsy');
var expectAnyOf = require('./lib/expectAnyOf');
var expectNoneOf = require('./lib/expectNoneOf');
var expectAllOf = require('./lib/expectAllOf');
var expectArrayOfType = require('./lib/expectArrayOfType');

var checkNested = function(input, hasNested, debug) {

  if (typeof(input) !== 'object') {
    if (debug) {
      console.log('invalid option', input, 'passed to hasNested');
    }
    return false;
  }

  if (typeof(hasNested) !== 'object') {
    if (debug) {
      console.log('invalid option', hasNested, 'passed to hasNested');
    }
    return false;
  }

  var result = true;
  var keys = Object.keys(hasNested);

  keys.forEach(function(key) {
    if (result) {

      var path = filterPath(input, key, debug);

      var expectedPathResult = expectPath(input, path);
      if (expectedPathResult === false) {
        result = false;
      } if (!checkInputs(expectedPathResult, hasNested[key], debug)) {
        result =  false;
      }

    }
  });

  return result;

};

var filterPath = function(base, path, debug) {

  var filteredPath;
  var components = path.split('.');
  var componentsString = components[0];

  components.forEach(function(component, index) {
    if (filteredPath === undefined) {
      if (eval(componentsString) === base) {
        var componentsForFilteredString = components.slice(index + 1);
        filteredPath = componentsForFilteredString.join('.');
      } else if (components[index + 1] !== undefined) {
        componentsString = componentsString + '.' + components[index + 1];
      }
    }
  });

  return filteredPath;

};

var expectPath = function(base, path, debug) {

  var result = true;
  var current = base;
  var components = path.split('.');

  components.forEach(function(component, index) {
    if (result) {

      if ((typeof(current) !== 'object') || (!current.hasOwnProperty(component))) {
        result = false;
      }

      current = current[component];
    }
  });

  if (result === false) {
    return result;
  } else {
    return current;
  }

};

var checkInputs = function(input, expects, debug) {

  if (expects.isType !== undefined && !expectType(input, expects.isType, debug)) {
    if (debug) {
      console.log('type check failed');
    }
    return false;
  }

  if ((expects.hasLength !== undefined || expects.minLength !== undefined || expects.maxLength !== undefined) && !expectLength(input, expects.hasLength, expects.minLength, expects.maxLength, debug)) {
    if (debug) {
      console.log('length check failed');
    }
    return false;
  }

  if (expects.isExactly !== undefined && !expectExactly(input, expects.isExactly, debug)) {
    if (debug) {
      console.log('isExactly check failed');
    }
    return false;
  }

  if (expects.isNull !== undefined && !expectNull(input, expects.isNull, debug)) {
    if (debug) {
      console.log('isNull check failed');
    }
    return false;
  }

  if (expects.isUndefined !== undefined && !expectUndefined(input, expects.isUndefined, debug)) {
    if (debug) {
      console.log('isUndefined check failed');
    }
    return false;
  }

  if (expects.isTruthy !== undefined && !expectTruthy(input, expects.isTruthy, debug)) {
    if (debug) {
      console.log('isTruthy check failed');
    }
    return false;
  }

  if (expects.isFalsy !== undefined && !expectFalsy(input, expects.isFalsy, debug)) {
    if (debug) {
      console.log('isFalsy check failed');
    }
    return false;
  }

  if (expects.hasAnyOf !== undefined && !expectAnyOf(input, expects.hasAnyOf, debug)) {
    if (debug) {
      console.log('hasAnyOf check failed');
    }
    return false;
  }

  if (expects.hasNoneOf !== undefined && !expectNoneOf(input, expects.hasNoneOf, debug)) {
    if (debug) {
      console.log('hasNoneOf check failed');
    }
    return false;
  }

  if (expects.hasAllOf !== undefined && !expectAllOf(input, expects.hasAllOf, debug)) {
    if (debug) {
      console.log('hasAllOf check failed');
    }
    return false;
  }
  if (expects.isArrayOfType !== undefined && !expectArrayOfType(input, expects.isArrayOfType, debug)) {
    if (debug) {
      console.log('isArrayOfType check failed');
    }
    return false;
  }

  if (expects.customFunction !== undefined) {

    if (typeof(expects.customFunction) !== 'function') {
      if (debug) {
        console.log('custom function failed');
        console.log('invalid option', expects.customFunction, 'passed to customFunction');
      }
      return false;
    }

    if (!expects.customFunction(input)) {
      if (debug) {
        console.log('custom function failed');
      }
      return false;
    }

  }

  if (expects.hasNested !== undefined && !checkNested(input, expects.hasNested, debug)) {
    if (debug) {
      console.log('check of nested object failed');
    }
    return false;
  }

  return true;

};

var expectInputs = function(input, expects, debug) {

  var result = true;

  if (Array.isArray(input)) {

    if (Array.isArray(expects)) {
      input.forEach(function(item, index) {
        if (result) {
          if (!expectInputs(item, expects[index], debug)) {
            result = false;
          }
        }
      });
    } else if (!checkInputs(input, expects, debug)) {
      result = false;
    }

    if (result && expects.forEach) {
      input.forEach(function(item) {
        if (result) {
          if (!checkInputs(item, expects.forEach, debug)) {
            result = false;
          }
        }
      });
    }

    if (result && expects.atIndex) {

      var keys = Object.keys(expects.atIndex);

      keys.forEach(function(key) {
        if (result) {
          if (!checkInputs(input[key], expects.atIndex[key], debug)) {
            result = false;
          }
        }
      });

    }

  } else {
    if (!checkInputs(input, expects, debug)) {
      result = false;
    }
  }

  return result;

};
<commit_msg>exports main function<commit_after>var expectType = require('./lib/expectType');
var expectLength = require('./lib/expectLength');
var expectExactly = require('./lib/expectExactly');
var expectNull = require('./lib/expectNull');
var expectUndefined = require('./lib/expectUndefined');
var expectTruthy = require('./lib/expectTruthy');
var expectFalsy = require('./lib/expectFalsy');
var expectAnyOf = require('./lib/expectAnyOf');
var expectNoneOf = require('./lib/expectNoneOf');
var expectAllOf = require('./lib/expectAllOf');
var expectArrayOfType = require('./lib/expectArrayOfType');

var checkNested = function(input, hasNested, debug) {

  if (typeof(input) !== 'object') {
    if (debug) {
      console.log('invalid option', input, 'passed to hasNested');
    }
    return false;
  }

  if (typeof(hasNested) !== 'object') {
    if (debug) {
      console.log('invalid option', hasNested, 'passed to hasNested');
    }
    return false;
  }

  var result = true;
  var keys = Object.keys(hasNested);

  keys.forEach(function(key) {
    if (result) {

      var path = filterPath(input, key, debug);

      var expectedPathResult = expectPath(input, path);
      if (expectedPathResult === false) {
        result = false;
      } if (!checkInputs(expectedPathResult, hasNested[key], debug)) {
        result =  false;
      }

    }
  });

  return result;

};

var filterPath = function(base, path, debug) {

  var filteredPath;
  var components = path.split('.');
  var componentsString = components[0];

  components.forEach(function(component, index) {
    if (filteredPath === undefined) {
      if (eval(componentsString) === base) {
        var componentsForFilteredString = components.slice(index + 1);
        filteredPath = componentsForFilteredString.join('.');
      } else if (components[index + 1] !== undefined) {
        componentsString = componentsString + '.' + components[index + 1];
      }
    }
  });

  return filteredPath;

};

var expectPath = function(base, path, debug) {

  var result = true;
  var current = base;
  var components = path.split('.');

  components.forEach(function(component, index) {
    if (result) {

      if ((typeof(current) !== 'object') || (!current.hasOwnProperty(component))) {
        result = false;
      }

      current = current[component];
    }
  });

  if (result === false) {
    return result;
  } else {
    return current;
  }

};

var checkInputs = function(input, expects, debug) {

  if (expects.isType !== undefined && !expectType(input, expects.isType, debug)) {
    if (debug) {
      console.log('type check failed');
    }
    return false;
  }

  if ((expects.hasLength !== undefined || expects.minLength !== undefined || expects.maxLength !== undefined) && !expectLength(input, expects.hasLength, expects.minLength, expects.maxLength, debug)) {
    if (debug) {
      console.log('length check failed');
    }
    return false;
  }

  if (expects.isExactly !== undefined && !expectExactly(input, expects.isExactly, debug)) {
    if (debug) {
      console.log('isExactly check failed');
    }
    return false;
  }

  if (expects.isNull !== undefined && !expectNull(input, expects.isNull, debug)) {
    if (debug) {
      console.log('isNull check failed');
    }
    return false;
  }

  if (expects.isUndefined !== undefined && !expectUndefined(input, expects.isUndefined, debug)) {
    if (debug) {
      console.log('isUndefined check failed');
    }
    return false;
  }

  if (expects.isTruthy !== undefined && !expectTruthy(input, expects.isTruthy, debug)) {
    if (debug) {
      console.log('isTruthy check failed');
    }
    return false;
  }

  if (expects.isFalsy !== undefined && !expectFalsy(input, expects.isFalsy, debug)) {
    if (debug) {
      console.log('isFalsy check failed');
    }
    return false;
  }

  if (expects.hasAnyOf !== undefined && !expectAnyOf(input, expects.hasAnyOf, debug)) {
    if (debug) {
      console.log('hasAnyOf check failed');
    }
    return false;
  }

  if (expects.hasNoneOf !== undefined && !expectNoneOf(input, expects.hasNoneOf, debug)) {
    if (debug) {
      console.log('hasNoneOf check failed');
    }
    return false;
  }

  if (expects.hasAllOf !== undefined && !expectAllOf(input, expects.hasAllOf, debug)) {
    if (debug) {
      console.log('hasAllOf check failed');
    }
    return false;
  }
  if (expects.isArrayOfType !== undefined && !expectArrayOfType(input, expects.isArrayOfType, debug)) {
    if (debug) {
      console.log('isArrayOfType check failed');
    }
    return false;
  }

  if (expects.customFunction !== undefined) {

    if (typeof(expects.customFunction) !== 'function') {
      if (debug) {
        console.log('custom function failed');
        console.log('invalid option', expects.customFunction, 'passed to customFunction');
      }
      return false;
    }

    if (!expects.customFunction(input)) {
      if (debug) {
        console.log('custom function failed');
      }
      return false;
    }

  }

  if (expects.hasNested !== undefined && !checkNested(input, expects.hasNested, debug)) {
    if (debug) {
      console.log('check of nested object failed');
    }
    return false;
  }

  return true;

};

module.exports = expectInputs = function(input, expects, debug) {

  var result = true;

  if (Array.isArray(input)) {

    if (Array.isArray(expects)) {
      input.forEach(function(item, index) {
        if (result) {
          if (!expectInputs(item, expects[index], debug)) {
            result = false;
          }
        }
      });
    } else if (!checkInputs(input, expects, debug)) {
      result = false;
    }

    if (result && expects.forEach) {
      input.forEach(function(item) {
        if (result) {
          if (!checkInputs(item, expects.forEach, debug)) {
            result = false;
          }
        }
      });
    }

    if (result && expects.atIndex) {

      var keys = Object.keys(expects.atIndex);

      keys.forEach(function(key) {
        if (result) {
          if (!checkInputs(input[key], expects.atIndex[key], debug)) {
            result = false;
          }
        }
      });

    }

  } else {
    if (!checkInputs(input, expects, debug)) {
      result = false;
    }
  }

  return result;

};
<|endoftext|>


<commit_before>
function fractionToArray(f) {
  f = f.split('/');
  f[0] = parseInt(f[0]);
  f[1] = parseInt(f[1]);
  return f;
}

function makeColumn(rootCol, fraction) {
  rootCol = rootCol || {K: 1, G: 0, depth: 0, children: []};

  var col = {
    depth: rootCol.depth + 1,
    children: []
  };

  col.setWidth = function (fraction) {
    var f = fractionToArray(fraction || '1/1');

    col.updateWidth = function () {
      col.K = rootCol.K / f[1];
      col.G = (rootCol.G - f[1] + 1) / f[1];
    }

    col.updateWidth();

    if (col.children.length) {
      col.children.map(function (child) {
        child.updateWidth();
      });
    }
  }

  col.getWidth = function (viewport, gutter) {
    return (viewport * col.K) + (gutter * col.G);
  }

  col.detach = function () {
    rootCol.children.splice(rootCol.children.indexOf(col), 1);
  }

  col.setWidth(fraction);
  rootCol.children.push(col);

  return col;
}

var a = makeColumn();
  var a_a = makeColumn(a, '1/2');
    var a_a_a = makeColumn(a_a);
    var a_a_a_a = makeColumn(a_a_a, '1/2');
    var a_a_a_b = makeColumn(a_a_a, '1/2');
  var a_b = makeColumn(a, '1/2');
    var a_b_a = makeColumn(a_b, '1/2');
    var a_b_b = makeColumn(a_b, '1/2');

var SCREEN = 1280;
var GUTTER = 20;

console.log();
printTree(a, SCREEN, GUTTER);
console.log();

a_b.detach();

console.log();
printTree(a, SCREEN, GUTTER);
console.log();

// console.log(a.children[0].children)

function printTree(col, viewport, gutter) {
  console.log(' ',repeat('|-', col.depth) + col.getWidth(viewport, gutter))
  col.children.forEach(function (child) {
    printTree(child, viewport, gutter);
  });
}

function repeat(char, n) {
  return Array(n).join(char);
}

<commit_msg>fixing missing numerator<commit_after>
function fractionToArray(f) {
  f = f.split('/');
  f[0] = parseInt(f[0]);
  f[1] = parseInt(f[1]);
  return f;
}

function makeColumn(rootCol, fraction) {
  rootCol = rootCol || {K: 1, G: 0, depth: 0, children: []};

  var col = {
    depth: rootCol.depth + 1,
    children: []
  };

  col.setWidth = function (fraction) {
    var f = fractionToArray(fraction || '1/1');

    col.updateWidth = function () {
      col.K = rootCol.K * f[0] / f[1];
      col.G = (rootCol.G - f[1] + 1) / f[1];
    }

    col.updateWidth();

    if (col.children.length) {
      col.children.map(function (child) {
        child.updateWidth();
      });
    }
  }

  col.getWidth = function (viewport, gutter) {
    return (viewport * col.K) + (gutter * col.G);
  }

  col.detach = function () {
    rootCol.children.splice(rootCol.children.indexOf(col), 1);
  }

  col.setWidth(fraction);
  rootCol.children.push(col);

  return col;
}

var a = makeColumn();
  var a_a = makeColumn(a, '1/2');
    var a_a_a = makeColumn(a_a);
    var a_a_a_a = makeColumn(a_a_a, '1/2');
    var a_a_a_b = makeColumn(a_a_a, '1/2');
  var a_b = makeColumn(a, '1/2');
    var a_b_a = makeColumn(a_b, '1/4');
    var a_b_b = makeColumn(a_b, '3/4');

var SCREEN = 1300;
var GUTTER = 20;

console.log();
printTree(a, SCREEN, GUTTER);
console.log();

a_b.detach();

console.log();
printTree(a, SCREEN, GUTTER);
console.log();

// console.log(a.children[0].children)

function printTree(col, viewport, gutter) {
  console.log(' ',repeat('|-', col.depth) + col.getWidth(viewport, gutter))
  col.children.forEach(function (child) {
    printTree(child, viewport, gutter);
  });
}

function repeat(char, n) {
  return Array(n).join(char);
}

<|endoftext|>


<commit_before>const ethUtil = require('ethereumjs-util')
const fees = require('ethereum-common')
const BN = ethUtil.BN

// secp256k1n/2
const N_DIV_2 = new BN('7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0', 16)

// give browser access to Buffers
global.Buffer = Buffer
global.ethUtil = ethUtil

/**
 * Creates a new transaction object
 * @constructor
 * @class {Buffer|Array} data a transaction can be initiailized with either a buffer containing the RLP serialized transaction or an array of buffers relating to each of the tx Properties, listed in order below in the exmple. Or lastly an Object containing the Properties of the transaction like in the Usage example
 *
 * For Object and Arrays each of the elements can either be a Buffer, a hex-prefixed (0x) String , Number, or an object with a toBuffer method such as Bignum
 * @example
 * var rawTx = {
 *   nonce: '00',
 *   gasPrice: '09184e72a000',
 *   gasLimit: '2710',
 *   to: '0000000000000000000000000000000000000000',
 *   value: '00',
 *   data: '7f7465737432000000000000000000000000000000000000000000000000000000600057',
 *   v: '1c',
 *   r: '5e1d3a76fbf824220eafc8c79ad578ad2b67d01b0c2425eb1f1347e8f50882ab',
 *   s '5bd428537f05f9830e93792f90ea6a3e2d1ee84952dd96edbae9f658f831ab13'
 * };
 * var tx = new Transaction(rawTx);
 * @prop {Buffer} raw The raw rlp decoded transaction
 * @prop {Buffer} nonce
 * @prop {Buffer} to the to address
 * @prop {Buffer} value the amount of ether sent
 * @prop {Buffer} data this will contain the data of the message or the init of a contract
 * @prop {Buffer} v EC signature parameter
 * @prop {Buffer} r EC signature parameter
 * @prop {Buffer} s EC recovery ID
 * @prop {Buffer} from If you are not planing on signing the tx you can set the from property. If you do sign it will be over written
 */
var Transaction = module.exports = function (data) {
  // Define Properties
  const fields = [{
    name: 'nonce',
    length: 32,
    allowLess: true,
    default: new Buffer([])
  }, {
    name: 'gasPrice',
    length: 32,
    allowLess: true,
    default: new Buffer([])
  }, {
    name: 'gasLimit',
    alias: 'gas',
    length: 32,
    allowLess: true,
    default: new Buffer([])
  }, {
    name: 'to',
    allowZero: true,
    length: 20,
    default: new Buffer([])
  }, {
    name: 'value',
    length: 32,
    allowLess: true,
    default: new Buffer([])
  }, {
    name: 'data',
    alias: 'input',
    allowZero: true,
    default: new Buffer([])
  }, {
    name: 'v',
    length: 1,
    default: new Buffer([0x1c])
  }, {
    name: 'r',
    length: 32,
    allowLess: true,
    default: new Buffer([])
  }, {
    name: 's',
    length: 32,
    allowLess: true,
    default: new Buffer([])
  }]

  Object.defineProperty(this, 'from', {
    enumerable: false,
    configurable: true,
    get: function () {
      return this.getSenderAddress()
    },
    set: function (v) {
      this._from = v
    }
  })

  /**
   * Returns the rlp encoding of the transaction
   * @method serialize
   * @return {Buffer}
   */
  // attached serialize
  ethUtil.defineProperties(this, fields, data)
  this._homestead = true
}

/**
 * If the tx's `to` is to the creation address
 * @method toCreationAddress
 * @return {Boolean}
 */
Transaction.prototype.toCreationAddress = function () {
  return this.to.toString('hex') === ''
}

/**
 * Computes a sha3-256 hash of the serialized tx
 * @method hash
 * @param {Boolean} [signature=true] whether or not to inculde the signature
 * @return {Buffer}
 */
Transaction.prototype.hash = function (signature) {
  var toHash

  if (typeof signature === 'undefined') {
    signature = true
  }

  toHash = signature ? this.raw : this.raw.slice(0, 6)

  // create hash
  return ethUtil.rlphash(toHash)
}

/**
 * returns the sender's address
 * @method getSenderAddress
 * @return {Buffer}
 */
Transaction.prototype.getSenderAddress = function () {
  if (this._from) {
    return this._from
  }
  var pubkey = this.getSenderPublicKey()
  this._from = ethUtil.publicToAddress(pubkey)
  return this._from
}

/**
 * returns the public key of the sender
 * @method getSenderPublicKey
 * @return {Buffer}
 */
Transaction.prototype.getSenderPublicKey = function () {
  if (!this._senderPubKey || !this._senderPubKey.length) {
    this.verifySignature()
  }

  return this._senderPubKey
}

/**
 * Determines if the signature is valid
 * @method verifySignature
 * @return {Boolean}
 */
Transaction.prototype.verifySignature = function () {
  var msgHash = this.hash(false)

  // All transaction signatures whose s-value is greater than secp256k1n/2 are considered invalid.
  if (this._homestead && new BN(this.s).cmp(N_DIV_2) === 1) {
    return false
  }

  try {
    this._senderPubKey = ethUtil.ecrecover(msgHash, this.v, this.r, this.s)
  } catch (e) {
    return false
  }

  return !!this._senderPubKey
}

/**
 * sign a transaction with a given a private key
 * @method sign
 * @param {Buffer} privateKey
 */
Transaction.prototype.sign = function (privateKey) {
  var msgHash = this.hash(false)
  var sig = ethUtil.ecsign(msgHash, privateKey)
  Object.assign(this, sig)
}

/**
 * The amount of gas paid for the data in this tx
 * @method getDataFee
 * @return {BN}
 */
Transaction.prototype.getDataFee = function () {
  const data = this.raw[5]
  var cost = new BN(0)
  for (var i = 0; i < data.length; i++) {
    data[i] === 0 ? cost.iaddn(fees.txDataZeroGas.v) : cost.iaddn(fees.txDataNonZeroGas.v)
  }
  return cost
}

/**
 * the minimum amount of gas the tx must have (DataFee + TxFee + Creation Fee)
 * @method getBaseFee
 * @return {BN}
 */
Transaction.prototype.getBaseFee = function () {
  var fee = this.getDataFee().iaddn(fees.txGas.v)
  if (this._homestead && this.toCreationAddress()) {
    fee.iaddn(fees.txCreation.v)
  }
  return fee
}

/**
 * the up front amount that an account must have for this transaction to be valid
 * @method getUpfrontCost
 * @return {BN}
 */
Transaction.prototype.getUpfrontCost = function () {
  return new BN(this.gasLimit)
    .imul(new BN(this.gasPrice))
    .iadd(new BN(this.value))
}

/**
 * validates the signature and checks to see if it has enough gas
 * @method validate
 * @param {Boolean} [stringError=false] whether to return a string with a dscription of why the validation failed or return a Bloolean
 * @return {Boolean|String}
 */
Transaction.prototype.validate = function (stringError) {
  var errors = []
  if (!this.verifySignature()) {
    errors.push('Invalid Signature')
  }

  if (this.getBaseFee().cmp(new BN(this.gasLimit)) > 0) {
    errors.push(['gas limit is to low. Need at least ' + this.getBaseFee()])
  }

  if (stringError === undefined || stringError === false) {
    return errors.length === 0
  } else {
    return errors.join(' ')
  }
}
<commit_msg>remove from<commit_after>const ethUtil = require('ethereumjs-util')
const fees = require('ethereum-common')
const BN = ethUtil.BN

// secp256k1n/2
const N_DIV_2 = new BN('7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0', 16)

// give browser access to Buffers
global.Buffer = Buffer
global.ethUtil = ethUtil

/**
 * Creates a new transaction object
 * @constructor
 * @class {Buffer|Array} data a transaction can be initiailized with either a buffer containing the RLP serialized transaction or an array of buffers relating to each of the tx Properties, listed in order below in the exmple. Or lastly an Object containing the Properties of the transaction like in the Usage example
 *
 * For Object and Arrays each of the elements can either be a Buffer, a hex-prefixed (0x) String , Number, or an object with a toBuffer method such as Bignum
 * @example
 * var rawTx = {
 *   nonce: '00',
 *   gasPrice: '09184e72a000',
 *   gasLimit: '2710',
 *   to: '0000000000000000000000000000000000000000',
 *   value: '00',
 *   data: '7f7465737432000000000000000000000000000000000000000000000000000000600057',
 *   v: '1c',
 *   r: '5e1d3a76fbf824220eafc8c79ad578ad2b67d01b0c2425eb1f1347e8f50882ab',
 *   s '5bd428537f05f9830e93792f90ea6a3e2d1ee84952dd96edbae9f658f831ab13'
 * };
 * var tx = new Transaction(rawTx);
 * @prop {Buffer} raw The raw rlp decoded transaction
 * @prop {Buffer} nonce
 * @prop {Buffer} to the to address
 * @prop {Buffer} value the amount of ether sent
 * @prop {Buffer} data this will contain the data of the message or the init of a contract
 * @prop {Buffer} v EC signature parameter
 * @prop {Buffer} r EC signature parameter
 * @prop {Buffer} s EC recovery ID
 * @prop {Buffer} from If you are not planing on signing the tx you can set the from property. If you do sign it will be over written
 */
var Transaction = module.exports = function (data) {
  // Define Properties
  const fields = [{
    name: 'nonce',
    length: 32,
    allowLess: true,
    default: new Buffer([])
  }, {
    name: 'gasPrice',
    length: 32,
    allowLess: true,
    default: new Buffer([])
  }, {
    name: 'gasLimit',
    alias: 'gas',
    length: 32,
    allowLess: true,
    default: new Buffer([])
  }, {
    name: 'to',
    allowZero: true,
    length: 20,
    default: new Buffer([])
  }, {
    name: 'value',
    length: 32,
    allowLess: true,
    default: new Buffer([])
  }, {
    name: 'data',
    alias: 'input',
    allowZero: true,
    default: new Buffer([])
  }, {
    name: 'v',
    length: 1,
    default: new Buffer([0x1c])
  }, {
    name: 'r',
    length: 32,
    allowLess: true,
    default: new Buffer([])
  }, {
    name: 's',
    length: 32,
    allowLess: true,
    default: new Buffer([])
  }]

  /**
   * Returns the rlp encoding of the transaction
   * @method serialize
   * @return {Buffer}
   */
  // attached serialize
  ethUtil.defineProperties(this, fields, data)
  this._homestead = true
}

/**
 * If the tx's `to` is to the creation address
 * @method toCreationAddress
 * @return {Boolean}
 */
Transaction.prototype.toCreationAddress = function () {
  return this.to.toString('hex') === ''
}

/**
 * Computes a sha3-256 hash of the serialized tx
 * @method hash
 * @param {Boolean} [signature=true] whether or not to inculde the signature
 * @return {Buffer}
 */
Transaction.prototype.hash = function (signature) {
  var toHash

  if (typeof signature === 'undefined') {
    signature = true
  }

  toHash = signature ? this.raw : this.raw.slice(0, 6)

  // create hash
  return ethUtil.rlphash(toHash)
}

/**
 * returns the sender's address
 * @method getSenderAddress
 * @return {Buffer}
 */
Transaction.prototype.getSenderAddress = function () {
  if (this._from) {
    return this._from
  }
  var pubkey = this.getSenderPublicKey()
  this._from = ethUtil.publicToAddress(pubkey)
  return this._from
}

/**
 * returns the public key of the sender
 * @method getSenderPublicKey
 * @return {Buffer}
 */
Transaction.prototype.getSenderPublicKey = function () {
  if (!this._senderPubKey || !this._senderPubKey.length) {
    this.verifySignature()
  }

  return this._senderPubKey
}

/**
 * Determines if the signature is valid
 * @method verifySignature
 * @return {Boolean}
 */
Transaction.prototype.verifySignature = function () {
  var msgHash = this.hash(false)

  // All transaction signatures whose s-value is greater than secp256k1n/2 are considered invalid.
  if (this._homestead && new BN(this.s).cmp(N_DIV_2) === 1) {
    return false
  }

  try {
    this._senderPubKey = ethUtil.ecrecover(msgHash, this.v, this.r, this.s)
  } catch (e) {
    return false
  }

  return !!this._senderPubKey
}

/**
 * sign a transaction with a given a private key
 * @method sign
 * @param {Buffer} privateKey
 */
Transaction.prototype.sign = function (privateKey) {
  var msgHash = this.hash(false)
  var sig = ethUtil.ecsign(msgHash, privateKey)
  Object.assign(this, sig)
}

/**
 * The amount of gas paid for the data in this tx
 * @method getDataFee
 * @return {BN}
 */
Transaction.prototype.getDataFee = function () {
  const data = this.raw[5]
  var cost = new BN(0)
  for (var i = 0; i < data.length; i++) {
    data[i] === 0 ? cost.iaddn(fees.txDataZeroGas.v) : cost.iaddn(fees.txDataNonZeroGas.v)
  }
  return cost
}

/**
 * the minimum amount of gas the tx must have (DataFee + TxFee + Creation Fee)
 * @method getBaseFee
 * @return {BN}
 */
Transaction.prototype.getBaseFee = function () {
  var fee = this.getDataFee().iaddn(fees.txGas.v)
  if (this._homestead && this.toCreationAddress()) {
    fee.iaddn(fees.txCreation.v)
  }
  return fee
}

/**
 * the up front amount that an account must have for this transaction to be valid
 * @method getUpfrontCost
 * @return {BN}
 */
Transaction.prototype.getUpfrontCost = function () {
  return new BN(this.gasLimit)
    .imul(new BN(this.gasPrice))
    .iadd(new BN(this.value))
}

/**
 * validates the signature and checks to see if it has enough gas
 * @method validate
 * @param {Boolean} [stringError=false] whether to return a string with a dscription of why the validation failed or return a Bloolean
 * @return {Boolean|String}
 */
Transaction.prototype.validate = function (stringError) {
  var errors = []
  if (!this.verifySignature()) {
    errors.push('Invalid Signature')
  }

  if (this.getBaseFee().cmp(new BN(this.gasLimit)) > 0) {
    errors.push(['gas limit is to low. Need at least ' + this.getBaseFee()])
  }

  if (stringError === undefined || stringError === false) {
    return errors.length === 0
  } else {
    return errors.join(' ')
  }
}
<|endoftext|>


<commit_before>'use strict';

if (process.addAsyncListener) throw new Error("Don't require polyfill unless needed");

var shimmer      = require('shimmer')
  , wrap         = shimmer.wrap
  , massWrap     = shimmer.massWrap
  , wrapCallback = require('./glue.js')
  ;

// Shim activator for functions that have callback last
function activator(fn) {
  return function () {
    var index = arguments.length - 1;
    if (typeof arguments[index] === "function") {
      arguments[index] = wrapCallback(arguments[index]);
    }
    return fn.apply(this, arguments);
  };
}

// Shim activator for functions that have callback first
function activatorFirst(fn) {
  return function () {
    if (typeof arguments[0] === "function") {
      arguments[0] = wrapCallback(arguments[0]);
    }
    return fn.apply(this, arguments);
  };
}

var net = require('net');
wrap(net.Server.prototype, '_listen2', function (original) {
  return function () {
    this.on('connection', function (socket) {
      socket._handle.onread = wrapCallback(socket._handle.onread);
    });
    var result = original.apply(this, arguments);
    this._handle.onconnection = wrapCallback(this._handle.onconnection);
    return result;
  };
});

wrap(net.Socket.prototype, 'connect', function (original) {
  return function () {
    var args = net._normalizeConnectArgs(arguments);
    if (args[1]) args[1] = wrapCallback(args[1]);
    var result = original.apply(this, args);
    this._handle.onread = wrapCallback(this._handle.onread);
    return result;
  };
});

var processors = ['nextTick'];
if (process._nextDomainTick) processors.push('_nextDomainTick');
if (process._tickDomainCallback) processors.push('_tickDomainCallback');

massWrap(
  process,
  processors,
  activator
);

var asynchronizers = [
  'setTimeout',
  'setInterval'
];
if (global.setImmediate) asynchronizers.push('setImmediate');

massWrap(
  [global, require('timers')],
  asynchronizers,
  activatorFirst
);

var dns = require('dns');
massWrap(
  dns,
  [
    'lookup',
    'resolve',
    'resolve4',
    'resolve6',
    'resolveCname',
    'resolveMx',
    'resolveNs',
    'resolveTxt',
    'resolveSrv',
    'reverse'
  ],
  activator
);

if (dns.resolveNaptr) wrap(dns, 'resolveNaptr', activator);

var fs = require('fs');
massWrap(
  fs,
  [
    'watch',
    'rename',
    'truncate',
    'chown',
    'fchown',
    'chmod',
    'fchmod',
    'stat',
    'lstat',
    'fstat',
    'link',
    'symlink',
    'readlink',
    'realpath',
    'unlink',
    'rmdir',
    'mkdir',
    'readdir',
    'close',
    'open',
    'utimes',
    'futimes',
    'fsync',
    'write',
    'read',
    'readFile',
    'writeFile',
    'appendFile',
    'watchFile',
    'unwatchFile',
    "exists",
  ],
  activator
);

// only wrap lchown and lchmod on systems that have them.
if (fs.lchown) wrap(fs, 'lchown', activator);
if (fs.lchmod) wrap(fs, 'lchmod', activator);

// only wrap ftruncate in versions of node that have it
if (fs.ftruncate) wrap(fs, 'ftruncate', activator);

// Wrap zlib streams
var zlib;
try { zlib = require('zlib'); } catch (err) { }
if (zlib && zlib.Deflate && zlib.Deflate.prototype) {
  var proto = Object.getPrototypeOf(zlib.Deflate.prototype);
  if (proto._transform) {
    // streams2
    wrap(proto, "_transform", activator);
  }
  else if (proto.write && proto.flush && proto.end) {
    // plain ol' streams
    massWrap(
      proto,
      [
        'write',
        'flush',
        'end'
      ],
      activator
    );
  }
}

// Wrap Crypto
var crypto;
try { crypto = require('crypto'); } catch (err) { }
if (crypto) {
  massWrap(
    crypto,
    [
      'pbkdf2',
      'randomBytes',
      'pseudoRandomBytes',
    ],
    activator
  );
}
<commit_msg>glue: don't double-wrap timer functions<commit_after>'use strict';

if (process.addAsyncListener) throw new Error("Don't require polyfill unless needed");

var shimmer      = require('shimmer')
  , wrap         = shimmer.wrap
  , massWrap     = shimmer.massWrap
  , wrapCallback = require('./glue.js')
  ;

// Shim activator for functions that have callback last
function activator(fn) {
  return function () {
    var index = arguments.length - 1;
    if (typeof arguments[index] === "function") {
      arguments[index] = wrapCallback(arguments[index]);
    }
    return fn.apply(this, arguments);
  };
}

// Shim activator for functions that have callback first
function activatorFirst(fn) {
  return function () {
    if (typeof arguments[0] === "function") {
      arguments[0] = wrapCallback(arguments[0]);
    }
    return fn.apply(this, arguments);
  };
}

var net = require('net');
wrap(net.Server.prototype, '_listen2', function (original) {
  return function () {
    this.on('connection', function (socket) {
      socket._handle.onread = wrapCallback(socket._handle.onread);
    });
    var result = original.apply(this, arguments);
    this._handle.onconnection = wrapCallback(this._handle.onconnection);
    return result;
  };
});

wrap(net.Socket.prototype, 'connect', function (original) {
  return function () {
    var args = net._normalizeConnectArgs(arguments);
    if (args[1]) args[1] = wrapCallback(args[1]);
    var result = original.apply(this, args);
    this._handle.onread = wrapCallback(this._handle.onread);
    return result;
  };
});

var processors = ['nextTick'];
if (process._nextDomainTick) processors.push('_nextDomainTick');
if (process._tickDomainCallback) processors.push('_tickDomainCallback');

massWrap(
  process,
  processors,
  activator
);

var asynchronizers = [
  'setTimeout',
  'setInterval'
];
if (global.setImmediate) asynchronizers.push('setImmediate');

massWrap(
  require('timers'),
  asynchronizers,
  activatorFirst
);

var dns = require('dns');
massWrap(
  dns,
  [
    'lookup',
    'resolve',
    'resolve4',
    'resolve6',
    'resolveCname',
    'resolveMx',
    'resolveNs',
    'resolveTxt',
    'resolveSrv',
    'reverse'
  ],
  activator
);

if (dns.resolveNaptr) wrap(dns, 'resolveNaptr', activator);

var fs = require('fs');
massWrap(
  fs,
  [
    'watch',
    'rename',
    'truncate',
    'chown',
    'fchown',
    'chmod',
    'fchmod',
    'stat',
    'lstat',
    'fstat',
    'link',
    'symlink',
    'readlink',
    'realpath',
    'unlink',
    'rmdir',
    'mkdir',
    'readdir',
    'close',
    'open',
    'utimes',
    'futimes',
    'fsync',
    'write',
    'read',
    'readFile',
    'writeFile',
    'appendFile',
    'watchFile',
    'unwatchFile',
    "exists",
  ],
  activator
);

// only wrap lchown and lchmod on systems that have them.
if (fs.lchown) wrap(fs, 'lchown', activator);
if (fs.lchmod) wrap(fs, 'lchmod', activator);

// only wrap ftruncate in versions of node that have it
if (fs.ftruncate) wrap(fs, 'ftruncate', activator);

// Wrap zlib streams
var zlib;
try { zlib = require('zlib'); } catch (err) { }
if (zlib && zlib.Deflate && zlib.Deflate.prototype) {
  var proto = Object.getPrototypeOf(zlib.Deflate.prototype);
  if (proto._transform) {
    // streams2
    wrap(proto, "_transform", activator);
  }
  else if (proto.write && proto.flush && proto.end) {
    // plain ol' streams
    massWrap(
      proto,
      [
        'write',
        'flush',
        'end'
      ],
      activator
    );
  }
}

// Wrap Crypto
var crypto;
try { crypto = require('crypto'); } catch (err) { }
if (crypto) {
  massWrap(
    crypto,
    [
      'pbkdf2',
      'randomBytes',
      'pseudoRandomBytes',
    ],
    activator
  );
}
<|endoftext|>


<commit_before>'use strict'

const self = require('sdk/self')
const cm = require('sdk/context-menu')
const sp = require('sdk/simple-prefs')
const ps = require('sdk/preferences/service')
const tabs = require('sdk/tabs')
const { debounce } = require('sdk/lang/functional')
const { translate, translateUrl } = require('./providers/google-translate')
const languages = require('./languages')
const { getMostRecentBrowserWindow } = require('sdk/window/utils')
const addonUnload = require('sdk/system/unload')

// Context Menu
const LABEL_LOADING = 'Fetching translation…'
const LABEL_TRANSLATE = 'Translate “{0}”'
const LABEL_CHANGE_LANGUAGES = 'Change Languages ({0} > {1})'

// Replace params in a string à la Python
const strParams = str => {
  var params = [].slice.call(arguments, 1)
  for (var i = 0; i < params.length; i++) {
    str = str.replace(new RegExp(`\\{${i}\\}`, 'g'), params[i])
  }
  return str
}

// Get the From language from the preferences
const currentFrom = () => {
  const langCode = sp.prefs.lang_from
  const lang = languages[langCode]
  return {
    code: langCode,
    name: (lang && (lang.fromName || lang.name)) || null,
  }
}

// Get the To language from the preferences
const currentTo = () => {
  let langCode = sp.prefs.lang_to
  if (langCode === 'auto') {
    langCode = ps.getLocalized('general.useragent.locale', 'en')
    if (!langCode.startsWith('zh')) {
      langCode = langCode.replace(/-[a-zA-Z]+$/, '')
    }
  }
  const lang = languages[langCode]
  return {
    code: langCode,
    name: (lang && lang.name) || null,
  }
}

// Utility function to create elements
const eltCreator = doc => (name, props, attrs, parent) => {
  const elt = doc.createElement(name)
  if (props) Object.keys(props).forEach(p => elt[p] = props[p])
  if (attrs) Object.keys(attrs).forEach(a => elt.setAttribute(a, attrs[a]))
  if (parent) parent.appendChild(elt)
  return elt
}

const langToItems = (languages, doc) => (
  Object.keys(languages)
    .filter(lang => !languages[lang].onlyFrom)
    .map(lang => {
      const item = doc.createElement('menuitem')
      item.setAttribute('label', languages[lang].name)
      item.setAttribute('data-gtranslate-to', lang)
      return item
    })
)

const langFromMenus = (languages, doc) => {
  const toItemsPopup = doc.createElement('menupopup')
  langToItems(languages, doc).forEach(item => toItemsPopup.appendChild(item))
  return Object.keys(languages)
    .filter(lang => !languages[lang].onlyTo)
    .map(lang => {
      const menu = doc.createElement('menu')
      menu.setAttribute('label', languages[lang].fromName || languages[lang].name)
      menu.setAttribute('data-gtranslate-from', lang)
      menu.appendChild(toItemsPopup.cloneNode(true))
      return menu
    })
}

// Returns the current selection based on the active node
const getSelectionFromNode = node => {
  const contentWin = node.ownerDocument.defaultView
  const name = node.nodeName.toLowerCase()
  const text = contentWin.getSelection().toString().trim()
  if (text) {
    return text
  }
  if (name === 'input' || name === 'textarea') {
    return node.value.substr(
      node.selectionStart,
      node.selectionEnd-node.selectionStart
    ) || null
  }
  if (name === 'a') {
    return node.textContent || node.title || null
  }
  if (name === 'img') {
    return node.alt || node.title || null
  }
  return null
}

// Returns the current selection from a window
const getSelectionFromWin = win => {
  const popupNode = win.gContextMenuContentData.popupNode
  return (popupNode && getSelectionFromNode(popupNode)) || ''
}

// Addon loaded
const start = () => {
  const win = getMostRecentBrowserWindow()
  const doc = win.document
  const cmNode = doc.getElementById('contentAreaContextMenu')
  const elt = eltCreator(doc)

  const translateMenu = elt(
    'menu', { className: 'menu-iconic' },
    { label: LABEL_TRANSLATE, image: self.data.url('menuitem.svg') }
  )
  const translatePopup = elt('menupopup', null, null, translateMenu)
  const result = elt('menuitem', null, null, translatePopup)
  const separator = elt('menuseparator', null, null, translatePopup)
  const langMenu = elt('menu', null, null, translatePopup)
  const fromPopup = elt('menupopup', null, null, langMenu)
  const fromMenus = langFromMenus(languages, doc)

  fromMenus.forEach(menu => fromPopup.appendChild(menu))

  const updateResult = translation => {
    result.setAttribute('tooltiptext', translation || '')
    result.setAttribute('label', translation || LABEL_LOADING)
    result.setAttribute('disabled', !translation)
  }

  // Update the menu when the preferences are updated
  sp.on('', () => {
    updateLangMenuLabel()
    updateLangMenuChecks()
  })

  // Update the languages menu label (“Change Languages […]”)
  const updateLangMenuLabel = detected => {
    const from = detected? `${languages[detected].name} - detected` : currentFrom().name
    const to = currentTo().name
    langMenu.setAttribute('label', strParams(LABEL_CHANGE_LANGUAGES, from, to))
  }

  const updateLangMenuChecks = () => {

    // Uncheck
    const checkedElts = fromPopup.querySelectorAll('[checked]')
    for (let elt of checkedElts) elt.removeAttribute('checked')

    // Check
    const from = currentFrom().code
    const to = currentTo().code
    const fromMenu = fromPopup.querySelector(`[data-gtranslate-from="${from}"]`)
    const toItem = fromMenu && fromMenu.querySelector(`[data-gtranslate-to="${to}"]`)
    if (fromMenu && toItem) {
      fromMenu.setAttribute('checked', true)
      toItem.setAttribute('checked', true)
    }
  }

  // Show the context menupopup
  const showContextMenu = event => {
    const selection = getSelectionFromWin(win)

    translateMenu.setAttribute('hidden', !selection)
    if (!selection) return

    translateMenu.setAttribute('label', strParams(LABEL_TRANSLATE, selection))
    updateResult(null)
    updateLangMenuLabel()
  }

  // Show the results menupopup
  const showResultsMenu = event => {
    const selection = getSelectionFromWin(win)

    translate(currentFrom().code, currentTo().code, selection, res => {
      updateResult(res.translation)
      if (sp.prefs.lang_from === 'auto') {
        updateLangMenuLabel(res.detectedSource)
      }
    })
  }

  // Listen to popupshowing events
  const onPopupshowing = event => {
    if (event.target === cmNode) {
      return showContextMenu(event)
    }
    if (event.target === translatePopup) {
      return showResultsMenu(event)
    }
  }

  // Listen to command events
  const onContextCommand = event => {
    const target = event.target
    const parent = target.parentNode && target.parentNode.parentNode
    const selection = getSelectionFromWin(win)

    // Open the translation page
    if (target === result) {
      tabs.open(translateUrl(currentFrom().code, currentTo().code, selection))
      return
    }

    // Language change
    if (target.hasAttribute('data-gtranslate-to') &&
        parent && parent.hasAttribute('data-gtranslate-from')) {
      sp.prefs.lang_to = target.getAttribute('data-gtranslate-to')
      sp.prefs.lang_from = parent.getAttribute('data-gtranslate-from')
    }
  }

  cmNode.appendChild(translateMenu)
  cmNode.addEventListener('popupshowing', onPopupshowing)
  cmNode.addEventListener('command', onContextCommand)

  updateLangMenuChecks()

  // Addon unloaded
  addonUnload.when(() => {
    cmNode.removeEventListener('popupshowing', onPopupshowing)
    cmNode.removeEventListener('command', onContextCommand)
    cmNode.removeChild(translateMenu)
  })
}

start()
<commit_msg>Do not disable the result menu<commit_after>'use strict'

const self = require('sdk/self')
const cm = require('sdk/context-menu')
const sp = require('sdk/simple-prefs')
const ps = require('sdk/preferences/service')
const tabs = require('sdk/tabs')
const { debounce } = require('sdk/lang/functional')
const { translate, translateUrl } = require('./providers/google-translate')
const languages = require('./languages')
const { getMostRecentBrowserWindow } = require('sdk/window/utils')
const addonUnload = require('sdk/system/unload')

// Context Menu
const LABEL_LOADING = 'Fetching translation…'
const LABEL_TRANSLATE = 'Translate “{0}”'
const LABEL_CHANGE_LANGUAGES = 'Change Languages ({0} > {1})'

// Replace params in a string à la Python
const strParams = str => {
  var params = [].slice.call(arguments, 1)
  for (var i = 0; i < params.length; i++) {
    str = str.replace(new RegExp(`\\{${i}\\}`, 'g'), params[i])
  }
  return str
}

// Get the From language from the preferences
const currentFrom = () => {
  const langCode = sp.prefs.lang_from
  const lang = languages[langCode]
  return {
    code: langCode,
    name: (lang && (lang.fromName || lang.name)) || null,
  }
}

// Get the To language from the preferences
const currentTo = () => {
  let langCode = sp.prefs.lang_to
  if (langCode === 'auto') {
    langCode = ps.getLocalized('general.useragent.locale', 'en')
    if (!langCode.startsWith('zh')) {
      langCode = langCode.replace(/-[a-zA-Z]+$/, '')
    }
  }
  const lang = languages[langCode]
  return {
    code: langCode,
    name: (lang && lang.name) || null,
  }
}

// Utility function to create elements
const eltCreator = doc => (name, props, attrs, parent) => {
  const elt = doc.createElement(name)
  if (props) Object.keys(props).forEach(p => elt[p] = props[p])
  if (attrs) Object.keys(attrs).forEach(a => elt.setAttribute(a, attrs[a]))
  if (parent) parent.appendChild(elt)
  return elt
}

const langToItems = (languages, doc) => (
  Object.keys(languages)
    .filter(lang => !languages[lang].onlyFrom)
    .map(lang => {
      const item = doc.createElement('menuitem')
      item.setAttribute('label', languages[lang].name)
      item.setAttribute('data-gtranslate-to', lang)
      return item
    })
)

const langFromMenus = (languages, doc) => {
  const toItemsPopup = doc.createElement('menupopup')
  langToItems(languages, doc).forEach(item => toItemsPopup.appendChild(item))
  return Object.keys(languages)
    .filter(lang => !languages[lang].onlyTo)
    .map(lang => {
      const menu = doc.createElement('menu')
      menu.setAttribute('label', languages[lang].fromName || languages[lang].name)
      menu.setAttribute('data-gtranslate-from', lang)
      menu.appendChild(toItemsPopup.cloneNode(true))
      return menu
    })
}

// Returns the current selection based on the active node
const getSelectionFromNode = node => {
  const contentWin = node.ownerDocument.defaultView
  const name = node.nodeName.toLowerCase()
  const text = contentWin.getSelection().toString().trim()
  if (text) {
    return text
  }
  if (name === 'input' || name === 'textarea') {
    return node.value.substr(
      node.selectionStart,
      node.selectionEnd-node.selectionStart
    ) || null
  }
  if (name === 'a') {
    return node.textContent || node.title || null
  }
  if (name === 'img') {
    return node.alt || node.title || null
  }
  return null
}

// Returns the current selection from a window
const getSelectionFromWin = win => {
  const popupNode = win.gContextMenuContentData.popupNode
  return (popupNode && getSelectionFromNode(popupNode)) || ''
}

// Addon loaded
const start = () => {
  const win = getMostRecentBrowserWindow()
  const doc = win.document
  const cmNode = doc.getElementById('contentAreaContextMenu')
  const elt = eltCreator(doc)

  const translateMenu = elt(
    'menu', { className: 'menu-iconic' },
    { label: LABEL_TRANSLATE, image: self.data.url('menuitem.svg') }
  )
  const translatePopup = elt('menupopup', null, null, translateMenu)
  const result = elt('menuitem', null, null, translatePopup)
  const separator = elt('menuseparator', null, null, translatePopup)
  const langMenu = elt('menu', null, null, translatePopup)
  const fromPopup = elt('menupopup', null, null, langMenu)
  const fromMenus = langFromMenus(languages, doc)

  fromMenus.forEach(menu => fromPopup.appendChild(menu))

  const updateResult = translation => {
    result.setAttribute('tooltiptext', translation || '')
    result.setAttribute('label', translation || LABEL_LOADING)
  }

  // Update the menu when the preferences are updated
  sp.on('', () => {
    updateLangMenuLabel()
    updateLangMenuChecks()
  })

  // Update the languages menu label (“Change Languages […]”)
  const updateLangMenuLabel = detected => {
    const from = detected? `${languages[detected].name} - detected` : currentFrom().name
    const to = currentTo().name
    langMenu.setAttribute('label', strParams(LABEL_CHANGE_LANGUAGES, from, to))
  }

  const updateLangMenuChecks = () => {

    // Uncheck
    const checkedElts = fromPopup.querySelectorAll('[checked]')
    for (let elt of checkedElts) elt.removeAttribute('checked')

    // Check
    const from = currentFrom().code
    const to = currentTo().code
    const fromMenu = fromPopup.querySelector(`[data-gtranslate-from="${from}"]`)
    const toItem = fromMenu && fromMenu.querySelector(`[data-gtranslate-to="${to}"]`)
    if (fromMenu && toItem) {
      fromMenu.setAttribute('checked', true)
      toItem.setAttribute('checked', true)
    }
  }

  // Show the context menupopup
  const showContextMenu = event => {
    const selection = getSelectionFromWin(win)

    translateMenu.setAttribute('hidden', !selection)
    if (!selection) return

    translateMenu.setAttribute('label', strParams(LABEL_TRANSLATE, selection))
    updateResult(null)
    updateLangMenuLabel()
  }

  // Show the results menupopup
  const showResultsMenu = event => {
    const selection = getSelectionFromWin(win)

    translate(currentFrom().code, currentTo().code, selection, res => {
      updateResult(res.translation)
      if (sp.prefs.lang_from === 'auto') {
        updateLangMenuLabel(res.detectedSource)
      }
    })
  }

  // Listen to popupshowing events
  const onPopupshowing = event => {
    if (event.target === cmNode) {
      return showContextMenu(event)
    }
    if (event.target === translatePopup) {
      return showResultsMenu(event)
    }
  }

  // Listen to command events
  const onContextCommand = event => {
    const target = event.target
    const parent = target.parentNode && target.parentNode.parentNode
    const selection = getSelectionFromWin(win)

    // Open the translation page
    if (target === result) {
      tabs.open(translateUrl(currentFrom().code, currentTo().code, selection))
      return
    }

    // Language change
    if (target.hasAttribute('data-gtranslate-to') &&
        parent && parent.hasAttribute('data-gtranslate-from')) {
      sp.prefs.lang_to = target.getAttribute('data-gtranslate-to')
      sp.prefs.lang_from = parent.getAttribute('data-gtranslate-from')
    }
  }

  cmNode.appendChild(translateMenu)
  cmNode.addEventListener('popupshowing', onPopupshowing)
  cmNode.addEventListener('command', onContextCommand)

  updateLangMenuChecks()

  // Addon unloaded
  addonUnload.when(() => {
    cmNode.removeEventListener('popupshowing', onPopupshowing)
    cmNode.removeEventListener('command', onContextCommand)
    cmNode.removeChild(translateMenu)
  })
}

start()
<|endoftext|>