<commit_before>"use strict";
var Promise = require("bluebird");
var extend = require("extend");

var AppServiceRegistration = require("matrix-appservice-bridge").AppServiceRegistration;

var IrcBridge = require("./bridge/instance.js");
var IrcServer = require("./irclib/server.js").IrcServer;
var stats = require("./config/stats");
var ident = require("./irclib/ident");
var logging = require("./logging");
var log = logging.get("main");

var _toServer = function(domain, serverConfig) {
    // set server config defaults
    if (serverConfig.dynamicChannels.visibility) {
        throw new Error(
            `[DEPRECATED] Use of the config field dynamicChannels.visibility
            is deprecated. Use dynamicChannels.published, dynamicChannels.joinRule
            and dynamicChannels.createAlias instead.`
        );
    }
    return new IrcServer(domain, extend(true, IrcServer.DEFAULT_CONFIG, serverConfig));
};

module.exports.defaultConfig = function() {
    return {
        ircService: {
            ident: {
                enabled: false,
                port: 113
            },
            logging: {
                level: "debug",
                toConsole: true
            },
            statsd: {}
        }
    };
};

module.exports.generateRegistration = Promise.coroutine(function*(reg, config) {
    var asToken;
    if (config.appService) {
        console.warn(
            `[DEPRECATED] Use of config field 'appService' is deprecated.
            Remove this field from the config file to remove this warning.

            This release will use values from this config file. This will produce
            a fatal error in a later release.

            The new format looks like:
            homeserver:
                url: "https://home.server.url"
                domain: "home.server.url"

            The new locations for the missing fields are as follows:
            http.port - Passed as a CLI flag --port.
            appservice.token - Automatically generated.
            appservice.url - Passed as a CLI flag --url
            localpart - Passed as a CLI flag --localpart
            `
        );
        if (config.appService.localpart) {
            console.log("NOTICE: Using localpart from config file");
            reg.setSenderLocalpart(config.appService.localpart);
        }
        asToken = config.appService.appservice.token;
    }

    if (!reg.getSenderLocalpart()) {
        reg.setSenderLocalpart(IrcBridge.DEFAULT_LOCALPART);
    }

    reg.setHomeserverToken(AppServiceRegistration.generateToken());
    reg.setAppServiceToken(asToken || AppServiceRegistration.generateToken());

    let serverDomains = Object.keys(config.ircService.servers);
    serverDomains.forEach(function(domain) {
        let server = _toServer(domain, config.ircService.servers[domain]);
        server.getHardCodedRoomIds().forEach(function(roomId) {
            reg.addRegexPattern("rooms", roomId, false);
        });
        // add an alias pattern for servers who want aliases exposed.
        if (server.createsDynamicAliases()) {
            reg.addRegexPattern("aliases", server.getAliasRegex(), true);
        }
        reg.addRegexPattern("users", server.getUserRegex(), true);
    });

    return reg;
});

module.exports.runBridge = Promise.coroutine(function*(port, config, reg) {
    // configure global stuff for the process
    if (config.ircService.logging) {
        logging.configure(config.ircService.logging);
        logging.setUncaughtExceptionLogger(log);
    }
    if (config.ircService.statsd.hostname) {
        stats.setEndpoint(config.ircService.statsd);
    }
    if (config.ircService.ident.enabled) {
        ident.configure(config.ircService.ident);
        ident.run();
    }

    if (config.appService && !config.homeserver) {
        config.homeserver = config.appService.homeserver;
    }

    // run the bridge
    var ircBridge = new IrcBridge(config, reg);
    yield ircBridge.run(port);
});
<commit_msg>Deterministically generate config file<commit_after>"use strict";
var Promise = require("bluebird");
var extend = require("extend");

var AppServiceRegistration = require("matrix-appservice-bridge").AppServiceRegistration;

var IrcBridge = require("./bridge/instance.js");
var IrcServer = require("./irclib/server.js").IrcServer;
var stats = require("./config/stats");
var ident = require("./irclib/ident");
var logging = require("./logging");
var log = logging.get("main");

var _toServer = function(domain, serverConfig) {
    // set server config defaults
    if (serverConfig.dynamicChannels.visibility) {
        throw new Error(
            `[DEPRECATED] Use of the config field dynamicChannels.visibility
            is deprecated. Use dynamicChannels.published, dynamicChannels.joinRule
            and dynamicChannels.createAlias instead.`
        );
    }
    return new IrcServer(domain, extend(true, IrcServer.DEFAULT_CONFIG, serverConfig));
};

module.exports.defaultConfig = function() {
    return {
        ircService: {
            ident: {
                enabled: false,
                port: 113
            },
            logging: {
                level: "debug",
                toConsole: true
            },
            statsd: {}
        }
    };
};

module.exports.generateRegistration = Promise.coroutine(function*(reg, config) {
    var asToken;
    if (config.appService) {
        console.warn(
            `[DEPRECATED] Use of config field 'appService' is deprecated.
            Remove this field from the config file to remove this warning.

            This release will use values from this config file. This will produce
            a fatal error in a later release.

            The new format looks like:
            homeserver:
                url: "https://home.server.url"
                domain: "home.server.url"

            The new locations for the missing fields are as follows:
            http.port - Passed as a CLI flag --port.
            appservice.token - Automatically generated.
            appservice.url - Passed as a CLI flag --url
            localpart - Passed as a CLI flag --localpart
            `
        );
        if (config.appService.localpart) {
            console.log("NOTICE: Using localpart from config file");
            reg.setSenderLocalpart(config.appService.localpart);
        }
        asToken = config.appService.appservice.token;
    }

    if (!reg.getSenderLocalpart()) {
        reg.setSenderLocalpart(IrcBridge.DEFAULT_LOCALPART);
    }

    reg.setHomeserverToken(AppServiceRegistration.generateToken());
    reg.setAppServiceToken(asToken || AppServiceRegistration.generateToken());

    let serverDomains = Object.keys(config.ircService.servers);
    serverDomains.sort().forEach(function(domain) {
        let server = _toServer(domain, config.ircService.servers[domain]);
        server.getHardCodedRoomIds().sort().forEach(function(roomId) {
            reg.addRegexPattern("rooms", roomId, false);
        });
        // add an alias pattern for servers who want aliases exposed.
        if (server.createsDynamicAliases()) {
            reg.addRegexPattern("aliases", server.getAliasRegex(), true);
        }
        reg.addRegexPattern("users", server.getUserRegex(), true);
    });

    return reg;
});

module.exports.runBridge = Promise.coroutine(function*(port, config, reg) {
    // configure global stuff for the process
    if (config.ircService.logging) {
        logging.configure(config.ircService.logging);
        logging.setUncaughtExceptionLogger(log);
    }
    if (config.ircService.statsd.hostname) {
        stats.setEndpoint(config.ircService.statsd);
    }
    if (config.ircService.ident.enabled) {
        ident.configure(config.ircService.ident);
        ident.run();
    }

    if (config.appService && !config.homeserver) {
        config.homeserver = config.appService.homeserver;
    }

    // run the bridge
    var ircBridge = new IrcBridge(config, reg);
    yield ircBridge.run(port);
});
<|endoftext|>


<commit_before>var Moonboots = require('moonboots');
var Emitter = require('events').EventEmitter;
var path = require('path');
var ncp = require('ncp');
var async = require('async');
var fs = require('fs');
var rimraf = require('rimraf');
var mkdirp = require('mkdirp');
require('colors');

var last = function (arr) { return arr[arr.length - 1]; };
function timingString(ms) {
    ms = ms + '';
    var ws = new Array(5 - ms.length).join(' ');
    return (ws + ms + 'ms').red + ' | ';
}

function MoonbootsStatic(options) {
    if (options !== Object(options)) {
        throw new Error('Invalid options');
    }

    Emitter.call(this);

    this.initialTime = Date.now();
    this.lastTime = this.initialTime;

    this.verbose = options.verbose;
    if (this.verbose) {
        options.moonboots.timingMode = true;
    }

    this.moonboots = new Moonboots(options.moonboots);
    this.moonboots.on('ready', this.build.bind(this));
    this.moonboots.on('log', this.emitPassThrough.bind(this, 'log'));

    this.dir = options.directory;
    this.resourceDir = path.join(this.dir, this.moonboots.config.resourcePrefix);
    this.publicDirectory = options.public;
    this.htmlSource = options.htmlSource;
    this.cb = options.cb;
}

MoonbootsStatic.prototype = Object.create(Emitter.prototype, {
    constructor: {
        value: MoonbootsStatic
    }
});

MoonbootsStatic.prototype.emitPassThrough = function () {
    this.emit.apply(this, arguments);
    if (this.verbose) {
        this.timingLog.apply(this, arguments);
    }
};

MoonbootsStatic.prototype.timingLog = function () {
    var timing = arguments[3];
    var message = arguments[2];

    if (last(message.split(' ')) === 'finish') {
        console.log(timingString(timing - this.lastTime) + message.replace('finish', ''));
        this.lastTime = timing;
    }
    else if (message === 'built') {
        console.log('-----------------------');
        console.log(timingString(timing - this.initialTime) + 'Complete'.blue);
    }
};

MoonbootsStatic.prototype.build = function () {
    var self = this;
    var tasks = [
        this.writeFile.bind(this, 'html'),
        this.writeFile.bind(this, 'js')
    ];

    if (this.moonboots.config.stylesheets.length > 0) {
        tasks.push(this.writeFile.bind(this, 'css'));
    }

    async.series([
        function (cb) {
            rimraf(self.dir, cb);
        },
        function (cb) {
            mkdirp(self.dir, cb);
        },
        function (cb) {
            mkdirp(self.resourceDir, cb);
        }
    ], function (err) {
        async.parallel(tasks, function (err) {
            if (self.publicDirectory) {
                ncp(self.publicDirectory, self.dir, self.done.bind(self));
            } else {
                self.done(err);
            }
        });
    });
};

MoonbootsStatic.prototype.done = function (err) {
    this.moonboots.timing('built');
    this.cb ? this.cb(err) : this.emit('ready', err);
};

MoonbootsStatic.prototype.writeFile = function (type, cb) {
    var self = this;
    var moonboots = this.moonboots;
    var filename, source;

    if (type === 'html') {
        filename = 'index.html';
        source = function (cb) {
            var context = moonboots.htmlContext();
            context.resourcePrefix = moonboots.config.resourcePrefix;
            var src;
            if (self.htmlSource) {
                src = self.htmlSource.call(moonboots, context);
            } else {
                src = moonboots.htmlSource();
            }
            cb(null, src);
        };
    } else {
        filename = path.join(this.moonboots.config.resourcePrefix, moonboots[type + 'FileName']());
        source = moonboots[type + 'Source'];
    }

    source.call(moonboots, function (err, src) {
        fs.writeFile(path.join(self.dir, filename), src, cb);
    });
};

module.exports = MoonbootsStatic;
<commit_msg>Better error handling when module is not found<commit_after>var Moonboots = require('moonboots');
var Emitter = require('events').EventEmitter;
var path = require('path');
var ncp = require('ncp');
var async = require('async');
var fs = require('fs');
var rimraf = require('rimraf');
var mkdirp = require('mkdirp');
require('colors');

var last = function (arr) { return arr[arr.length - 1]; };
function timingString(ms) {
    ms = ms + '';
    var ws = new Array(5 - ms.length).join(' ');
    return (ws + ms + 'ms').red + ' | ';
}

function MoonbootsStatic(options) {
    if (options !== Object(options)) {
        throw new Error('Invalid options');
    }

    Emitter.call(this);

    this.initialTime = Date.now();
    this.lastTime = this.initialTime;

    this.verbose = options.verbose;
    if (this.verbose) {
        options.moonboots.timingMode = true;
    }

    this.moonboots = new Moonboots(options.moonboots);
    this.moonboots.on('ready', this.build.bind(this));
    this.moonboots.on('log', this.emitPassThrough.bind(this, 'log'));

    this.dir = options.directory;
    this.resourceDir = path.join(this.dir, this.moonboots.config.resourcePrefix);
    this.publicDirectory = options.public;
    this.htmlSource = options.htmlSource;
    this.cb = options.cb;
}

MoonbootsStatic.prototype = Object.create(Emitter.prototype, {
    constructor: {
        value: MoonbootsStatic
    }
});

MoonbootsStatic.prototype.emitPassThrough = function () {
    this.emit.apply(this, arguments);
    if (this.verbose) {
        this.timingLog.apply(this, arguments);
    }
};

MoonbootsStatic.prototype.timingLog = function () {
    var timing = arguments[3];
    var message = arguments[2];

    if( typeof message != 'object' ){

        if (last(message.split(' ')) === 'finish') {
            console.log(timingString(timing - this.lastTime) + message.replace('finish', ''));
            this.lastTime = timing;
        }
        else if (message === 'built') {
            console.log('-----------------------');
            console.log(timingString(timing - this.initialTime) + 'Complete'.blue);
        }

    } else {

        throw( message );

    }
};

MoonbootsStatic.prototype.build = function () {
    var self = this;
    var tasks = [
        this.writeFile.bind(this, 'html'),
        this.writeFile.bind(this, 'js')
    ];

    if (this.moonboots.config.stylesheets.length > 0) {
        tasks.push(this.writeFile.bind(this, 'css'));
    }

    async.series([
        function (cb) {
            rimraf(self.dir, cb);
        },
        function (cb) {
            mkdirp(self.dir, cb);
        },
        function (cb) {
            mkdirp(self.resourceDir, cb);
        }
    ], function (err) {
        async.parallel(tasks, function (err) {
            if (self.publicDirectory) {
                ncp(self.publicDirectory, self.dir, self.done.bind(self));
            } else {
                self.done(err);
            }
        });
    });
};

MoonbootsStatic.prototype.done = function (err) {
    this.moonboots.timing('built');
    this.cb ? this.cb(err) : this.emit('ready', err);
};

MoonbootsStatic.prototype.writeFile = function (type, cb) {
    var self = this;
    var moonboots = this.moonboots;
    var filename, source;

    if (type === 'html') {
        filename = 'index.html';
        source = function (cb) {
            var context = moonboots.htmlContext();
            context.resourcePrefix = moonboots.config.resourcePrefix;
            var src;
            if (self.htmlSource) {
                src = self.htmlSource.call(moonboots, context);
            } else {
                src = moonboots.htmlSource();
            }
            cb(null, src);
        };
    } else {
        filename = path.join(this.moonboots.config.resourcePrefix, moonboots[type + 'FileName']());
        source = moonboots[type + 'Source'];
    }

    source.call(moonboots, function (err, src) {
        fs.writeFile(path.join(self.dir, filename), src, cb);
    });
};

module.exports = MoonbootsStatic;
<|endoftext|>


<commit_before>'use strict';

const _ = require('lodash');
const turfCircle = require('@turf/circle');
const turfBbox = require('@turf/bbox');
const turfBboxPoly = require('@turf/bbox-polygon');
const turfTruncate = require('@turf/truncate');
const turfDestination = require('@turf/destination');
const turfDistance = require('@turf/distance');
const turfHelpers = require('@turf/helpers');

/**
 * A `google.maps.Circle` replacement for Mapbox GL JS, rendering a "spherical cap" on top of the world.
 * @class MapboxCircle
 */
class MapboxCircle {
    /** @param {mapboxgl.Map} map Target map. */
    set map(map) {
        if (this._map === undefined) {
            this._map = map;
        } else {
            throw new TypeError('MapboxCircle.map immutable.');
        }
    }

    /** @return {mapboxgl.Map} Mapbox map. */
    get map() {
        return this._map;
    }

    /** @param {Array<Number>} newCenter Center `[lng, lat]` coordinates. */
    set center(newCenter) {
        this._center = newCenter;
        this._updateCircle();
        this._animate();
    }

    /** @return {Array<Number>} Center `[lng, lat]` coordinates. */
    get center() {
        return this._center;
    }

    /** @param {Number} newRadius Meter radius. */
    set radius(newRadius) {
        this._radius = newRadius;
        this._updateCircle();
        this._animate();
    }

    /** @return {Number} Circle radius. */
    get radius() {
        return this._radius;
    }

    /** @param {Number} newZoom New zoom level. */
    set zoom(newZoom) {
        this._zoom = newZoom;
        this._updateCircle();
        this._animate();
    }

    /**
     * @param {Array<Number>} center Center `[lng, lat]` coordinates.
     * @param {Number} radius Meter radius.
     * @param {?Object} options
     * @param {?String} [options.strokeColor='#000000'] Stroke color.
     * @param {?String} [options.fillColor='#FB6A4A'] Fill color.
     * @param {?Number} [options.fillOpacity=0.5] Fill opacity.
     * @param {?Object} [options.properties={}] Property metadata for Mapbox GL JS circle object.
     * @param {?HTMLElement} [options.statusEl] HTML element for emitting debug info.
     */
    constructor(center, radius, options) {
        /** @type {Array<Number>} */ this._center = center;
        /** @const {Number} */ this._radius = radius;
        /** @const {Object} */ this.options = _.extend({
            strokeColor: '#000000',
            strokeWeight: 2,
            strokeOpacity: 0.5,
            fillColor: '#FB6A4A',
            fillOpacity: 0.5,
            properties: {},
            statusEl: null
        }, options);

        /** @const {mapboxgl.Map} */ this._map = undefined;
        /** @const {Number} */ this._zoom = undefined;
        /** @const {Polygon} */ this._circle = undefined;
        /** @const {Array<Point>} */ this._handles = undefined;

        // Bind event handlers.
        this.onMouseMove = this.onMouseMove.bind(this);
        this.onCenterHandleMouseDown = this.onCenterHandleMouseDown.bind(this);
        this.onRadiusHandleMouseDown = this.onRadiusHandleMouseDown.bind(this);
        this.onCenterHandleMouseUp = this.onCenterHandleMouseUp.bind(this);
        this.onRadiusHandleMouseUp = this.onRadiusHandleMouseUp.bind(this);
        this.onCenterHandleMouseMove = this.onCenterHandleMouseMove.bind(this);
        this.onRadiusHandleMouseMove = this.onRadiusHandleMouseMove.bind(this);
        this.onZoomEnd = this.onZoomEnd.bind(this);

        // Initialize circle.
        this._updateCircle();
    }

    /**
     * Re-calculate/update circle polygon and handles.
     * @private
     */
    _updateCircle() {
        const zoom = !this._zoom || this._zoom <= 0.1 ? 0.1 : this._zoom;
        const steps = Math.max((Math.sqrt(Math.trunc(this._radius * 0.25)) * zoom ^ 2), 64);
        const units = 'meters';

        this._circle = turfCircle(this._center, this._radius, steps, units, this.options.properties);
        this._handles = [
            turfDestination(this._center, this._radius, 0, units),
            turfDestination(this._center, this._radius, 90, units),
            turfDestination(this._center, this._radius, 180, units),
            turfDestination(this._center, this._radius, -90, units)
        ];

        if (this.options.statusEl) {
            this.options.statusEl.innerHTML = ('Center: ' + this._center + ' / Radius: ' + Math.trunc(this._radius) +
                                               ' meters / Bounds: ' + this.getBounds() + ' / Steps: ' + steps);
        }
    }

    /**
     * Refresh map with the circle's GeoJSON.
     * @private
     */
    _animate() {
        // map.on('sourcedata', onSourceData)
        this._map.getSource('circle-1').setData(this._asGeoJSON());
    }

    /**
     * Return GeoJSON for circle and handles.
     * @private
     * @return {FeatureCollection}
     */
    _asGeoJSON() {
        let feats = this._handles;
        feats.push(this._circle);
        feats.push(turfHelpers.point(this._center, {'type': 'center'}));
        return turfHelpers.featureCollection(feats);
    }

    /**
     * Get geodesic bounds for the circle.
     * @return {[Number,Number,Number,Number]}
     */
    getBounds() {
        let bboxPoly = turfTruncate(turfBboxPoly(turfBbox(this._circle)), 6);
        return [
            bboxPoly.geometry.coordinates[0][0][0],
            bboxPoly.geometry.coordinates[0][0][1],
            bboxPoly.geometry.coordinates[0][2][0],
            bboxPoly.geometry.coordinates[0][2][1]
        ];
    }

    /*
    getBboxPoly() {
        return turfTruncate(turfBboxPoly(turfBbox(this._circle)), 6);
    }

    get_handles() {
        return turfHelpers.featureCollection(this._handles);
    }
    */

    /**
     * Adjust circle precision (steps used to draw the polygon).
     */
    onZoomEnd() {
        this.zoom = this.map.getZoom();
    }

    /**
     * Disable panning, set color of center handle, add onCenterHandleMouseMove (drag) listener and wait for mouse-up.
     */
    onCenterHandleMouseDown() {
        this.map.dragPan.disable();
        this.map.setPaintProperty('circle-center-handle', 'circle-color', '#a50f15');
        this.map.on('mousemove', this.onCenterHandleMouseMove);
        this.map.once('mouseup', this.onCenterHandleMouseUp);
    }

    /**
     * Mouse-move listener, emulating a drag listener in conjunction with onCenterHandleMouseDown/onCenterHandleMouseUp.
     * @param {MapMouseEvent} event
     */
    onCenterHandleMouseMove(event) {
        const mousePoint = turfTruncate(turfHelpers.point(this.map.unproject(event.point).toArray()), 6);
        this.center = mousePoint.geometry.coordinates;
    }

    /**
     * Restore center handle color, re-enable panning and remove onCenterHandleMouseMove (drag) listener.
     */
    onCenterHandleMouseUp() {
        this.map.setPaintProperty('circle-center-handle', 'circle-color', '#fb6a4a');
        this.map.dragPan.enable();
        this.map.off('mousemove', this.onCenterHandleMouseMove);
    }

    /**
     * Disable panning, set color of radius handles, add mouse-move listener and wait for mouse-up (emulating drag).
     */
    onRadiusHandleMouseDown() {
        this.map.dragPan.disable();
        this.map.setPaintProperty('circle-radius-handles', 'circle-color', '#a50f15');
        this.map.on('mousemove', this.onRadiusHandleMouseMove);
        this.map.once('mouseup', this.onRadiusHandleMouseUp);
    }

    /**
     * Mouse-move listener for the radius handles, emulating a drag event with
     * onRadiusHandleMouseDown/onRadiusHandleMouseUp.
     * @param {MapMouseEvent} event
     */
    onRadiusHandleMouseMove(event) {
        const mousePoint = this.map.unproject(event.point).toArray();
        this.radius = turfDistance(this.center, mousePoint, 'meters');
    }

    /**
     * Restore color of radius handles, re-enable panning and deactivate existing mouse-move listener.
     */
    onRadiusHandleMouseUp() {
        this.map.setPaintProperty('circle-radius-handles', 'circle-color', 'white');
        this.map.dragPan.enable();
        this.map.off('mousemove', this.onRadiusHandleMouseMove);
    }

    /**
     * Deactivate existing mouse-down listeners, check position and add new ones for map or handle as appropriate.
     * @param {MapMouseEvent} event
     */
    onMouseMove(event) {
        this.map.off('mousedown', this.onCenterHandleMouseDown);
        this.map.off('mousedown', this.onRadiusHandleMouseDown);

        let pointFeatures = this.map.queryRenderedFeatures(event.point, {
            layers: ['circle-radius-handles']
        });

        let circleFeatures = this.map.queryRenderedFeatures(event.point, {
            layers: ['circle-center-handle']
        });

        if ((!pointFeatures.length) && (!circleFeatures.length)) {
            this.map.getCanvas().style.cursor = '';
        }

        if (pointFeatures.length) {
            this.map.getCanvas().style.cursor = 'pointer';
            this.map.once('mousedown', this.onRadiusHandleMouseDown);
        } else if (circleFeatures.length) {
            this.map.getCanvas().style.cursor = 'pointer';
            this.map.once('mousedown', this.onCenterHandleMouseDown);
        }
    }

    /**
     * Set map and initialize it with Mapbox GL layers for circle artifacts.
     * @param {mapboxgl.Map} map
     * @return {MapboxCircle}
     */
    addTo(map) {
        this.map = map;

        this.map.on('load', () => {
            this.map.addSource('circle-1', {
                type: 'geojson',
                data: this._asGeoJSON(),
                buffer: 1
            });

            this.map.addLayer({
                id: 'circle-line',
                type: 'line',
                source: 'circle-1',
                paint: {
                    'line-color': this.options.strokeColor,
                    'line-width': this.options.strokeWeight,
                    'line-opacity': this.options.strokeOpacity
                },
                filter: ['==', '$type', 'Polygon']
            }, 'waterway-label');

            this.map.addLayer({
                id: 'circle-fill',
                type: 'fill',
                source: 'circle-1',
                paint: {
                    'fill-color': this.options.fillColor,
                    'fill-opacity': this.options.fillOpacity
                },
                filter: ['==', '$type', 'Polygon']
            }, 'waterway-label');

            this.map.addLayer({
                id: 'circle-radius-handles',
                type: 'circle',
                source: 'circle-1',
                paint: {
                    'circle-color': '#ffffff',
                    'circle-radius': 3.75,
                    'circle-stroke-color': this.options.strokeColor,
                    'circle-stroke-opacity': this.options.strokeOpacity,
                    'circle-stroke-width': this.options.strokeWeight
                },
                filter: ['all', ['==', '$type', 'Point'],
                    ['!=', 'type', 'center']
                ]
            });

            this.map.addLayer({
                id: 'circle-center-handle',
                type: 'circle',
                source: 'circle-1',
                paint: {
                    'circle-color': '#ffffff',
                    'circle-radius': 3.75,
                    'circle-stroke-color': this.options.strokeColor,
                    'circle-stroke-opacity': this.options.strokeOpacity,
                    'circle-stroke-width': this.options.strokeWeight
                },
                filter: ['all', ['==', '$type', 'Point'],
                    ['==', 'type', 'center']
                ]
            });

            this.map.on('zoomend', this.onZoomEnd);
            this.map.on('mousemove', _.debounce(this.onMouseMove, 16));
        });
        return this;
    }
}

module.exports = exports = MapboxCircle;
<commit_msg>Issue #14 Update JSDoc + use fillColor when pressing a handle<commit_after>'use strict';

const _ = require('lodash');
const turfCircle = require('@turf/circle');
const turfBbox = require('@turf/bbox');
const turfBboxPoly = require('@turf/bbox-polygon');
const turfTruncate = require('@turf/truncate');
const turfDestination = require('@turf/destination');
const turfDistance = require('@turf/distance');
const turfHelpers = require('@turf/helpers');

/**
 * A `google.maps.Circle` replacement for Mapbox GL JS, rendering a "spherical cap" on top of the world.
 * @class MapboxCircle
 */
class MapboxCircle {
    /** @param {mapboxgl.Map} map Target map. */
    set map(map) {
        if (this._map === undefined) {
            this._map = map;
        } else {
            throw new TypeError('MapboxCircle.map immutable.');
        }
    }

    /** @return {mapboxgl.Map} Mapbox map. */
    get map() {
        return this._map;
    }

    /** @param {Array<Number>} newCenter Center `[lng, lat]` coordinates. */
    set center(newCenter) {
        this._center = newCenter;
        this._updateCircle();
        this._animate();
    }

    /** @return {Array<Number>} Center `[lng, lat]` coordinates. */
    get center() {
        return this._center;
    }

    /** @param {Number} newRadius Meter radius. */
    set radius(newRadius) {
        this._radius = newRadius;
        this._updateCircle();
        this._animate();
    }

    /** @return {Number} Circle radius. */
    get radius() {
        return this._radius;
    }

    /** @param {Number} newZoom New zoom level. */
    set zoom(newZoom) {
        this._zoom = newZoom;
        this._updateCircle();
        this._animate();
    }

    /**
     * @param {Array<Number>} center Center `[lng, lat]` coordinates.
     * @param {Number} radius Meter radius.
     * @param {?Object} options
     * @param {?Boolean} [options.editable=false] Enable handles for changing center and radius.
     * @param {?String} [options.strokeColor='#000000'] Stroke color.
     * @param {?Number} [options.strokeWeight=2] Stroke weight.
     * @param {?Number} [options.strokeOpacity=0.5] Stroke opacity.
     * @param {?String} [options.fillColor='#FB6A4A'] Fill color.
     * @param {?Number} [options.fillOpacity=0.5] Fill opacity.
     * @param {?Object} [options.properties={}] Property metadata for Mapbox GL JS circle object.
     * @param {?HTMLElement} [options.statusEl] HTML element for emitting debug info.
     */
    constructor(center, radius, options) {
        /** @type {Array<Number>} */ this._center = center;
        /** @const {Number} */ this._radius = radius;
        /** @const {Object} */ this.options = _.extend({
            editable: false,
            strokeColor: '#000000',
            strokeWeight: 2,
            strokeOpacity: 0.5,
            fillColor: '#FB6A4A',
            fillOpacity: 0.5,
            properties: {},
            statusEl: null
        }, options);

        /** @const {mapboxgl.Map} */ this._map = undefined;
        /** @const {Number} */ this._zoom = undefined;
        /** @const {Polygon} */ this._circle = undefined;
        /** @const {Array<Point>} */ this._handles = undefined;

        // Bind event handlers.
        this.onMouseMove = this.onMouseMove.bind(this);
        this.onCenterHandleMouseDown = this.onCenterHandleMouseDown.bind(this);
        this.onRadiusHandleMouseDown = this.onRadiusHandleMouseDown.bind(this);
        this.onCenterHandleMouseUp = this.onCenterHandleMouseUp.bind(this);
        this.onRadiusHandleMouseUp = this.onRadiusHandleMouseUp.bind(this);
        this.onCenterHandleMouseMove = this.onCenterHandleMouseMove.bind(this);
        this.onRadiusHandleMouseMove = this.onRadiusHandleMouseMove.bind(this);
        this.onZoomEnd = this.onZoomEnd.bind(this);

        // Initialize circle.
        this._updateCircle();
    }

    /**
     * Re-calculate/update circle polygon and handles.
     * @private
     */
    _updateCircle() {
        const zoom = !this._zoom || this._zoom <= 0.1 ? 0.1 : this._zoom;
        const steps = Math.max((Math.sqrt(Math.trunc(this._radius * 0.25)) * zoom ^ 2), 64);
        const units = 'meters';

        this._circle = turfCircle(this._center, this._radius, steps, units, this.options.properties);
        this._handles = [
            turfDestination(this._center, this._radius, 0, units),
            turfDestination(this._center, this._radius, 90, units),
            turfDestination(this._center, this._radius, 180, units),
            turfDestination(this._center, this._radius, -90, units)
        ];

        if (this.options.statusEl) {
            this.options.statusEl.innerHTML = ('Center: ' + this._center + ' / Radius: ' + Math.trunc(this._radius) +
                                               ' meters / Bounds: ' + this.getBounds() + ' / Steps: ' + steps);
        }
    }

    /**
     * Refresh map with the circle's GeoJSON.
     * @private
     */
    _animate() {
        // map.on('sourcedata', onSourceData)
        this._map.getSource('circle-1').setData(this._asGeoJSON());
    }

    /**
     * Return GeoJSON for circle and handles.
     * @private
     * @return {FeatureCollection}
     */
    _asGeoJSON() {
        let feats = this._handles;
        feats.push(this._circle);
        feats.push(turfHelpers.point(this._center, {'type': 'center'}));
        return turfHelpers.featureCollection(feats);
    }

    /**
     * Get geodesic bounds for the circle.
     * @return {[Number,Number,Number,Number]}
     */
    getBounds() {
        let bboxPoly = turfTruncate(turfBboxPoly(turfBbox(this._circle)), 6);
        return [
            bboxPoly.geometry.coordinates[0][0][0],
            bboxPoly.geometry.coordinates[0][0][1],
            bboxPoly.geometry.coordinates[0][2][0],
            bboxPoly.geometry.coordinates[0][2][1]
        ];
    }

    /*
    getBboxPoly() {
        return turfTruncate(turfBboxPoly(turfBbox(this._circle)), 6);
    }

    get_handles() {
        return turfHelpers.featureCollection(this._handles);
    }
    */

    /**
     * Adjust circle precision (steps used to draw the polygon).
     */
    onZoomEnd() {
        this.zoom = this.map.getZoom();
    }

    /**
     * Disable panning, set color of center handle, add onCenterHandleMouseMove (drag) listener and wait for mouse-up.
     */
    onCenterHandleMouseDown() {
        this.map.dragPan.disable();
        this.map.setPaintProperty('circle-center-handle', 'circle-color', this.options.fillColor);
        this.map.on('mousemove', this.onCenterHandleMouseMove);
        this.map.once('mouseup', this.onCenterHandleMouseUp);
    }

    /**
     * Mouse-move listener, emulating a drag listener in conjunction with onCenterHandleMouseDown/onCenterHandleMouseUp.
     * @param {MapMouseEvent} event
     */
    onCenterHandleMouseMove(event) {
        const mousePoint = turfTruncate(turfHelpers.point(this.map.unproject(event.point).toArray()), 6);
        this.center = mousePoint.geometry.coordinates;
    }

    /**
     * Restore center handle color, re-enable panning and remove onCenterHandleMouseMove (drag) listener.
     */
    onCenterHandleMouseUp() {
        this.map.setPaintProperty('circle-center-handle', 'circle-color', '#ffffff');
        this.map.dragPan.enable();
        this.map.off('mousemove', this.onCenterHandleMouseMove);
    }

    /**
     * Disable panning, set color of radius handles, add mouse-move listener and wait for mouse-up (emulating drag).
     */
    onRadiusHandleMouseDown() {
        this.map.dragPan.disable();
        this.map.setPaintProperty('circle-radius-handles', 'circle-color', this.options.fillColor);
        this.map.on('mousemove', this.onRadiusHandleMouseMove);
        this.map.once('mouseup', this.onRadiusHandleMouseUp);
    }

    /**
     * Mouse-move listener for the radius handles, emulating a drag event with
     * onRadiusHandleMouseDown/onRadiusHandleMouseUp.
     * @param {MapMouseEvent} event
     */
    onRadiusHandleMouseMove(event) {
        const mousePoint = this.map.unproject(event.point).toArray();
        this.radius = turfDistance(this.center, mousePoint, 'meters');
    }

    /**
     * Restore color of radius handles, re-enable panning and deactivate existing mouse-move listener.
     */
    onRadiusHandleMouseUp() {
        this.map.setPaintProperty('circle-radius-handles', 'circle-color', '#ffffff');
        this.map.dragPan.enable();
        this.map.off('mousemove', this.onRadiusHandleMouseMove);
    }

    /**
     * Deactivate existing mouse-down listeners, check position and add new ones for map or handle as appropriate.
     * @param {MapMouseEvent} event
     */
    onMouseMove(event) {
        this.map.off('mousedown', this.onCenterHandleMouseDown);
        this.map.off('mousedown', this.onRadiusHandleMouseDown);

        let radiusHandle = this.map.queryRenderedFeatures(event.point, {
            layers: ['circle-radius-handles']
        });

        let centerHandle = this.map.queryRenderedFeatures(event.point, {
            layers: ['circle-center-handle']
        });

        if (radiusHandle.length || centerHandle.length) {
            this.map.getCanvas().style.cursor = 'pointer';
            let mouseDownHandler = radiusHandle.length ? this.onRadiusHandleMouseDown : this.onCenterHandleMouseDown;
            this.map.once('mousedown', mouseDownHandler);
        } else {
            this.map.getCanvas().style.cursor = '';
        }
    }

    /**
     * Set map and initialize it with Mapbox GL layers for circle artifacts.
     * @param {mapboxgl.Map} map
     * @return {MapboxCircle}
     */
    addTo(map) {
        this.map = map;

        this.map.on('load', () => {
            this.map.addSource('circle-1', {
                type: 'geojson',
                data: this._asGeoJSON(),
                buffer: 1
            });

            this.map.addLayer({
                id: 'circle-line',
                type: 'line',
                source: 'circle-1',
                paint: {
                    'line-color': this.options.strokeColor,
                    'line-width': this.options.strokeWeight,
                    'line-opacity': this.options.strokeOpacity
                },
                filter: ['==', '$type', 'Polygon']
            }, 'waterway-label');

            this.map.addLayer({
                id: 'circle-fill',
                type: 'fill',
                source: 'circle-1',
                paint: {
                    'fill-color': this.options.fillColor,
                    'fill-opacity': this.options.fillOpacity
                },
                filter: ['==', '$type', 'Polygon']
            }, 'waterway-label');

            this.map.addLayer({
                id: 'circle-radius-handles',
                type: 'circle',
                source: 'circle-1',
                paint: {
                    'circle-color': '#ffffff',
                    'circle-radius': 3.75,
                    'circle-stroke-color': this.options.strokeColor,
                    'circle-stroke-opacity': this.options.strokeOpacity,
                    'circle-stroke-width': this.options.strokeWeight
                },
                filter: ['all', ['==', '$type', 'Point'], ['!=', 'type', 'center']]
            });

            this.map.addLayer({
                id: 'circle-center-handle',
                type: 'circle',
                source: 'circle-1',
                paint: {
                    'circle-color': '#ffffff',
                    'circle-radius': 3.75,
                    'circle-stroke-color': this.options.strokeColor,
                    'circle-stroke-opacity': this.options.strokeOpacity,
                    'circle-stroke-width': this.options.strokeWeight
                },
                filter: ['all', ['==', '$type', 'Point'], ['==', 'type', 'center']]
            });

            this.map.on('zoomend', this.onZoomEnd);
            this.map.on('mousemove', _.debounce(this.onMouseMove, 16));
        });
        return this;
    }
}

module.exports = exports = MapboxCircle;
<|endoftext|>


<commit_before>const cheerio = require('cheerio');

module.exports = (() => {
  'use strict';

  const weekdays = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday'];

  function getDates(cheerioHandle) {
    let arr = [];
    cheerioHandle('td.speiseplan-head').each(function() {
      arr.push(removeWhitespace(cheerioHandle(this).text()).split(',')[1]);
    });
    return arr;
  }

  function getMeals(cheerioHandle) {
    const arr = {};
    let dayCounter = 0;
    cheerioHandle('td.speiseplan-tag-container').each(function() {
      const eachDayContent = {};
      let mealCounter = 0;
      eachDayContent.date = getDates(cheerioHandle)[dayCounter] + new Date().getFullYear();
      cheerioHandle('td.speiseplan-tag', this).each(function(i, elem) {
        mealCounter += 1;
        const mealName = 'meal'.concat(mealCounter);
        eachDayContent[mealName] = meal(cheerioHandle, elem);
      });
      arr[weekdays[dayCounter]] = eachDayContent;
      dayCounter += 1;
    });
    return arr;
  }

  function meal(parserContext, element) {
    return {
      description: removeWhitespace(parserContext('.speiseplan-kurzbeschreibung', element).text()),
      price: removeWhitespace(parserContext('.speiseplan-preis', element).text())
    };
  }

  function removeWhitespace(text) {
    return text.trim().replace(/\s\s+/g, '');
  }

  return {
    getDates,
    getMeals
  };
})();
<commit_msg>Removed EUR after each price<commit_after>const cheerio = require('cheerio');

module.exports = (() => {
  'use strict';

  const weekdays = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday'];

  function getDates(cheerioHandle) {
    let arr = [];
    cheerioHandle('td.speiseplan-head').each(function() {
      arr.push(removeWhitespace(cheerioHandle(this).text()).split(',')[1]);
    });
    return arr;
  }

  function getMeals(cheerioHandle) {
    const arr = {};
    let dayCounter = 0;
    cheerioHandle('td.speiseplan-tag-container').each(function() {
      const eachDayContent = {};
      let mealCounter = 0;
      eachDayContent.date = getDates(cheerioHandle)[dayCounter] + new Date().getFullYear();
      cheerioHandle('td.speiseplan-tag', this).each(function(i, elem) {
        mealCounter += 1;
        const mealName = 'meal'.concat(mealCounter);
        eachDayContent[mealName] = meal(cheerioHandle, elem);
      });
      arr[weekdays[dayCounter]] = eachDayContent;
      dayCounter += 1;
    });
    return arr;
  }

  function meal(parserContext, element) {
    return {
      description: removeWhitespace(parserContext('.speiseplan-kurzbeschreibung', element).text()),
      price: removeWhitespace(parserContext('.speiseplan-preis', element).text().slice(0,-4))
    };
  }

  function removeWhitespace(text) {
    return text.trim().replace(/\s\s+/g, '');
  }

  return {
    getDates,
    getMeals
  };
})();
<|endoftext|>


<commit_before>/*
 1. Напишите функцию которая принимает 2 числа
 и возвращает массив содержащий числа между первым числом и вторым числом;
 */
//первое и второе задание слепил в кучу
 function numbersBetween(a, b) {
     var returnArray =[];
 	 if (b == undefined){//если нет 2го параметра делам 2 задание:)
		for (var i = 0; i <= a; i++){
        returnArray.push(fizzBuzz(i)); // вот тут вызывается функция для 2го задания
	 }
	 }
	 else {
	     a++; //это шоб не брало первое значание
		for (var i = a; i < b; i++){
        returnArray.push(i);
     }
	 }
     return returnArray;
 }

function fizzBuzz(num) {// функция для второго задания
  /* Ваш код здесь */
  return (num === 0 ? '0 деленный на число будет 0' :
          (((num % 3 == 0) && (num % 5 == 0)) ? 'FizzBuzz' :
            ((num % 5 == 0) ? 'Buzz' :
              (((num % 3 == 0) ? 'Fizz' :
                num)))));
	}
 console.log(numbersBetween(1, 5)); // 2,3,4
 console.log(numbersBetween(3, 6)); // 4,5
 console.log(numbersBetween(12, 15)); // 13,14
 console.log(numbersBetween(10, 15)); // 11, 12, 13, 14
 console.log(numbersBetween(100)); //Для второго задания.

/*
 2. Перепешите задачу FizzBuzz, но с использованием цикла.
 Расчет чисел должен идти до 100
 */

/*
 3. Напишите функцию которая принимает 1 аргумент - массив
 И возвращает новый массив содержащий типы значений переменных
 */

let arr = [1, null, undefined, 'str', {}, [], function() {}];

function arrayTypes(arrayT){
    newArray =[];
for (var i =0; i < arrayT.length; i++ ){
newArray[i] = typeof(arrayT[i]);
}
return(newArray);
}
console.log(arrayTypes(arr));
/*
 @@SUPER@@. Вам дан массив array, содержащий внутри объекты.
 Напишите функцию которая внутри цикла проходится по каждому элементу массива
 И проверяет какой тип данных содержит свойство age, если тип данных NaN,
 тогда добавляет данному объекту свойство unknownAge: true

 На основании нового массива, создайте новую функцию, которая вернет новый массив
  содержащий все объекты содержащие свойство unknownAge:true
 */

let array = Array.from({ length: 35 }).map(
  (value, index) => (index % 2 ? { age: index + 2 } : { age: NaN })
);

//console.log(array); // [ {age:NaN}, {age:3}, {age:NaN}, {age:5}, {age:NaN}, {age:7} ....]
//console.log(array.length); // 35

function solution(arr) {
    for(let i = 0; i < arr.length; i++){
    if (isNaN(arr[i].age)){
        arr[i].unknownAge = true;
    }
    }
    return arr;
}

function unknownAge(arr){
    let localArr = [];
    for(let i = 0; i < arr.length; i++){
        if (arr[i].unknownAge){
            localArr.push(arr[i]);
        }
    }
    return(localArr);
}

console.log(solution(array));
console.log(unknownAge(solution(array)));

<commit_msg>Homework4<commit_after>/*
 1. Напишите функцию которая принимает 2 числа
 и возвращает массив содержащий числа между первым числом и вторым числом;
 */
//первое и второе задание слепил в кучу
 function numbersBetween(a, b) {
     var returnArray =[];
 	 if (b == undefined){//если нет 2го параметра делам 2 задание:)
		for (var i = 0; i <= a; i++){
        returnArray.push(fizzBuzz(i)); // вот тут вызывается функция для 2го задания
	    }
	 }
	 else {
	     a++; //это шоб не брало первое значание
		for (var i = a; i < b; i++){
        returnArray.push(i);
        }
	 }
     return returnArray;
 }

function fizzBuzz(num) {// функция для второго задания
  /* Ваш код здесь */
  return (num === 0 ? '0 деленный на число будет 0' :
          (((num % 3 == 0) && (num % 5 == 0)) ? 'FizzBuzz' :
            ((num % 5 == 0) ? 'Buzz' :
              (((num % 3 == 0) ? 'Fizz' :
                num)))));
	}
 console.log(numbersBetween(1, 5)); // 2,3,4
 console.log(numbersBetween(3, 6)); // 4,5
 console.log(numbersBetween(12, 15)); // 13,14
 console.log(numbersBetween(10, 15)); // 11, 12, 13, 14
 console.log(numbersBetween(100)); //Для второго задания.

/*
 2. Перепешите задачу FizzBuzz, но с использованием цикла.
 Расчет чисел должен идти до 100
 */

/*
 3. Напишите функцию которая принимает 1 аргумент - массив
 И возвращает новый массив содержащий типы значений переменных
 */

let arr = [1, null, undefined, 'str', {}, [], function() {}];

function arrayTypes(arrayT){
    newArray =[];
    for (var i =0; i < arrayT.length; i++ ){
        newArray[i] = typeof(arrayT[i]);
    }
    return(newArray);
}
console.log(arrayTypes(arr));
/*
 @@SUPER@@. Вам дан массив array, содержащий внутри объекты.
 Напишите функцию которая внутри цикла проходится по каждому элементу массива
 И проверяет какой тип данных содержит свойство age, если тип данных NaN,
 тогда добавляет данному объекту свойство unknownAge: true

 На основании нового массива, создайте новую функцию, которая вернет новый массив
  содержащий все объекты содержащие свойство unknownAge:true
 */

let array = Array.from({ length: 35 }).map(
  (value, index) => (index % 2 ? { age: index + 2 } : { age: NaN })
);

//console.log(array); // [ {age:NaN}, {age:3}, {age:NaN}, {age:5}, {age:NaN}, {age:7} ....]
//console.log(array.length); // 35

function solution(arr) {
    for(let i = 0; i < arr.length; i++){
        if (isNaN(arr[i].age)){
            arr[i].unknownAge = true;
            }
    }
    return arr;
}

function unknownAge(arr){
    let localArr = [];
    for(let i = 0; i < arr.length; i++){
        if (arr[i].unknownAge){
            localArr.push(arr[i]);
        }
    }
    return(localArr);
}

console.log(solution(array));
console.log(unknownAge(solution(array)));

<|endoftext|>


<commit_before>/**
 * Requires
 *
 */
var prefs = require("sdk/preferences/service");
var ui = require("sdk/ui");
var self = require("sdk/self");

/**
 * Current status
 *
 */
var strictModeDisabled = true;

/**
 * Whitelisted preferences, as a POC I'm using:
 * 1) no 128 bit (except for ECDHE)
 * 2) no RC4
 * 3) no ECDSA
 *
 * This list has been updated for FF 35.0
 *
 */
var whitelist = [
  "security.ssl.require_safe_negotiation",
  "security.ssl.treat_unsafe_negotiation_as_broken",
//  "security.ssl3.ecdhe_ecdsa_aes_128_sha",
  "security.ssl3.rsa_aes_256_sha",
//  "security.ssl3.dhe_rsa_aes_128_sha",
  "security.ssl3.ecdhe_rsa_aes_256_sha",
//  "security.ssl3.rsa_aes_128_sha",
//  "security.ssl3.ecdhe_rsa_rc4_128_sha",
//  "security.ssl3.ecdhe_ecdsa_aes_256_sha",
  "security.ssl3.rsa_des_ede3_sha",
//  "security.ssl3.rsa_rc4_128_sha",
  "security.ssl3.dhe_rsa_aes_256_sha",
//  "security.ssl3.dhe_dss_aes_128_sha",
//  "security.ssl3.ecdhe_rsa_aes_128_sha",
//  "security.ssl3.rsa_rc4_128_md5",
//  "security.ssl3.ecdhe_ecdsa_rc4_128_sha",
  "security.ssl3.ecdhe_rsa_aes_128_gcm_sha256",
//  "security.ssl3.ecdhe_ecdsa_aes_128_gcm_sha256",
];

/**
 * These preferences have been defaulted to "false" by Mozilla.
 * Do not modify them.
 *
 * This list has been updated for FF 35.0
 *
 */
var ignorelist = [
  "security.ssl3.dhe_dss_aes_256_sha",
  "security.ssl3.dhe_rsa_camellia_128_sha",
  "security.ssl3.dhe_rsa_camellia_256_sha",
  "security.ssl3.dhe_rsa_des_ede3_sha",
  "security.ssl3.ecdhe_rsa_des_ede3_sha",
  "security.ssl3.rsa_camellia_128_sha",
  "security.ssl3.rsa_camellia_256_sha",
];

/**
 * Toggle all current security.ssl3 preferences.
 *
 */
function toggleAllPreferences() {
  // Get security.ssl3 keys
  var keys = prefs.keys("security.ssl3.");

  // Flip current status
  strictModeDisabled = !strictModeDisabled;

  // Flip not whitelisted entries
  keys.forEach(flipSinglePreference);
}

/**
 * Toggle a single security.ssl3 preference.
 *
 * Preferences with a default value of "false" will not be modified.
 * In default mode, it will reset the preference to its default value.
 * In strict mode, it will flip whitelisted entries to true and everything else
 * to false.
 *
 * @param prefName {String|Object}
 *        the preference to flip
 */
function flipSinglePreference(prefName) {
  if(ignorelist.indexOf(prefName) === -1) {
    // Preference can be modified
    if(strictModeDisabled) {
      // Default mode
      prefs.reset(prefName);
    } else {
      // Strict mode
      prefs.set(prefName, !(whitelist.indexOf(prefName) === -1));
    }
  }
}

/**
 * Return a path to the current button icon.
 *
 */
function getIcon() {
  if(strictModeDisabled) {
    return self.data.url("default-16.png");
  } else {
    return self.data.url("strict-16.png");
  }
}

/**
 * Start in strict mode.
 *
 */
toggleAllPreferences();

/**
 * Display button.
 *
 */
var button = ui.ActionButton({
  id: "strict-ssl3-config",
  label: "Toggle strict security.ssl3 configuration",
  icon: getIcon(),
  onClick: function() {
    toggleAllPreferences();
    this.icon = getIcon();
  }
});
<commit_msg>Also retrieve safe_negotiation preferences<commit_after>/**
 * Requires
 *
 */
var prefs = require("sdk/preferences/service");
var ui = require("sdk/ui");
var self = require("sdk/self");

/**
 * Current status
 *
 */
var strictModeDisabled = true;

/**
 * Whitelisted preferences, as a POC I'm using:
 * 1) no 128 bit (except for ECDHE)
 * 2) no RC4
 * 3) no ECDSA
 *
 * This list has been updated for FF 35.0
 *
 */
var whitelist = [
  "security.ssl.require_safe_negotiation",
  "security.ssl.treat_unsafe_negotiation_as_broken",
//  "security.ssl3.ecdhe_ecdsa_aes_128_sha",
  "security.ssl3.rsa_aes_256_sha",
//  "security.ssl3.dhe_rsa_aes_128_sha",
  "security.ssl3.ecdhe_rsa_aes_256_sha",
//  "security.ssl3.rsa_aes_128_sha",
//  "security.ssl3.ecdhe_rsa_rc4_128_sha",
//  "security.ssl3.ecdhe_ecdsa_aes_256_sha",
  "security.ssl3.rsa_des_ede3_sha",
//  "security.ssl3.rsa_rc4_128_sha",
  "security.ssl3.dhe_rsa_aes_256_sha",
//  "security.ssl3.dhe_dss_aes_128_sha",
//  "security.ssl3.ecdhe_rsa_aes_128_sha",
//  "security.ssl3.rsa_rc4_128_md5",
//  "security.ssl3.ecdhe_ecdsa_rc4_128_sha",
  "security.ssl3.ecdhe_rsa_aes_128_gcm_sha256",
//  "security.ssl3.ecdhe_ecdsa_aes_128_gcm_sha256",
];

/**
 * These preferences have been defaulted to "false" by Mozilla.
 * Do not modify them.
 *
 * This list has been updated for FF 35.0
 *
 */
var ignorelist = [
  "security.ssl3.dhe_dss_aes_256_sha",
  "security.ssl3.dhe_rsa_camellia_128_sha",
  "security.ssl3.dhe_rsa_camellia_256_sha",
  "security.ssl3.dhe_rsa_des_ede3_sha",
  "security.ssl3.ecdhe_rsa_des_ede3_sha",
  "security.ssl3.rsa_camellia_128_sha",
  "security.ssl3.rsa_camellia_256_sha",
];

/**
 * Toggle all current security.ssl3 preferences.
 *
 */
function toggleAllPreferences() {
  // Get security.ssl3 keys
  var keys = prefs.keys("security.ssl3.");
  // Also concatenate secure renegotiation preferences
  keys = keys.concat(prefs.keys("security.ssl.require_safe_negotiation"));
  keys = keys.concat(prefs.keys("security.ssl.treat_unsafe_negotiation_as_broken"));

  // Flip current status
  strictModeDisabled = !strictModeDisabled;

  // Flip not whitelisted entries
  keys.forEach(flipSinglePreference);
}

/**
 * Toggle a single security.ssl3 preference.
 *
 * Preferences with a default value of "false" will not be modified.
 * In default mode, it will reset the preference to its default value.
 * In strict mode, it will flip whitelisted entries to true and everything else
 * to false.
 *
 * @param prefName {String|Object}
 *        the preference to flip
 */
function flipSinglePreference(prefName) {
  if(ignorelist.indexOf(prefName) === -1) {
    // Preference can be modified
    if(strictModeDisabled) {
      // Default mode
      prefs.reset(prefName);
    } else {
      // Strict mode
      prefs.set(prefName, !(whitelist.indexOf(prefName) === -1));
    }
  }
}

/**
 * Return a path to the current button icon.
 *
 */
function getIcon() {
  if(strictModeDisabled) {
    return self.data.url("default-16.png");
  } else {
    return self.data.url("strict-16.png");
  }
}

/**
 * Start in strict mode.
 *
 */
toggleAllPreferences();

/**
 * Display button.
 *
 */
var button = ui.ActionButton({
  id: "strict-ssl3-config",
  label: "Toggle strict security.ssl3 configuration",
  icon: getIcon(),
  onClick: function() {
    toggleAllPreferences();
    this.icon = getIcon();
  }
});
<|endoftext|>


<commit_before>/* jshint node: true  */
'use strict';

var options = require('./options');

var DefaultDefaults = {};

function ApigeeTool(defaults) {
  this.defaults = (defaults ? defaults : DefaultDefaults);
}
module.exports = ApigeeTool;

ApigeeTool.defaults = function(newDefaults) {
  return new ApigeeTool(newDefaults);
};

ApigeeTool.listDeployments = function(opts, cb) {
  var cmd = require('./commands/listdeployments');
  runCommand(cmd, opts, cb);
};

ApigeeTool.deployNodeApp = function(opts, cb) {
  var cmd = require('./commands/deploynodeapp');
  runCommand(cmd, opts, cb);
};

ApigeeTool.deployProxy = function(opts, cb) {
  var cmd = require('./commands/deployproxy');
  runCommand(cmd, opts, cb);
};

ApigeeTool.undeploy = function(opts, cb) {
  var cmd = require('./commands/undeploy');
  runCommand(cmd, opts, cb);
};

function runCommand(cmd, opts, cb) {
  options.validate(cmd.descriptor, opts, function(err) {
    if (err) {
      cb(err);
      return;
    }
    cmd.run(opts, cb);
  });
}
<commit_msg>parameters were reversed in call<commit_after>/* jshint node: true  */
'use strict';

var options = require('./options');

var DefaultDefaults = {};

function ApigeeTool(defaults) {
  this.defaults = (defaults ? defaults : DefaultDefaults);
}
module.exports = ApigeeTool;

ApigeeTool.defaults = function(newDefaults) {
  return new ApigeeTool(newDefaults);
};

ApigeeTool.listDeployments = function(opts, cb) {
  var cmd = require('./commands/listdeployments');
  runCommand(cmd, opts, cb);
};

ApigeeTool.deployNodeApp = function(opts, cb) {
  var cmd = require('./commands/deploynodeapp');
  runCommand(cmd, opts, cb);
};

ApigeeTool.deployProxy = function(opts, cb) {
  var cmd = require('./commands/deployproxy');
  runCommand(cmd, opts, cb);
};

ApigeeTool.undeploy = function(opts, cb) {
  var cmd = require('./commands/undeploy');
  runCommand(cmd, opts, cb);
};

function runCommand(cmd, opts, cb) {
  options.validate(opts, cmd.descriptor, function(err) {
    if (err) {
      cb(err);
      return;
    }
    cmd.run(opts, cb);
  });
}
<|endoftext|>


<commit_before>const jsdom = require('jsdom');
const serializeDocument = jsdom.serializeDocument;
const mathjax = require('mathjax-node');
const typeset = mathjax.typeset;
const tex = require('./tex.js').tex2jax;
const ascii = require('./ascii.js').ascii2jax;
const mathml = require('./mathml.js').mathml2jax;
// HACK isolate confingurations cf #22
const texconfig = JSON.stringify(tex.config);
const asciiconfig = JSON.stringify(ascii.config);

exports.mjpage = function(htmlstring, configOptions, typesetOptions, callback) {

    // `config` extends options for mathjax-node's config method, cf https://github.com/mathjax/MathJax-node/wiki/Configuration-options#configoptions

    const config = {
        // mathjax-node-page specific
        format: ["MathML", "TeX", "AsciiMath"], // determines type of pre-processors to run
        tex: {}, // configuration options for tex pre-processor
        ascii: {}, // configuration options for ascii pre-processor
        singleDollars: false, // allow single-dollar delimiter for inline TeX
        fragment: false,
        jsdom: {
            FetchExternalResources: [],
            ProcessExternalResources: false,
            // NOTE virtualConsole: not the jsdom way but for configurability (cf. below)
            virtualConsole: true
        },
        //
        // standard mathjax-node options
        //
        displayMessages: false, // determines whether Message.Set() calls are logged
        displayErrors: true, // determines whether error messages are shown on the console
        undefinedCharError: false, // determines whether unknown characters are saved in the error array
        extensions: '', // a convenience option to add MathJax extensions
        fontURL: 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js/fonts/HTML-CSS', // for webfont urls in the CSS for HTML output
        MathJax: {} // options MathJax configuration, see https://docs.mathjax.org
    }
    const mjstate = {};
    // defaults for mathjax-node's typeset method
    const typesetConfig = {
        ex: 6, // ex-size in pixels
        width: 100, // width of container (in ex) for linebreaking and tags
        useFontCache: true, // use <defs> and <use> in svg output?
        useGlobalCache: false, // use common <defs> for all equations?
        state: mjstate, // track global state
        linebreaks: false, // do linebreaking?
        equationNumbers: "none", // or "AMS" or "all"
        math: "", // the math to typeset
        html: false, // generate HTML output?
        css: false, // generate CSS for HTML output?
        mml: false, // generate mml output?
        svg: false, // generate svg output?
        speakText: true, // add spoken annotations to svg output?
        speakRuleset: "mathspeak", // set speech ruleset (default (chromevox rules), mathspeak)
        speakStyle: "default", // set speech style (mathspeak:  default, brief, sbrief)
        timeout: 10 * 1000, // 10 second timeout before restarting MathJax
    }

    //merge configurations

    const mergeConfig = function(conf, confDefaults) {
        for (index in conf) {
            confDefaults[index] = conf[index];
        }
    };

    mergeConfig(configOptions, config);
    mergeConfig(typesetOptions, typesetConfig);

    // Set jsdom console (cf. defaults for config.jsdom)
    if (config.jsdom.virtualConsole) {
        config.jsdom.virtualConsole = jsdom.createVirtualConsole().sendTo(console);
    }

    // set up DOM basics
    const doc = jsdom.jsdom(htmlstring, config.jsdom);
    const window = doc.defaultView;
    const document = window.document;

    // configure mathjax-node
    mathjax.config(config);

    // configure and pre-process
    if (config.format.indexOf('MathML') > -1) {
        window.mathml = mathml;
        window.mathml.config.doc = document;
        window.mathml.PreProcess();
    }
    // HACK clone configuration cf #22
    tex.config = JSON.parse(texconfig);
    if (config.format.indexOf('TeX') > -1) {
        if (config.MathJax.tex2jax) {
            mergeConfig(config.MathJax.tex2jax, tex.config);
        }
        window.tex = tex;
        window.tex.config.doc = document;
        if (config.singleDollars) {
            window.tex.config.inlineMath.push(['$', '$']);
            window.tex.config.processEscapes = true;
        }
        window.tex.PreProcess();
    }
    // HACK clone configuration cf #22
    ascii.config = JSON.parse(asciiconfig);
    if (config.format.indexOf('AsciiMath') > -1) {
        if (config.MathJax.ascii2jax) {
            mergeConfig(config.MathJax.ascii2jax, ascii.config);
        }
        window.ascii = ascii;
        window.ascii.config.doc = document;
        window.ascii.PreProcess();
    }

    // convert with mathjax-node
    const scripts = document.querySelectorAll('script[type^="math/"]');
    const process = function(index) {
        const script = scripts[index];
        if (script) {
            const format = script.getAttribute('type').slice(5);
            const conf = typesetConfig;
            conf.format = format;
            if (format === 'MathML-block') conf.format = 'MathML';
            conf.math = script.text;
            const wrapper = document.createElement('span');
            if (format === 'TeX' || format === 'MathML-block') wrapper.className = 'mjpage mjpage__block';
            else wrapper.className = 'mjpage';
            script.parentNode.replaceChild(wrapper, script);
            typeset(conf, function(result) {
                if (result.errors) {
                    console.log('Error source: ' + script.outerHTML);
                    // throw result.errors;
                }
                if (result.mml) {
                    wrapper.innerHTML = result.mml;
                }
                if (result.html) {
                    wrapper.innerHTML = result.html;
                }
                if (result.svg) {
                    wrapper.innerHTML = result.svg;
                }
                // recursion
                process(index + 1);
            });
        } else {
            // a dummy call to wait for mathjax-node to finish
            const conf = typesetConfig;
            conf.format = 'TeX';
            conf.math = '';
            typeset(conf, function(result) {
                if (index > 0) {
                    // NOTE cf https://github.com/mathjax/MathJax-node/issues/283
                    if (typesetConfig.svg) result.css = `
                            .mjpage .MJX-monospace {
                            font-family: monospace
                            }

                            .mjpage .MJX-sans-serif {
                            font-family: sans-serif
                            }

                            .mjpage {
                            display: inline;
                            font-style: normal;
                            font-weight: normal;
                            line-height: normal;
                            font-size: 100%;
                            font-size-adjust: none;
                            text-indent: 0;
                            text-align: left;
                            text-transform: none;
                            letter-spacing: normal;
                            word-spacing: normal;
                            word-wrap: normal;
                            white-space: nowrap;
                            float: none;
                            direction: ltr;
                            max-width: none;
                            max-height: none;
                            min-width: 0;
                            min-height: 0;
                            border: 0;
                            padding: 0;
                            margin: 0
                            }

                            .mjpage * {
                            transition: none;
                            -webkit-transition: none;
                            -moz-transition: none;
                            -ms-transition: none;
                            -o-transition: none
                            }

                            .mjx-svg-href {
                            fill: blue;
                            stroke: blue
                            }

                            .MathJax_SVG_LineBox {
                            display: table!important
                            }

                            .MathJax_SVG_LineBox span {
                            display: table-cell!important;
                            width: 10000em!important;
                            min-width: 0;
                            max-width: none;
                            padding: 0;
                            border: 0;
                            margin: 0
                            }

                            .mjpage__block {
                            text-align: center;
                            margin: 1em 0em;
                            position: relative;
                            display: block!important;
                            text-indent: 0;
                            max-width: none;
                            max-height: none;
                            min-width: 0;
                            min-height: 0;
                            width: 100%
                            }`;
                    if (result.css) {
                        // TODO make optional
                        var styles = document.createElement('style');
                        styles.setAttribute('type', 'text/css');
                        styles.appendChild(document.createTextNode(result.css));
                        document.head.appendChild(styles);
                    }
                    if (typesetConfig.useGlobalCache) {
                        var globalSVG = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
                        globalSVG.style.display = 'none';
                        // TODO `globalSVG.appendChild(document.importNode(state.defs,true))` throws error
                        // `globablSVG.appendChild(mjstate.defs)`` throws WrongDocumentError so above seems correct
                        globalSVG.innerHTML = mjstate.defs.outerHTML;
                        document.body.appendChild(globalSVG);
                    }
                }
                let output = '';
                if (config.fragment) output = document.body.innerHTML;
                else output = serializeDocument(document);
                window.close();
                callback(output);
            })
        }
    }

    process(0);
}
<commit_msg>Fix handling of format strings in custom script types<commit_after>const jsdom = require('jsdom');
const serializeDocument = jsdom.serializeDocument;
const mathjax = require('mathjax-node');
const typeset = mathjax.typeset;
const tex = require('./tex.js').tex2jax;
const ascii = require('./ascii.js').ascii2jax;
const mathml = require('./mathml.js').mathml2jax;
// HACK isolate confingurations cf #22
const texconfig = JSON.stringify(tex.config);
const asciiconfig = JSON.stringify(ascii.config);

exports.mjpage = function(htmlstring, configOptions, typesetOptions, callback) {

    // `config` extends options for mathjax-node's config method, cf https://github.com/mathjax/MathJax-node/wiki/Configuration-options#configoptions

    const config = {
        // mathjax-node-page specific
        format: ["MathML", "TeX", "AsciiMath"], // determines type of pre-processors to run
        tex: {}, // configuration options for tex pre-processor
        ascii: {}, // configuration options for ascii pre-processor
        singleDollars: false, // allow single-dollar delimiter for inline TeX
        fragment: false,
        jsdom: {
            FetchExternalResources: [],
            ProcessExternalResources: false,
            // NOTE virtualConsole: not the jsdom way but for configurability (cf. below)
            virtualConsole: true
        },
        //
        // standard mathjax-node options
        //
        displayMessages: false, // determines whether Message.Set() calls are logged
        displayErrors: true, // determines whether error messages are shown on the console
        undefinedCharError: false, // determines whether unknown characters are saved in the error array
        extensions: '', // a convenience option to add MathJax extensions
        fontURL: 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js/fonts/HTML-CSS', // for webfont urls in the CSS for HTML output
        MathJax: {} // options MathJax configuration, see https://docs.mathjax.org
    }
    const mjstate = {};
    // defaults for mathjax-node's typeset method
    const typesetConfig = {
        ex: 6, // ex-size in pixels
        width: 100, // width of container (in ex) for linebreaking and tags
        useFontCache: true, // use <defs> and <use> in svg output?
        useGlobalCache: false, // use common <defs> for all equations?
        state: mjstate, // track global state
        linebreaks: false, // do linebreaking?
        equationNumbers: "none", // or "AMS" or "all"
        math: "", // the math to typeset
        html: false, // generate HTML output?
        css: false, // generate CSS for HTML output?
        mml: false, // generate mml output?
        svg: false, // generate svg output?
        speakText: true, // add spoken annotations to svg output?
        speakRuleset: "mathspeak", // set speech ruleset (default (chromevox rules), mathspeak)
        speakStyle: "default", // set speech style (mathspeak:  default, brief, sbrief)
        timeout: 10 * 1000, // 10 second timeout before restarting MathJax
    }

    //merge configurations

    const mergeConfig = function(conf, confDefaults) {
        for (index in conf) {
            confDefaults[index] = conf[index];
        }
    };

    mergeConfig(configOptions, config);
    mergeConfig(typesetOptions, typesetConfig);

    // Set jsdom console (cf. defaults for config.jsdom)
    if (config.jsdom.virtualConsole) {
        config.jsdom.virtualConsole = jsdom.createVirtualConsole().sendTo(console);
    }

    // set up DOM basics
    const doc = jsdom.jsdom(htmlstring, config.jsdom);
    const window = doc.defaultView;
    const document = window.document;

    // configure mathjax-node
    mathjax.config(config);

    // configure and pre-process
    if (config.format.indexOf('MathML') > -1) {
        window.mathml = mathml;
        window.mathml.config.doc = document;
        window.mathml.PreProcess();
    }
    // HACK clone configuration cf #22
    tex.config = JSON.parse(texconfig);
    if (config.format.indexOf('TeX') > -1) {
        if (config.MathJax.tex2jax) {
            mergeConfig(config.MathJax.tex2jax, tex.config);
        }
        window.tex = tex;
        window.tex.config.doc = document;
        if (config.singleDollars) {
            window.tex.config.inlineMath.push(['$', '$']);
            window.tex.config.processEscapes = true;
        }
        window.tex.PreProcess();
    }
    // HACK clone configuration cf #22
    ascii.config = JSON.parse(asciiconfig);
    if (config.format.indexOf('AsciiMath') > -1) {
        if (config.MathJax.ascii2jax) {
            mergeConfig(config.MathJax.ascii2jax, ascii.config);
        }
        window.ascii = ascii;
        window.ascii.config.doc = document;
        window.ascii.PreProcess();
    }

    const normalizeFormat = function(str) {
        const format = str.toLowerCase();
        if (format === "tex") {
            return "inline-TeX";
        } else if (format === "tex; mode=display") {
            return "TeX";
        } else if (format == "mathml") {
            return "MathML";
        } else if (format == "asciimath") {
            return "AsciiMath";
        }
    }
    // convert with mathjax-node
    const scripts = document.querySelectorAll('script[type^="math/"]');
    const process = function(index) {
        const script = scripts[index];
        if (script) {
            const format = normalizeFormat(script.getAttribute('type').slice(5));
            const conf = typesetConfig;
            conf.format = format;
            if (format === 'MathML-block') conf.format = 'MathML';
            conf.math = script.text;
            const wrapper = document.createElement('span');
            if (format === 'TeX' || format === 'MathML-block') wrapper.className = 'mjpage mjpage__block';
            else wrapper.className = 'mjpage';
            script.parentNode.replaceChild(wrapper, script);
            typeset(conf, function(result) {
                if (result.errors) {
                    console.log('Error source: ' + script.outerHTML);
                    // throw result.errors;
                }
                if (result.mml) {
                    wrapper.innerHTML = result.mml;
                }
                if (result.html) {
                    wrapper.innerHTML = result.html;
                }
                if (result.svg) {
                    wrapper.innerHTML = result.svg;
                }
                // recursion
                process(index + 1);
            });
        } else {
            // a dummy call to wait for mathjax-node to finish
            const conf = typesetConfig;
            conf.format = 'TeX';
            conf.math = '';
            typeset(conf, function(result) {
                if (index > 0) {
                    // NOTE cf https://github.com/mathjax/MathJax-node/issues/283
                    if (typesetConfig.svg) result.css = `
                            .mjpage .MJX-monospace {
                            font-family: monospace
                            }

                            .mjpage .MJX-sans-serif {
                            font-family: sans-serif
                            }

                            .mjpage {
                            display: inline;
                            font-style: normal;
                            font-weight: normal;
                            line-height: normal;
                            font-size: 100%;
                            font-size-adjust: none;
                            text-indent: 0;
                            text-align: left;
                            text-transform: none;
                            letter-spacing: normal;
                            word-spacing: normal;
                            word-wrap: normal;
                            white-space: nowrap;
                            float: none;
                            direction: ltr;
                            max-width: none;
                            max-height: none;
                            min-width: 0;
                            min-height: 0;
                            border: 0;
                            padding: 0;
                            margin: 0
                            }

                            .mjpage * {
                            transition: none;
                            -webkit-transition: none;
                            -moz-transition: none;
                            -ms-transition: none;
                            -o-transition: none
                            }

                            .mjx-svg-href {
                            fill: blue;
                            stroke: blue
                            }

                            .MathJax_SVG_LineBox {
                            display: table!important
                            }

                            .MathJax_SVG_LineBox span {
                            display: table-cell!important;
                            width: 10000em!important;
                            min-width: 0;
                            max-width: none;
                            padding: 0;
                            border: 0;
                            margin: 0
                            }

                            .mjpage__block {
                            text-align: center;
                            margin: 1em 0em;
                            position: relative;
                            display: block!important;
                            text-indent: 0;
                            max-width: none;
                            max-height: none;
                            min-width: 0;
                            min-height: 0;
                            width: 100%
                            }`;
                    if (result.css) {
                        // TODO make optional
                        var styles = document.createElement('style');
                        styles.setAttribute('type', 'text/css');
                        styles.appendChild(document.createTextNode(result.css));
                        document.head.appendChild(styles);
                    }
                    if (typesetConfig.useGlobalCache) {
                        var globalSVG = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
                        globalSVG.style.display = 'none';
                        // TODO `globalSVG.appendChild(document.importNode(state.defs,true))` throws error
                        // `globablSVG.appendChild(mjstate.defs)`` throws WrongDocumentError so above seems correct
                        globalSVG.innerHTML = mjstate.defs.outerHTML;
                        document.body.appendChild(globalSVG);
                    }
                }
                let output = '';
                if (config.fragment) output = document.body.innerHTML;
                else output = serializeDocument(document);
                window.close();
                callback(output);
            })
        }
    }

    process(0);
}
<|endoftext|>


<commit_before>// Generated by CoffeeScript 1.9.3
(function() {
  var i, len, method_count, module, name, njs_util, ref, route, routes, rpr, value;

  njs_util = require('util');

  rpr = njs_util.inspect;

  this.LODASH = require('lodash');

  this.TSORT = require('./TSORT');

  this.BLOOM = require('./BLOOM');

  this.XJSON = require('./XJSON');

  this.columnify = require('columnify');

  this.INTERSKIPLIST = require('./INTERSKIPLIST');

  method_count = 0;

  routes = ['./TRM', './BITSNPIECES', './TYPES', './SHIM'];

  for (i = 0, len = routes.length; i < len; i++) {
    route = routes[i];
    ref = module = require(route);
    for (name in ref) {
      value = ref[name];
      if (this[name] != null) {
        throw new Error("duplicate name " + (rpr(name)));
      }
      method_count += +1;
      if ((Object.prototype.toString.call(value)) === '[object Function]') {
        value = value.bind(module);
      }
      this[name] = value;
    }
  }

}).call(this);
<commit_msg>autocommit<commit_after>// Generated by CoffeeScript 1.9.3
(function() {
  var i, len, method_count, module, name, njs_util, ref, route, routes, rpr, value;

  njs_util = require('util');

  rpr = njs_util.inspect;

  this.LODASH = require('lodash');

  this.TSORT = require('./TSORT');

  this.BLOOM = require('./BLOOM');

  this.XJSON = require('./XJSON');

  this.columnify = require('columnify');

  this.INTERSKIPLIST = require('./INTERSKIPLIST');

  method_count = 0;

  routes = ['./TRM', './BITSNPIECES', './TYPES'];

  for (i = 0, len = routes.length; i < len; i++) {
    route = routes[i];
    ref = module = require(route);
    for (name in ref) {
      value = ref[name];
      if (this[name] != null) {
        throw new Error("duplicate name " + (rpr(name)));
      }
      method_count += +1;
      if ((Object.prototype.toString.call(value)) === '[object Function]') {
        value = value.bind(module);
      }
      this[name] = value;
    }
  }

}).call(this);
<|endoftext|>


<commit_before>var request = require('request');

var randomId = function (seed) {
  if (seed) {
    return Math.floor(Math.random() * seed + 1000000000);
  }

  return Math.floor(Math.random() * 8999999999 + 1000000000);
};

var cookieParams = function () {
  var utma1 = randomId();
  var utma2 = randomId();
  var today = Date.now();

  var str1 = '1.' + utma1 + '00145214523.' + utma2 + '.' + today + '.' + today + '.15';

  return '__utma=' + str1 + ';+__utmz=1.' + today + '.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none);';
};

var eventData = function (category, action, label, value) {
  var data = '5(' + category + '*' + action;
  if (label) {
    data += '*' + label + ')';
  } else {
    data += ')';
  }
  if (value) {
    data += '(' + value + ')';
  }
  return data;
};

var GOOGLE_HOST = 'www.google-analytics.com';
var BEACON_PATH = '/__utm.gif';
var USER_AGENT = 'Nodealytics Agent';

var options = {
  utmwv : "4.4sh", // Google Analytics version
  utmcs : "UTF-8", // charset
  utmul : "en-us", // language

  utmn : randomId(),
  utmhid : randomId(),
  user_agent : USER_AGENT,

  custom_vars : [] // TODO: Implement custom variables
};

exports.initialize = function(accountId, domain, callback) {
  options.utmac = accountId;
  if (!/UA-[0-9-]+[0-9]+/i.test(accountId)) {
    return callback(new Error('Account ID is invalid'));
  }

  if (domain.length < 1) {
    return callback(new Error('Domain is invalid'));
  }

  options.utmhn = domain;

  if (callback) {
    return callback();
  }
};

exports.trackPage = function (title, page, params, callback) {
  if (typeof params === 'function') {
    callback = params;
    params = {};
  }

  if (typeof options.utmac === 'undefined') {
    return new Error('Google Analytics Account ID is undefined');
  }
  if (typeof options.utmhn === 'undefined') {
    return new Error('Google Analytics Domain is undefined');
  }

  var pageViewParams = {
    utmwv : options.utmwv,
    utmn : options.utmn,
    utmhn : options.utmhn,
    utmcs : options.utmcs,
    utmul : options.utmul,
    utmdt : title,
    utmhid : randomId(),
    utmp : page,
    utmac : options.utmac,
    utmcc : cookieParams()
  };

  Object.keys(params).forEach(function (key, i) {
    pageViewParams[key] = params[key];
  });

  return this.runQuery(pageViewParams, callback);
};

exports.trackEvent = function (category, action, label, value, utmni, utmhid, callback) {
  if (typeof label === 'function') {
    callback = label;
    label = undefined;
  } else if (typeof value === 'function') {
    callback = value;
    value = undefined;
  } else if (typeof utmni === 'function') {
    callback = utmni;
    utmni = undefined;
  } else if (typeof utmhid === 'function') {
    callback = utmhid;
    utmhid = undefined;
  }

  if (typeof options.utmac === 'undefined') {
    return callback(new Error('Google Analytics Account ID is undefined'));
  }
  if (typeof options.utmhn === 'undefined') {
    return callback(new Error('Google Analytics Domain is undefined'));
  }

  if (typeof utmni !== 'undefined' && typeof utmni !== 'boolean') {
    return callback(new Error('utmni must be a boolean'));
  }

  var eventParams = {
    utmwv : options.utmwv,
    utmn : options.utmn,
    utmhn : options.utmhn,
    utmt : 'event',
    utme : eventData(category, action, label, value), // #{custom_var_data}, TODO: work on custom data
    utmcs : options.utmcs,
    utmul : options.utmul,
    utmhid : (utmhid || randomId()),
    utmac : options.utmac,
    utmcc : options.utmcc || cookieParams()
  };

  if (utmni) {
    eventParams.utmni = 1; // 1 for non interactive event, excluded from bounce calcs
  }

  return this.runQuery(eventParams, callback);
};

exports.mapParams = function(params) {
  var result = '';

  Object.keys(params).forEach(function (key, i) {
    result += key + '=' + params[key] + '&';
  });
  result = result.slice(0, -1);

  return result;
};

exports.runQuery = function (params, callback) {
  var query = 'http://' + GOOGLE_HOST + BEACON_PATH + '?';

  query += exports.mapParams(params);

  request.get(query, function (error, response, body) {
    if (!error && response.statusCode == 200) {
      // console.log(body);
    }
    if (callback) {
      return callback(error, response);
    }
  });

};

exports.VERSION = '0.0.5';

<commit_msg>set proxy<commit_after>var request = require('request');

var randomId = function (seed) {
  if (seed) {
    return Math.floor(Math.random() * seed + 1000000000);
  }

  return Math.floor(Math.random() * 8999999999 + 1000000000);
};

var cookieParams = function () {
  var utma1 = randomId();
  var utma2 = randomId();
  var today = Date.now();

  var str1 = '1.' + utma1 + '00145214523.' + utma2 + '.' + today + '.' + today + '.15';

  return '__utma=' + str1 + ';+__utmz=1.' + today + '.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none);';
};

var eventData = function (category, action, label, value) {
  var data = '5(' + category + '*' + action;
  if (label) {
    data += '*' + label + ')';
  } else {
    data += ')';
  }
  if (value) {
    data += '(' + value + ')';
  }
  return data;
};

var GOOGLE_HOST = 'www.google-analytics.com';
var BEACON_PATH = '/__utm.gif';
var USER_AGENT = 'Nodealytics Agent';

var options = {
  utmwv : "4.4sh", // Google Analytics version
  utmcs : "UTF-8", // charset
  utmul : "en-us", // language

  utmn : randomId(),
  utmhid : randomId(),
  user_agent : USER_AGENT,

  custom_vars : [] // TODO: Implement custom variables
};

exports.initialize = function(accountId, domain, callback) {
  options.utmac = accountId;
  if (!/UA-[0-9-]+[0-9]+/i.test(accountId)) {
    return callback(new Error('Account ID is invalid'));
  }

  if (domain.length < 1) {
    return callback(new Error('Domain is invalid'));
  }

  options.utmhn = domain;

  if (callback) {
    return callback();
  }
};

exports.setProxy = function(proxyAddress) {
	request = require('request').defaults({proxy:proxyAddress, agent:false});
}

exports.trackPage = function (title, page, params, callback) {
  if (typeof params === 'function') {
    callback = params;
    params = {};
  }

  if (typeof options.utmac === 'undefined') {
    return new Error('Google Analytics Account ID is undefined');
  }
  if (typeof options.utmhn === 'undefined') {
    return new Error('Google Analytics Domain is undefined');
  }

  var pageViewParams = {
    utmwv : options.utmwv,
    utmn : options.utmn,
    utmhn : options.utmhn,
    utmcs : options.utmcs,
    utmul : options.utmul,
    utmdt : title,
    utmhid : randomId(),
    utmp : page,
    utmac : options.utmac,
    utmcc : cookieParams()
  };

  Object.keys(params).forEach(function (key, i) {
    pageViewParams[key] = params[key];
  });

  return this.runQuery(pageViewParams, callback);
};

exports.trackEvent = function (category, action, label, value, utmni, utmhid, callback) {
  if (typeof label === 'function') {
    callback = label;
    label = undefined;
  } else if (typeof value === 'function') {
    callback = value;
    value = undefined;
  } else if (typeof utmni === 'function') {
    callback = utmni;
    utmni = undefined;
  } else if (typeof utmhid === 'function') {
    callback = utmhid;
    utmhid = undefined;
  }

  if (typeof options.utmac === 'undefined') {
    return callback(new Error('Google Analytics Account ID is undefined'));
  }
  if (typeof options.utmhn === 'undefined') {
    return callback(new Error('Google Analytics Domain is undefined'));
  }

  if (typeof utmni !== 'undefined' && typeof utmni !== 'boolean') {
    return callback(new Error('utmni must be a boolean'));
  }

  var eventParams = {
    utmwv : options.utmwv,
    utmn : options.utmn,
    utmhn : options.utmhn,
    utmt : 'event',
    utme : eventData(category, action, label, value), // #{custom_var_data}, TODO: work on custom data
    utmcs : options.utmcs,
    utmul : options.utmul,
    utmhid : (utmhid || randomId()),
    utmac : options.utmac,
    utmcc : options.utmcc || cookieParams()
  };

  if (utmni) {
    eventParams.utmni = 1; // 1 for non interactive event, excluded from bounce calcs
  }

  return this.runQuery(eventParams, callback);
};

exports.mapParams = function(params) {
  var result = '';

  Object.keys(params).forEach(function (key, i) {
    result += key + '=' + params[key] + '&';
  });
  result = result.slice(0, -1);

  return result;
};

exports.runQuery = function (params, callback) {
  var query = 'http://' + GOOGLE_HOST + BEACON_PATH + '?';

  query += exports.mapParams(params);

  request.get(query, function (error, response, body) {
    if (!error && response.statusCode == 200) {
      // console.log(body);
    }
    if (callback) {
      return callback(error, response);
    }
  });

};

exports.VERSION = '0.0.5';

<|endoftext|>


<commit_before><commit_msg>Use new jQuery UI tabs API.<commit_after><|endoftext|>


<commit_before>/* Vim: set ts=8 sts=2 et sw=2 tw=80: */

var self     = require("sdk/self");
var buttons  = require('sdk/ui/button/toggle');
var tabs     = require("sdk/tabs");
var panels   = require("sdk/panel");
var spref    = require('sdk/simple-prefs');
var _        = require("sdk/l10n").get; // Localization
var {Cc, Ci} = require("chrome");       // Exports for tests

/*
 * Directory for highlight.js code (under data/)
 */
var gHJSPath = "highlightjs";
/*
 * Last language id chosen
 */
var gId;

/*
 * Icon sets for toggle button
 */
var gIconInit = { // actually links towards ./lightbulb_off-xx.png
  "16": "./lightbulb_init-16.png",
  "32": "./lightbulb_init-32.png",
  "64": "./lightbulb_init-64.png"
};
var gIconOff = {
  "16": "./lightbulb_off-16.png",
  "32": "./lightbulb_off-32.png",
  "64": "./lightbulb_off-64.png"
};
var gIconOn = {
  "16": "./lightbulb_on-16.png",
  "32": "./lightbulb_on-32.png",
  "64": "./lightbulb_on-64.png"
};

/*
 * Toggle button
 */
var button = buttons.ToggleButton({
  id      : "Highlighter",
  label   : _("button_label"),
  icon    : gIconInit,
  onClick : handleClick
});

/*
 * Language selection panel
 */
var panelSelect = "window.addEventListener('click', function(event) {" +
                  "  let t = event.target;" +
                  "  if (t.nodeName == 'DIV') {" +
                  "    self.port.emit('click-lang', t.getAttribute('id'));" +
                  "  }" +
                  "}, false);";

var panel = panels.Panel({
  contentURL    : self.data.url("panel.html"),
  contentScript : panelSelect,
  onHide        : function() {
    if (gId == "") {
      button.state("tab", {"icon" : gIconOff, "checked" : false});
    }
  }
});

panel.port.on("click-lang", function(id) {
  gId = id;
  panel.hide();
  doHighlight();
});

/*
 * Callbacks
 */
function handleClick(state) {
  /*
   * Classic behavior (window-wise) would be:
   *    // checked is false: clicking a first time set it to true
   *    if (checked)      // i.e. we just clicked an odd time
   *      do highlight
   *    else              // we just clicked an even time
   *      undo highlight
   *    fi
   * But here we toggle tab-wise, so we need to check "manually".
   *
   * Also first time we click tab.checked is false, click does not set it to
   * true. Hence we need a way to know if it's the first time for this tab:
   * here we change the icon path (actually is a link to same PNG file).
   */
  button.state("window", {"checked" : false});
  if (button.state("tab").icon["16"] == gIconInit["16"]) {
    button.state("tab", {"icon" : gIconOn, "checked" : false});
  }

  if (!button.state("tab").checked) {
    button.state("tab", {"icon" : gIconOn, "checked" : true});
    gId = "";
    panel.show({
      position: button
    });
  }
  else {
    button.state("tab", {"icon" : gIconOff, "checked" : false});
    undoHighlight();
  }
}

function doHighlight() {
  console.debug(_("log_highlight", gId, spref.prefs["style"]));

  let worker = tabs.activeTab.attach({
    contentScriptOptions: {
      "stylesheet" : self.data.url(gHJSPath + "/styles/" + spref.prefs["style"] + ".css"),
      "language"   : gId
    },
    contentScriptFile: [
      self.data.url(gHJSPath + "/highlight.pack.js"),
      self.data.url("enlightscript.js")
    ]
  });

  worker.port.on("toggle_off", function(reason) {
  /*
   * For some reason document content is not highlighted.
   * Need to toggle button off.
   */
    if (!button.state("tab").checked) {
      return;
    }
    let logToggleOffReason = _("log_toff_r" + reason);
    console.debug(_("log_toggleoff", logToggleOffReason));
    button.state("tab", {"icon" : gIconOff, "checked" : false});
  });
}

function undoHighlight() {
  console.debug(_("log_undo"));
  tabs.activeTab.attach({
    contentScriptFile: [
      self.data.url("enlightscript.js")
    ]
  });
}

exports.button      = button;
exports.panel       = panel;
exports.doHighlight = doHighlight;
<commit_msg>gId becomes a panel attribute, so that we can simulate panel.port.on('click-lang') in tests<commit_after>/* Vim: set ts=8 sts=2 et sw=2 tw=80: */

var self     = require("sdk/self");
var buttons  = require('sdk/ui/button/toggle');
var tabs     = require("sdk/tabs");
var panels   = require("sdk/panel");
var spref    = require('sdk/simple-prefs');
var _        = require("sdk/l10n").get; // Localization
var {Cc, Ci} = require("chrome");       // Exports for tests

/*
 * Directory for highlight.js code (under data/)
 */
var gHJSPath = "highlightjs";

/*
 * Icon sets for toggle button
 */
var gIconInit = { // actually links towards ./lightbulb_off-xx.png
  "16": "./lightbulb_init-16.png",
  "32": "./lightbulb_init-32.png",
  "64": "./lightbulb_init-64.png"
};
var gIconOff = {
  "16": "./lightbulb_off-16.png",
  "32": "./lightbulb_off-32.png",
  "64": "./lightbulb_off-64.png"
};
var gIconOn = {
  "16": "./lightbulb_on-16.png",
  "32": "./lightbulb_on-32.png",
  "64": "./lightbulb_on-64.png"
};

/*
 * Toggle button
 */
var button = buttons.ToggleButton({
  id      : "Highlighter",
  label   : _("button_label"),
  icon    : gIconInit,
  onClick : handleClick
});

/*
 * Language selection panel
 */
var panelSelect = "window.addEventListener('click', function(event) {" +
                  "  let t = event.target;" +
                  "  if (t.nodeName == 'DIV') {" +
                  "    self.port.emit('click-lang', t.getAttribute('id'));" +
                  "  }" +
                  "}, false);";

var panel = panels.Panel({
  contentURL    : self.data.url("panel.html"),
  contentScript : panelSelect,
  onHide        : function() {
    if (panel.languageId == "" || panel.languageId == undefined) {
      button.state("tab", {"icon" : gIconOff, "checked" : false});
    }
  }
});

panel.port.on("click-lang", function(languageId) {
  panel.languageId = languageId;
  panel.hide();
  doHighlight();
});

/*
 * Callbacks
 */
function handleClick(state) {
  /*
   * Classic behavior (window-wise) would be:
   *    // checked is false: clicking a first time set it to true
   *    if (checked)      // i.e. we just clicked an odd time
   *      do highlight
   *    else              // we just clicked an even time
   *      undo highlight
   *    fi
   * But here we toggle tab-wise, so we need to check "manually".
   *
   * Also first time we click tab.checked is false, click does not set it to
   * true. Hence we need a way to know if it's the first time for this tab:
   * here we change the icon path (actually is a link to same PNG file).
   */
  button.state("window", {"checked" : false});
  if (button.state("tab").icon["16"] == gIconInit["16"]) {
    button.state("tab", {"icon" : gIconOn, "checked" : false});
  }

  if (!button.state("tab").checked) {
    button.state("tab", {"icon" : gIconOn, "checked" : true});
    panel.languageId = "";
    panel.show({
      position: button
    });
  }
  else {
    button.state("tab", {"icon" : gIconOff, "checked" : false});
    undoHighlight();
  }
}

function doHighlight() {
  console.debug(_("log_highlight", panel.languageId, spref.prefs["style"]));

  let worker = tabs.activeTab.attach({
    contentScriptOptions: {
      "stylesheet" : self.data.url(gHJSPath + "/styles/" + spref.prefs["style"] + ".css"),
      "language"   : panel.languageId
    },
    contentScriptFile: [
      self.data.url(gHJSPath + "/highlight.pack.js"),
      self.data.url("enlightscript.js")
    ]
  });

  worker.port.on("toggle_off", function(reason) {
  /*
   * For some reason document content is not highlighted.
   * Need to toggle button off.
   */
    if (!button.state("tab").checked) {
      return;
    }
    let logToggleOffReason = _("log_toff_r" + reason);
    console.debug(_("log_toggleoff", logToggleOffReason));
    button.state("tab", {"icon" : gIconOff, "checked" : false});
  });
}

function undoHighlight() {
  console.debug(_("log_undo"));
  tabs.activeTab.attach({
    contentScriptFile: [
      self.data.url("enlightscript.js")
    ]
  });
}

exports.button      = button;
exports.panel       = panel;
exports.doHighlight = doHighlight;
<|endoftext|>