<commit_before>import Bresenham from './bresenham';
import ImageDebug from '../common/image_debug';
import Code128Reader from '../reader/code_128_reader';
import EANReader from '../reader/ean_reader';
import Code39Reader from '../reader/code_39_reader';
import Code39VINReader from '../reader/code_39_vin_reader';
import CodabarReader from '../reader/codabar_reader';
import UPCReader from '../reader/upc_reader';
import EAN8Reader from '../reader/ean_8_reader';
import EAN2Reader from '../reader/ean_2_reader';
import EAN5Reader from '../reader/ean_5_reader';
import UPCEReader from '../reader/upc_e_reader';
import I2of5Reader from '../reader/i2of5_reader';
import TwoOfFiveReader from '../reader/2of5_reader';
import Code93Reader from '../reader/code_93_reader';

const READERS = {
    code_128_reader: Code128Reader,
    ean_reader: EANReader,
    ean_5_reader: EAN5Reader,
    ean_2_reader: EAN2Reader,
    ean_8_reader: EAN8Reader,
    code_39_reader: Code39Reader,
    code_39_vin_reader: Code39VINReader,
    codabar_reader: CodabarReader,
    upc_reader: UPCReader,
    upc_e_reader: UPCEReader,
    i2of5_reader: I2of5Reader,
    '2of5_reader': TwoOfFiveReader,
    code_93_reader: Code93Reader,
};

export default {
    registerReader: (name, reader) => {
        READERS[name] = reader;
    },
    create: function(config, inputImageWrapper) {
        var _canvas = {
                ctx: {
                    frequency: null,
                    pattern: null,
                    overlay: null,
                },
                dom: {
                    frequency: null,
                    pattern: null,
                    overlay: null,
                },
            },
            _barcodeReaders = [];

        initCanvas();
        initReaders();
        initConfig();

        function initCanvas() {
            if (ENV.development && typeof document !== 'undefined') {
                var $debug = document.querySelector('#debug.detection');
                _canvas.dom.frequency = document.querySelector('canvas.frequency');
                if (!_canvas.dom.frequency) {
                    _canvas.dom.frequency = document.createElement('canvas');
                    _canvas.dom.frequency.className = 'frequency';
                    if ($debug) {
                        $debug.appendChild(_canvas.dom.frequency);
                    }
                }
                _canvas.ctx.frequency = _canvas.dom.frequency.getContext('2d');

                _canvas.dom.pattern = document.querySelector('canvas.patternBuffer');
                if (!_canvas.dom.pattern) {
                    _canvas.dom.pattern = document.createElement('canvas');
                    _canvas.dom.pattern.className = 'patternBuffer';
                    if ($debug) {
                        $debug.appendChild(_canvas.dom.pattern);
                    }
                }
                _canvas.ctx.pattern = _canvas.dom.pattern.getContext('2d');

                _canvas.dom.overlay = document.querySelector('canvas.drawingBuffer');
                if (_canvas.dom.overlay) {
                    _canvas.ctx.overlay = _canvas.dom.overlay.getContext('2d');
                }
            }
        }

        function initReaders() {
            config.readers.forEach(function(readerConfig) {
                var reader,
                    configuration = {},
                    supplements = [];

                if (typeof readerConfig === 'object') {
                    reader = readerConfig.format;
                    configuration = readerConfig.config;
                } else if (typeof readerConfig === 'string') {
                    reader = readerConfig;
                }
                if (ENV.development) {
                    console.log('Before registering reader: ', reader);
                }
                if (configuration.supplements) {
                    supplements = configuration
                        .supplements.map((supplement) => {
                            return new READERS[supplement]();
                        });
                }
                try {
                    const readerObj = new READERS[reader](configuration, supplements);
                    _barcodeReaders.push(readerObj);
                } catch (err) {
                    console.error('* Error constructing reader ', reader, err);
                    throw err;
                }
            });
            if (ENV.development) {
                console.log('Registered Readers: ' + _barcodeReaders
                    .map((reader) => JSON.stringify({format: reader.FORMAT, config: reader.config}))
                    .join(', '));
            }
        }

        function initConfig() {
            if (ENV.development && typeof document !== 'undefined') {
                var i,
                    vis = [{
                        node: _canvas.dom.frequency,
                        prop: config.debug.showFrequency,
                    }, {
                        node: _canvas.dom.pattern,
                        prop: config.debug.showPattern,
                    }];

                for (i = 0; i < vis.length; i++) {
                    if (vis[i].prop === true) {
                        vis[i].node.style.display = 'block';
                    } else {
                        vis[i].node.style.display = 'none';
                    }
                }
            }
        }

        /**
         * extend the line on both ends
         * @param {Array} line
         * @param {Number} angle
         */
        function getExtendedLine(line, angle, ext) {
            function extendLine(amount) {
                var extension = {
                    y: amount * Math.sin(angle),
                    x: amount * Math.cos(angle),
                };

                line[0].y -= extension.y;
                line[0].x -= extension.x;
                line[1].y += extension.y;
                line[1].x += extension.x;
            }

            // check if inside image
            extendLine(ext);
            while (ext > 1 && (!inputImageWrapper.inImageWithBorder(line[0], 0)
                    || !inputImageWrapper.inImageWithBorder(line[1], 0))) {
                ext -= Math.ceil(ext / 2);
                extendLine(-ext);
            }
            return line;
        }

        function getLine(box) {
            return [{
                x: (box[1][0] - box[0][0]) / 2 + box[0][0],
                y: (box[1][1] - box[0][1]) / 2 + box[0][1],
            }, {
                x: (box[3][0] - box[2][0]) / 2 + box[2][0],
                y: (box[3][1] - box[2][1]) / 2 + box[2][1],
            }];
        }

        function tryDecode(line) {
            var result = null,
                i,
                barcodeLine = Bresenham.getBarcodeLine(inputImageWrapper, line[0], line[1]);

            if (ENV.development && config.debug.showFrequency) {
                ImageDebug.drawPath(line, {x: 'x', y: 'y'}, _canvas.ctx.overlay, {color: 'red', lineWidth: 3});
                Bresenham.debug.printFrequency(barcodeLine.line, _canvas.dom.frequency);
            }

            Bresenham.toBinaryLine(barcodeLine);

            if (ENV.development && config.debug.showPattern) {
                Bresenham.debug.printPattern(barcodeLine.line, _canvas.dom.pattern);
            }

            for ( i = 0; i < _barcodeReaders.length && result === null; i++) {
                result = _barcodeReaders[i].decodePattern(barcodeLine.line);
            }
            if (result === null){
                return null;
            }
            return {
                codeResult: result,
                barcodeLine: barcodeLine,
            };
        }

        /**
         * This method slices the given area apart and tries to detect a barcode-pattern
         * for each slice. It returns the decoded barcode, or null if nothing was found
         * @param {Array} box
         * @param {Array} line
         * @param {Number} lineAngle
         */
        function tryDecodeBruteForce(box, line, lineAngle) {
            var sideLength = Math.sqrt(Math.pow(box[1][0] - box[0][0], 2) + Math.pow((box[1][1] - box[0][1]), 2)),
                i,
                slices = 16,
                result = null,
                dir,
                extension,
                xdir = Math.sin(lineAngle),
                ydir = Math.cos(lineAngle);

            for ( i = 1; i < slices && result === null; i++) {
                // move line perpendicular to angle
                dir = sideLength / slices * i * (i % 2 === 0 ? -1 : 1);
                extension = {
                    y: dir * xdir,
                    x: dir * ydir,
                };
                line[0].y += extension.x;
                line[0].x -= extension.y;
                line[1].y += extension.x;
                line[1].x -= extension.y;

                result = tryDecode(line);
            }
            return result;
        }

        function getLineLength(line) {
            return Math.sqrt(
                Math.pow(Math.abs(line[1].y - line[0].y), 2) +
                Math.pow(Math.abs(line[1].x - line[0].x), 2));
        }

        function decodeFromImage(imageWrapper) {
            let result = null;
            for (let i = 0; i < _barcodeReaders.length && result === null; i++) {
                result = _barcodeReaders[i].decodeImage ? _barcodeReaders[i].decodeImage(imageWrapper) : null;
            }
            return result;
        }
        /**
         * With the help of the configured readers (Code128 or EAN) this function tries to detect a
         * valid barcode pattern within the given area.
         * @param {Object} box The area to search in
         * @returns {Object} the result {codeResult, line, angle, pattern, threshold}
         */
        function decodeFromBoundingBox(box) {
            var line,
                lineAngle,
                ctx = _canvas.ctx.overlay,
                result,
                lineLength;

            if (ENV.development) {
                if (config.debug.drawBoundingBox && ctx) {
                    ImageDebug.drawPath(box, {x: 0, y: 1}, ctx, {color: 'blue', lineWidth: 2});
                }
            }

            line = getLine(box);
            lineLength = getLineLength(line);
            lineAngle = Math.atan2(line[1].y - line[0].y, line[1].x - line[0].x);
            line = getExtendedLine(line, lineAngle, Math.floor(lineLength * 0.1));
            if (line === null){
                return null;
            }

            result = tryDecode(line);
            if (result === null) {
                result = tryDecodeBruteForce(box, line, lineAngle);
            }

            if (result === null) {
                return null;
            }

            if (ENV.development && result && config.debug.drawScanline && ctx) {
                ImageDebug.drawPath(line, {x: 'x', y: 'y'}, ctx, {color: 'red', lineWidth: 3});
            }

            return {
                codeResult: result.codeResult,
                line: line,
                angle: lineAngle,
                pattern: result.barcodeLine.line,
                threshold: result.barcodeLine.threshold,
            };
        }

        return {
            decodeFromBoundingBox: function(box) {
                return decodeFromBoundingBox(box);
            },
            decodeFromBoundingBoxes: function(boxes) {
                var i, result,
                    barcodes = [],
                    multiple = config.multiple;

                for ( i = 0; i < boxes.length; i++) {
                    const box = boxes[i];
                    result = decodeFromBoundingBox(box) || {};
                    result.box = box;

                    if (multiple) {
                        barcodes.push(result);
                    } else if (result.codeResult) {
                        return result;
                    }
                }
                return { barcodes };
            },
            decodeFromImage: function(inputImageWrapper) {
                const result = decodeFromImage(inputImageWrapper);
                return result;
            },
            registerReader: function(name, reader) {
                if (READERS[name]) {
                    throw new Error('cannot register existing reader', name);
                }
                READERS[name] = reader;
            },
            setReaders: function(readers) {
                config.readers = readers;
                _barcodeReaders.length = 0;
                initReaders();
            },
        };
    },
};
<commit_msg>Revert "barcode_decoder: fix eslint errors"<commit_after>import Bresenham from './bresenham';
import ImageDebug from '../common/image_debug';
import Code128Reader from '../reader/code_128_reader';
import EANReader from '../reader/ean_reader';
import Code39Reader from '../reader/code_39_reader';
import Code39VINReader from '../reader/code_39_vin_reader';
import CodabarReader from '../reader/codabar_reader';
import UPCReader from '../reader/upc_reader';
import EAN8Reader from '../reader/ean_8_reader';
import EAN2Reader from '../reader/ean_2_reader';
import EAN5Reader from '../reader/ean_5_reader';
import UPCEReader from '../reader/upc_e_reader';
import I2of5Reader from '../reader/i2of5_reader';
import TwoOfFiveReader from '../reader/2of5_reader';
import Code93Reader from '../reader/code_93_reader';

const READERS = {
    code_128_reader: Code128Reader,
    ean_reader: EANReader,
    ean_5_reader: EAN5Reader,
    ean_2_reader: EAN2Reader,
    ean_8_reader: EAN8Reader,
    code_39_reader: Code39Reader,
    code_39_vin_reader: Code39VINReader,
    codabar_reader: CodabarReader,
    upc_reader: UPCReader,
    upc_e_reader: UPCEReader,
    i2of5_reader: I2of5Reader,
    '2of5_reader': TwoOfFiveReader,
    code_93_reader: Code93Reader,
};

export default {
    registerReader: (name, reader) => {
        READERS[name] = reader;
    },
    create: function(config, inputImageWrapper) {
        var _canvas = {
                ctx: {
                    frequency: null,
                    pattern: null,
                    overlay: null,
                },
                dom: {
                    frequency: null,
                    pattern: null,
                    overlay: null,
                },
            },
            _barcodeReaders = [];

        initCanvas();
        initReaders();
        initConfig();

        function initCanvas() {
            if (ENV.development && typeof document !== 'undefined') {
                var $debug = document.querySelector('#debug.detection');
                _canvas.dom.frequency = document.querySelector('canvas.frequency');
                if (!_canvas.dom.frequency) {
                    _canvas.dom.frequency = document.createElement('canvas');
                    _canvas.dom.frequency.className = 'frequency';
                    if ($debug) {
                        $debug.appendChild(_canvas.dom.frequency);
                    }
                }
                _canvas.ctx.frequency = _canvas.dom.frequency.getContext('2d');

                _canvas.dom.pattern = document.querySelector('canvas.patternBuffer');
                if (!_canvas.dom.pattern) {
                    _canvas.dom.pattern = document.createElement('canvas');
                    _canvas.dom.pattern.className = 'patternBuffer';
                    if ($debug) {
                        $debug.appendChild(_canvas.dom.pattern);
                    }
                }
                _canvas.ctx.pattern = _canvas.dom.pattern.getContext('2d');

                _canvas.dom.overlay = document.querySelector('canvas.drawingBuffer');
                if (_canvas.dom.overlay) {
                    _canvas.ctx.overlay = _canvas.dom.overlay.getContext('2d');
                }
            }
        }

        function initReaders() {
            config.readers.forEach(function(readerConfig) {
                var reader,
                    configuration = {},
                    supplements = [];

                if (typeof readerConfig === 'object') {
                    reader = readerConfig.format;
                    configuration = readerConfig.config;
                } else if (typeof readerConfig === 'string') {
                    reader = readerConfig;
                }
                if (ENV.development) {
                    console.log('Before registering reader: ', reader);
                }
                if (configuration.supplements) {
                    supplements = configuration
                        .supplements.map((supplement) => {
                            return new READERS[supplement]();
                        });
                }
                try {
                    const readerObj = new READERS[reader](configuration, supplements);
                    _barcodeReaders.push(readerObj);
                } catch (err) {
                    console.error('* Error constructing reader ', reader, err);
                    throw err;
                }
            });
            if (ENV.development) {
                console.log('Registered Readers: ' + _barcodeReaders
                    .map((reader) => JSON.stringify({format: reader.FORMAT, config: reader.config}))
                    .join(', '));
            }
        }

        function initConfig() {
            if (ENV.development && typeof document !== 'undefined') {
                var i,
                    vis = [{
                        node: _canvas.dom.frequency,
                        prop: config.debug.showFrequency,
                    }, {
                        node: _canvas.dom.pattern,
                        prop: config.debug.showPattern,
                    }];

                for (i = 0; i < vis.length; i++) {
                    if (vis[i].prop === true) {
                        vis[i].node.style.display = 'block';
                    } else {
                        vis[i].node.style.display = 'none';
                    }
                }
            }
        }

        /**
         * extend the line on both ends
         * @param {Array} line
         * @param {Number} angle
         */
        function getExtendedLine(line, angle, ext) {
            function extendLine(amount) {
                var extension = {
                    y: amount * Math.sin(angle),
                    x: amount * Math.cos(angle),
                };

                line[0].y -= extension.y;
                line[0].x -= extension.x;
                line[1].y += extension.y;
                line[1].x += extension.x;
            }

            // check if inside image
            extendLine(ext);
            while (ext > 1 && (!inputImageWrapper.inImageWithBorder(line[0], 0)
                    || !inputImageWrapper.inImageWithBorder(line[1], 0))) {
                ext -= Math.ceil(ext / 2);
                extendLine(-ext);
            }
            return line;
        }

        function getLine(box) {
            return [{
                x: (box[1][0] - box[0][0]) / 2 + box[0][0],
                y: (box[1][1] - box[0][1]) / 2 + box[0][1],
            }, {
                x: (box[3][0] - box[2][0]) / 2 + box[2][0],
                y: (box[3][1] - box[2][1]) / 2 + box[2][1],
            }];
        }

        function tryDecode(line) {
            var result = null,
                i,
                barcodeLine = Bresenham.getBarcodeLine(inputImageWrapper, line[0], line[1]);

            if (ENV.development && config.debug.showFrequency) {
                ImageDebug.drawPath(line, {x: 'x', y: 'y'}, _canvas.ctx.overlay, {color: 'red', lineWidth: 3});
                Bresenham.debug.printFrequency(barcodeLine.line, _canvas.dom.frequency);
            }

            Bresenham.toBinaryLine(barcodeLine);

            if (ENV.development && config.debug.showPattern) {
                Bresenham.debug.printPattern(barcodeLine.line, _canvas.dom.pattern);
            }

            for ( i = 0; i < _barcodeReaders.length && result === null; i++) {
                result = _barcodeReaders[i].decodePattern(barcodeLine.line);
            }
            if (result === null){
                return null;
            }
            return {
                codeResult: result,
                barcodeLine: barcodeLine,
            };
        }

        /**
         * This method slices the given area apart and tries to detect a barcode-pattern
         * for each slice. It returns the decoded barcode, or null if nothing was found
         * @param {Array} box
         * @param {Array} line
         * @param {Number} lineAngle
         */
        function tryDecodeBruteForce(box, line, lineAngle) {
            var sideLength = Math.sqrt(Math.pow(box[1][0] - box[0][0], 2) + Math.pow((box[1][1] - box[0][1]), 2)),
                i,
                slices = 16,
                result = null,
                dir,
                extension,
                xdir = Math.sin(lineAngle),
                ydir = Math.cos(lineAngle);

            for ( i = 1; i < slices && result === null; i++) {
                // move line perpendicular to angle
                dir = sideLength / slices * i * (i % 2 === 0 ? -1 : 1);
                extension = {
                    y: dir * xdir,
                    x: dir * ydir,
                };
                line[0].y += extension.x;
                line[0].x -= extension.y;
                line[1].y += extension.x;
                line[1].x -= extension.y;

                result = tryDecode(line);
            }
            return result;
        }

        function getLineLength(line) {
            return Math.sqrt(
                Math.pow(Math.abs(line[1].y - line[0].y), 2) +
                Math.pow(Math.abs(line[1].x - line[0].x), 2));
        }

        function decodeFromImage(imageWrapper) {
            let result = null;
            for (let i = 0; i < _barcodeReaders.length && result === null; i++) {
                result = _barcodeReaders[i].decodeImage ? _barcodeReaders[i].decodeImage(imageWrapper) : null;
            }
            return result;
        }
        /**
         * With the help of the configured readers (Code128 or EAN) this function tries to detect a
         * valid barcode pattern within the given area.
         * @param {Object} box The area to search in
         * @returns {Object} the result {codeResult, line, angle, pattern, threshold}
         */
        function decodeFromBoundingBox(box) {
            var line,
                lineAngle,
                ctx = _canvas.ctx.overlay,
                result,
                lineLength;

            if (ENV.development) {
                if (config.debug.drawBoundingBox && ctx) {
                    ImageDebug.drawPath(box, {x: 0, y: 1}, ctx, {color: 'blue', lineWidth: 2});
                }
            }

            line = getLine(box);
            lineLength = getLineLength(line);
            lineAngle = Math.atan2(line[1].y - line[0].y, line[1].x - line[0].x);
            line = getExtendedLine(line, lineAngle, Math.floor(lineLength * 0.1));
            if (line === null){
                return null;
            }

            result = tryDecode(line);
            if (result === null) {
                result = tryDecodeBruteForce(box, line, lineAngle);
            }

            if (result === null) {
                return null;
            }

            if (ENV.development && result && config.debug.drawScanline && ctx) {
                ImageDebug.drawPath(line, {x: 'x', y: 'y'}, ctx, {color: 'red', lineWidth: 3});
            }

            return {
                codeResult: result.codeResult,
                line: line,
                angle: lineAngle,
                pattern: result.barcodeLine.line,
                threshold: result.barcodeLine.threshold,
            };
        }

        return {
            decodeFromBoundingBox: function(box) {
                return decodeFromBoundingBox(box);
            },
            decodeFromBoundingBoxes: function(boxes) {
                var i, result,
                    barcodes = [],
                    multiple = config.multiple;

                for ( i = 0; i < boxes.length; i++) {
                    const box = boxes[i];
                    result = decodeFromBoundingBox(box) || {};
                    result.box = box;

                    if (multiple) {
                        barcodes.push(result);
                    } else if (result.codeResult) {
                        return result;
                    }
                }

                if (multiple) {
                    return {
                        barcodes
                    };
                }
            },
            decodeFromImage: function(inputImageWrapper) {
                const result = decodeFromImage(inputImageWrapper);
                return result;
            },
            registerReader: function(name, reader) {
                if (READERS[name]) {
                    throw new Error('cannot register existing reader', name);
                }
                READERS[name] = reader;
            },
            setReaders: function(readers) {
                config.readers = readers;
                _barcodeReaders.length = 0;
                initReaders();
            },
        };
    },
};
<|endoftext|>


<commit_before>var globalGraph = null; // TODO: integrate with react
define([], function () {
    var ProfileGraph = React.createClass({
        componentDidMount: function() {
            this.updateGraph();
        },
        componentDidUpdate: function() {
            this.updateGraph();
        },
        updateGraph: function() {
            var pData = this.props.profileData[1];

            var sortList = [];
            for (var i=0; i<pData.labels.length; i++) {
                sortList.push({"label": pData.labels[i], "value": pData.values[i]});
            }
            sortList.sort(function(a, b) {
                return a.value - b.value;
            });

            debugger
            var data = {
                labels: sortList.map(function(a) {return a.label}),
                datasets: [
                    {
                        label: "Call Frequency",
                        fillColor: "rgba(151,187,205,0.5)",
                        strokeColor: "rgba(151,187,205,0.8)",
                        highlightFill: "rgba(151,187,205,0.75)",
                        highlightStroke: "rgba(151,187,205,1)",
                        data: sortList.map(function(a) {return a.value})
                    }
                ]
            };
            var ctx = this.refs.canvas.getContext("2d");
            if (globalGraph) {
                globalGraph.destroy();
            }
            var graph = new Chart(ctx);
            globalGraph = graph.HorizontalBar(data, {});
        },
        render: function() {
            return <canvas
                style={{"padding-left":"50px"}}
                height={400}
                width={600}
                className="profile-graph"
                ref={"canvas"}>
            </canvas>;
        }
    });
    return ProfileGraph;
});
<commit_msg>Make call stack histogram responsive<commit_after>var globalGraph = null; // TODO: integrate with react
define([], function () {
    var ProfileGraph = React.createClass({
        componentDidMount: function() {
            this.updateGraph();
        },
        componentDidUpdate: function() {
            this.updateGraph();
        },
        updateGraph: function() {
            var pData = this.props.profileData[1];

            var sortList = [];
            for (var i=0; i<pData.labels.length; i++) {
                sortList.push({"label": pData.labels[i], "value": pData.values[i]});
            }
            sortList.sort(function(a, b) {
                return a.value - b.value;
            });

            debugger
            var data = {
                labels: sortList.map(function(a) {return a.label}),
                datasets: [
                    {
                        label: "Call Frequency",
                        fillColor: "rgba(151,187,205,0.5)",
                        strokeColor: "rgba(151,187,205,0.8)",
                        highlightFill: "rgba(151,187,205,0.75)",
                        highlightStroke: "rgba(151,187,205,1)",
                        data: sortList.map(function(a) {return a.value})
                    }
                ]
            };
            var ctx = this.refs.canvas.getContext("2d");
            if (globalGraph) {
                globalGraph.destroy();
            }
            var graph = new Chart(ctx);
            globalGraph = graph.HorizontalBar(data, {responsive: true});
        },
        render: function() {
            return <canvas
                style={{"margin-left":"50px", "margin-right": "100px"}}
                className="profile-graph"
                ref={"canvas"}>
            </canvas>;
        }
    });
    return ProfileGraph;
});
<|endoftext|>


<commit_before>var fs = require("fs");
var yaml = require("js-yaml");
var _ = require("lodash");
var path = require("path");
var marked = require("marked");

marked.setOptions({
  gfm: true,
  tables: true,
  breaks: true,
  highlight: function (code) {
    return require('highlight.js').highlightAuto(code).value;
  }
})

/**
 * Defaults object
 *
 */
var defaults = {
  optionsCheck: true,
  optionsDelimiter: "---",
  optionsParse: function (string) {
    return yaml.safeLoad(string);
  },
  contentParse: function (string, ext) {
    if (typeof ext === "string" && (ext.toLowerCase() === "markdown" || ext.toLowerCase() === "md")) {
      return marked(string);
    } else {
      return string;
    }
  },
  templatesDir: path.join(process.cwd(), "src", "layouts"),
  templateCompile: function (string) {
    return _.template(string);
  },
  templateData: {}
};

/**
 * Constructor for the Pagemaki class
 *
 * @param {[type]} config [description]
 */
var Pagemaki = function (config) {
  this.templates = {};
  this.globals = config.globals || {};
  this.config = _.extend({}, defaults, config);
  this.config.optionsRegex = new RegExp("^" + this.config.optionsDelimiter + "([\\S\\s]+)" + this.config.optionsDelimiter + "([\\S\\s]+)");

  if (!config.globals && config.globalYaml) {
    this.globals = yaml.safeLoad(config.globalYaml);
  }
};

/**
 * Find and return the template string to be compiled
 *
 * Note: this can be overridden by passing a 'getTemplateString'
 * function to the Pagemaki constructor, esp for testing
 *
 * @param  {[type]} name [description]
 * @return {[type]}      [description]
 */
Pagemaki.prototype.getTemplateString = function (name) {
  return fs.readFileSync(path.join(this.config.templatesDir, name + ".html")).toString();
}

/**
 * Get a cached template by name, or from disk and then cache for later
 *
 * @param  {[type]} name [description]
 * @return {[type]}      [description]
 */
Pagemaki.prototype.getTemplate = function (name) {

  var getTemplateString = (this.config.getTemplateString || this.getTemplateString).bind(this);

  if (!this.templates[name]) {
    this.templates[name] = this.config.templateCompile(getTemplateString(name).trim());
  }

  return this.templates[name];

};

/**
 * Parse out the string and look for options, content
 *
 * @param  {Object}   input    File object with string 'contents' and optional extension
 * @param  {Function} callback [description]
 * @return {[type]}            [description]
 */
Pagemaki.prototype.parse = function (input, callback) {

  if (!input) {
    callback(new Error("input.contents is required"));
    return;
  }

  if (typeof input.contents !== "string") {
    callback(new Error("input.contents must be a string, instead " + typeof input.contents));
    return;
  }

  var data = {};
  var matches = this.config.optionsCheck && this.config.optionsRegex.exec(input.contents);

  if (matches) {
    data.options = this.config.optionsParse(matches[1]);
    data.content = this.config.contentParse(matches[2].trim(), input.extension);
  } else {
    data.options = {};
    data.content = this.config.contentParse(input.contents.trim(), input.extension);
  }

  // Merge in global config values to be available in all templates
  data.options = _.defaults({}, data.options, this.globals);
  callback(null, data);

};

/**
 * Use the rendering function to create static string
 *
 * @param  {[type]}   err      [description]
 * @param  {[type]}   parsed   [description]
 * @param  {Function} callback [description]
 * @return {[type]}            [description]
 */
Pagemaki.prototype.render = function (err, parsed, callback) {

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

  if (!parsed.content) {
    callback(null, "");
    return;
  }

  var layout = (parsed.options && parsed.options.layout) || "default";
  var render = this.getTemplate(layout);

  parsed.content = this.config.templateCompile(parsed.content)(parsed.options);
  this.config.templateData.page = parsed;

  callback(null, render(this.config.templateData).trim());

};

/**
 * Putting it all together using the parsed options, content,
 * and templates to compile static HTML
 *
 * @param  {Object}   input   [description]
 * @param  {Function} callback [description]
 * @return {[type]}            [description]
 */
Pagemaki.prototype.make = function (input, callback) {

  var self = this;

  this.parse(input, function (err, parsed) {

    self.render(err, parsed, callback);

  });

};

module.exports = Pagemaki;
<commit_msg>Allow globals to be passed in as yaml to be parsed<commit_after>var fs = require("fs");
var yaml = require("js-yaml");
var _ = require("lodash");
var path = require("path");
var marked = require("marked");

marked.setOptions({
  gfm: true,
  tables: true,
  breaks: true,
  highlight: function (code) {
    return require('highlight.js').highlightAuto(code).value;
  }
})

/**
 * Defaults object
 *
 */
var defaults = {
  optionsCheck: true,
  optionsDelimiter: "---",
  optionsParse: function (string) {
    return yaml.safeLoad(string);
  },
  contentParse: function (string, ext) {
    if (typeof ext === "string" && (ext.toLowerCase() === "markdown" || ext.toLowerCase() === "md")) {
      return marked(string);
    } else {
      return string;
    }
  },
  templatesDir: path.join(process.cwd(), "src", "layouts"),
  templateCompile: function (string) {
    return _.template(string);
  },
  templateData: {}
};

/**
 * Constructor for the Pagemaki class
 *
 * @param {[type]} config [description]
 */
var Pagemaki = function (config) {
  this.templates = {};
  this.config = _.extend({}, defaults, config);
  this.config.optionsRegex = new RegExp("^" + this.config.optionsDelimiter + "([\\S\\s]+)" + this.config.optionsDelimiter + "([\\S\\s]+)");

  try {
    // allows for passing globals in as yaml to be parsed
    this.globals = yaml.safeLoad(config.globals);
  } catch (error) {
    this.globals = config.globals || {};
  }
};

/**
 * Find and return the template string to be compiled
 *
 * Note: this can be overridden by passing a 'getTemplateString'
 * function to the Pagemaki constructor, esp for testing
 *
 * @param  {[type]} name [description]
 * @return {[type]}      [description]
 */
Pagemaki.prototype.getTemplateString = function (name) {
  return fs.readFileSync(path.join(this.config.templatesDir, name + ".html")).toString();
}

/**
 * Get a cached template by name, or from disk and then cache for later
 *
 * @param  {[type]} name [description]
 * @return {[type]}      [description]
 */
Pagemaki.prototype.getTemplate = function (name) {

  var getTemplateString = (this.config.getTemplateString || this.getTemplateString).bind(this);

  if (!this.templates[name]) {
    this.templates[name] = this.config.templateCompile(getTemplateString(name).trim());
  }

  return this.templates[name];

};

/**
 * Parse out the string and look for options, content
 *
 * @param  {Object}   input    File object with string 'contents' and optional extension
 * @param  {Function} callback [description]
 * @return {[type]}            [description]
 */
Pagemaki.prototype.parse = function (input, callback) {

  if (!input) {
    callback(new Error("input.contents is required"));
    return;
  }

  if (typeof input.contents !== "string") {
    callback(new Error("input.contents must be a string, instead " + typeof input.contents));
    return;
  }

  var data = {};
  var matches = this.config.optionsCheck && this.config.optionsRegex.exec(input.contents);

  if (matches) {
    data.options = this.config.optionsParse(matches[1]);
    data.content = this.config.contentParse(matches[2].trim(), input.extension);
  } else {
    data.options = {};
    data.content = this.config.contentParse(input.contents.trim(), input.extension);
  }

  // Merge in global config values to be available in all templates
  data.options = _.defaults({}, data.options, this.globals);
  callback(null, data);

};

/**
 * Use the rendering function to create static string
 *
 * @param  {[type]}   err      [description]
 * @param  {[type]}   parsed   [description]
 * @param  {Function} callback [description]
 * @return {[type]}            [description]
 */
Pagemaki.prototype.render = function (err, parsed, callback) {

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

  if (!parsed.content) {
    callback(null, "");
    return;
  }

  var layout = (parsed.options && parsed.options.layout) || "default";
  var render = this.getTemplate(layout);

  parsed.content = this.config.templateCompile(parsed.content)(parsed.options);
  this.config.templateData.page = parsed;

  callback(null, render(this.config.templateData).trim());

};

/**
 * Putting it all together using the parsed options, content,
 * and templates to compile static HTML
 *
 * @param  {Object}   input   [description]
 * @param  {Function} callback [description]
 * @return {[type]}            [description]
 */
Pagemaki.prototype.make = function (input, callback) {

  var self = this;

  this.parse(input, function (err, parsed) {

    self.render(err, parsed, callback);

  });

};

module.exports = Pagemaki;
<|endoftext|>


<commit_before>// pagerank.js
// Copyright 2015 Shumpei IINUMA
// pagerank.js is freely distributable under the terms of the MIT license.

function pagerank(G, params) {
  // based on networkx.pagerank 1.9.1 (Python)
  // https://github.com/networkx/networkx/blob/master/networkx/algorithms/link_analysis/pagerank_alg.py

  // set default parameters
  if (params == null) params = {};
  if (params.alpha == null) params.alpha = 0.85;
  if (params.tol == null) params.tol = 1.0e-6;
  if (params.max_iter == null) params.max_iter = 100;

  // tools
  var sum = function(xs) {
    return xs.reduce(function(prev, current, idx, xs) {
      return prev + current;
    });
  };

  var N = Object.keys(G).length
  if (N == 0) return {};

  // Create a copy in (right) stochastic form
  var W = {}
  for (var node in G) {
    var nodes = G[node];
    var num_nodes = nodes.length;
    var new_nodes = {};
    //for (var node_ in nodes) {
    nodes.forEach(function(node_) {
      new_nodes[node_] = {'weight': 1.0 / num_nodes};
    });
    W[node] = new_nodes;
  }
  //console.log(W);

  // Choose fixed starting vector if not given
  var x = {};
  if (params.nstart == null) {
    for (var node in W) x[node] = 1.0 / N;
  }
  else {
    // Normalized nstart vector
    var sum_ = sum(Object.values(params.nstart));
    for (var node in params.nstart)
      x[node] = params.nstart[node] / sum_;
  }
  //console.log(x);

  p = {};
  if (params.personalization == null) {
    // Assign uniform personalization vector if not given
    for (var node in W) p[node] = 1.0 / N;
  }
  else {
    // TODO: check missing nodes
    var sum_ = sum(Object.values(params.personalization));
    for (var node in params.personalization)
      p[node] = params.personalization[node] / sum_;
  }

  var dangling_weights = {};
  if (params.dangling == null) {
    // Use personalization vector if dangling vector not specified
    dangling_weights = p;
  }
  else {
    // TODO: check missing nodes
    var sum_ = sum(Object.values(params.dangling));
    for (var node in params.dangling)
      dangling_weights[node] = params.dangling[node] / sum_;
  }
  var dangling_nodes = [];
  for (var node in W) {
    if (Object.keys(W[node]).length == 0) // need review
      dangling_nodes.push(node);
  }
  //console.log(dangling_nodes);

  // power iteration: make up to max_iter iterations
  for (var iter_count = 0; iter_count < params.max_iter; iter_count++) {
    var xlast = x;
    x = {};
    for (var node in xlast) x[node] = 0.0;
    var sum_ = 0.0;
    dangling_nodes.forEach(function(node) {
      sum_ += xlast[node]
    });
    var danglesum = params.alpha * sum_;

    for (var node in x) {
      // this matrix multiply looks odd because it is
      // doing a left multiply x^T=xlast^T*W
      for (var nbr in W[node]) {
        x[nbr] += params.alpha * xlast[node] * W[node][nbr]['weight'];
      }
      x[node] += danglesum * dangling_weights[node] + (1.0 - params.alpha) * p[node];
    }

    // check convergence, l1 norm
    var err = 0.0;
    Object.keys(x).forEach(function(node) {
      err += Math.abs(x[node] - xlast[node])
    });
    if (err < N*params.tol)
      return x;
  }

  console.warn('pagerank: power iteration failed to converge in ' +
               params.iter_max + ' iterations.');
  return x;
}

// node.js
//module.exports = pagerank;

// test
//var scores = pagerank({1: [2, 3, 4], 2: [3], 3: [4], 4: []}, {alpha: 0.9});
//console.log(scores);
//
//var scores = pagerank({'foo': ['bar', 'hoge'], 'bar': [], 'hoge': ['foo']});
//console.log(scores);
<commit_msg>remove name<commit_after>function pagerank(G, params) {
  // based on networkx.pagerank 1.9.1 (Python)
  // https://github.com/networkx/networkx/blob/master/networkx/algorithms/link_analysis/pagerank_alg.py

  // set default parameters
  if (params == null) params = {};
  if (params.alpha == null) params.alpha = 0.85;
  if (params.tol == null) params.tol = 1.0e-6;
  if (params.max_iter == null) params.max_iter = 100;

  // tools
  var sum = function(xs) {
    return xs.reduce(function(prev, current, idx, xs) {
      return prev + current;
    });
  };

  var N = Object.keys(G).length
  if (N == 0) return {};

  // Create a copy in (right) stochastic form
  var W = {}
  for (var node in G) {
    var nodes = G[node];
    var num_nodes = nodes.length;
    var new_nodes = {};
    //for (var node_ in nodes) {
    nodes.forEach(function(node_) {
      new_nodes[node_] = {'weight': 1.0 / num_nodes};
    });
    W[node] = new_nodes;
  }
  //console.log(W);

  // Choose fixed starting vector if not given
  var x = {};
  if (params.nstart == null) {
    for (var node in W) x[node] = 1.0 / N;
  }
  else {
    // Normalized nstart vector
    var sum_ = sum(Object.values(params.nstart));
    for (var node in params.nstart)
      x[node] = params.nstart[node] / sum_;
  }
  //console.log(x);

  p = {};
  if (params.personalization == null) {
    // Assign uniform personalization vector if not given
    for (var node in W) p[node] = 1.0 / N;
  }
  else {
    // TODO: check missing nodes
    var sum_ = sum(Object.values(params.personalization));
    for (var node in params.personalization)
      p[node] = params.personalization[node] / sum_;
  }

  var dangling_weights = {};
  if (params.dangling == null) {
    // Use personalization vector if dangling vector not specified
    dangling_weights = p;
  }
  else {
    // TODO: check missing nodes
    var sum_ = sum(Object.values(params.dangling));
    for (var node in params.dangling)
      dangling_weights[node] = params.dangling[node] / sum_;
  }
  var dangling_nodes = [];
  for (var node in W) {
    if (Object.keys(W[node]).length == 0) // need review
      dangling_nodes.push(node);
  }
  //console.log(dangling_nodes);

  // power iteration: make up to max_iter iterations
  for (var iter_count = 0; iter_count < params.max_iter; iter_count++) {
    var xlast = x;
    x = {};
    for (var node in xlast) x[node] = 0.0;
    var sum_ = 0.0;
    dangling_nodes.forEach(function(node) {
      sum_ += xlast[node]
    });
    var danglesum = params.alpha * sum_;

    for (var node in x) {
      // this matrix multiply looks odd because it is
      // doing a left multiply x^T=xlast^T*W
      for (var nbr in W[node]) {
        x[nbr] += params.alpha * xlast[node] * W[node][nbr]['weight'];
      }
      x[node] += danglesum * dangling_weights[node] + (1.0 - params.alpha) * p[node];
    }

    // check convergence, l1 norm
    var err = 0.0;
    Object.keys(x).forEach(function(node) {
      err += Math.abs(x[node] - xlast[node])
    });
    if (err < N*params.tol)
      return x;
  }

  console.warn('pagerank: power iteration failed to converge in ' +
               params.iter_max + ' iterations.');
  return x;
}

// node.js
//module.exports = pagerank;

// test
//var scores = pagerank({1: [2, 3, 4], 2: [3], 3: [4], 4: []}, {alpha: 0.9});
//console.log(scores);
//
//var scores = pagerank({'foo': ['bar', 'hoge'], 'bar': [], 'hoge': ['foo']});
//console.log(scores);
<|endoftext|>


<commit_before>// Creates html version of itself and wraps it inside html page tags and finally opens it in the browser

var peacock  =  require('..')
  , fs       =  require('fs')
  , exec     =  require('child_process').exec
  , code     =  fs.readFileSync(__filename, 'utf-8')
  , htmlFile =  './pageofself.html'
  ;

// Choose random style for kicks
/*
 *var styles =  nsh.getStyles()
 *  , index  =  Math.floor(Math.random() * styles.length)
 *  , style  =  styles[index]
 *  ;
 */

// Highlight code and generate html with style reference included

code = fs.readFileSync(__dirname + '/../../cardinal/cardinal.js', 'utf-8');
var highlightedCode = peacock.highlight(code, 'hide-semicolons');

if (3 <= 2 ) throw new Error('on no');
//console.log(highlightedCode);

var  html = [
        '<!DOCTYPE HTML>'
      , ''
      , ''
      , '   <meta http-equiv="content-type" content="text/html; charset=utf-8"/>'
      , '   <title>Page of Self</title>'
      , ' <link rel="stylesheet" href="styles/tango.css" type="text/css" media="screen" charset="utf-8" />'
      , ''
      , ''
      , highlightedCode
      , ''
      , '</html'
      ].join('\n');

// Copy style and write html
fs.writeFileSync(htmlFile, html);

exec('open ' + htmlFile);
<commit_msg>example updated<commit_after>// Creates html version of itself and wraps it inside html page tags and finally opens it in the browser

var peacock  =  require('..')
  , fs       =  require('fs')
  , path     =  require('path')
  , exec     =  require('child_process').exec
  , styles   =  path.join(__dirname, '..', 'styles')
  , code     =  fs.readFileSync(__filename, 'utf-8')
  , htmlFile =  './pageofself.html'
  ;

// Choose random style for kicks
/*
 *var styles =  nsh.getStyles()
 *  , index  =  Math.floor(Math.random() * styles.length)
 *  , style  =  styles[index]
 *  ;
 */

// Highlight code and generate html with style reference included

code = fs.readFileSync(__dirname + '/../../cardinal/cardinal.js', 'utf-8');
var highlightedCode = peacock.highlight(code, 'hide-semicolons');

if (3 <= 2 ) throw new Error('on no');
//console.log(highlightedCode);

var  html = [
        '<!DOCTYPE HTML>'
      , ''
      , ''
      , '   <meta http-equiv="content-type" content="text/html; charset=utf-8"/>'
      , '   <title>Page of Self</title>'
      , ' <link rel="stylesheet" href="' + styles + '/tango.css" type="text/css" media="screen" charset="utf-8" />'
      , ''
      , ''
      , highlightedCode
      , ''
      , '</html'
      ].join('\n');

// Copy style and write html
fs.writeFileSync(htmlFile, html);

exec('open ' + htmlFile);
<|endoftext|>


<commit_before>'use strict';

const auth = require('./auth');
const Couch = require('../..');
const couchMap = {};
const couchToProcess = ['key', 'startkey', 'endkey'];

exports.setupCouch = function*(next) {
    const dbname = this.params.dbname;
    this.state.userEmail = yield auth.getUserEmail(this);
    this.state.couch = getCouch(dbname);
    yield next;
};

exports.getDocumentByUuid = function*() {
    try {
        const doc = yield this.state.couch.getEntryByUuid(this.params.id, this.state.userEmail);
        this.status = 200;
        this.body = doc;
    } catch (e) {
        onGetError(this, e);
    }
};

exports.newEntry = function*() {
    const body = this.request.body;
    if (body) body._id = this.params.id;
    try {
        yield this.state.couch.insertEntry(this.request.body, this.state.userEmail);
        this.status = 200;
    } catch (e) {
        switch (e.reason) {
            case 'unauthorized':
                this.status = 401;
                this.body = 'unauthorized';
                break;
            default:
                this.status = 500;
                console.error(e);
                this.body = 'internal server error';
                break;
        }
    }
};

exports.getAttachmentById = function*() {
    try {
        console.log('get att by id')
        const entries = yield this.state.couch.getAttachmentByIdAndName(this.params.id, this.params.attachment, this.state.userEmail, true);
        this.status = 200;
        this.body = entries;
    } catch (e) {
        onGetError(this, e);
    }
};

exports.allEntries = function*() {
    try {
        const entries = yield this.state.couch.getEntriesByUserAndRights(this.state.userEmail, 'read');
        this.status = 200;
        this.body = entries;
    } catch (e) {
        console.log(e);
        onGetError(this, e);
    }
};

exports.queryViewByUser = function*() {
    try {
        processCouchQuery(this);
        this.body = yield this.state.couch.queryViewByUser(this.state.userEmail, this.params.view, this.query);
        this.status = 200;
    } catch (e) {
        onGetError(this, e);
    }
};

function getCouch(dbname) {
    if (!couchMap[dbname]) {
        couchMap[dbname] = new Couch({
            database: dbname
        });
    }
    return couchMap[dbname];
}

function onGetError(ctx, e) {
    switch (e.reason) {
        case 'not found':
        case 'unauthorized':
            ctx.status = 404;
            ctx.body = 'not found';
            break;
        default:
            ctx.status = 500;
            ctx.body = 'internal server error';
            console.error(e);
            break;
    }
}

function processCouchQuery(ctx) {
    for (let i = 0; i < couchToProcess.length; i++) {
        if (ctx.query[couchToProcess[i]]) {
            ctx.query[couchToProcess[i]] = JSON.parse(ctx.query[couchToProcess[i]])
        }
    }
}
<commit_msg>couch middleware: get database config from home dir<commit_after>'use strict';

const auth = require('./auth');
const Couch = require('../..');
const couchMap = {};
const couchToProcess = ['key', 'startkey', 'endkey'];
const dbconfig = require('../../util/dbconfig');

exports.setupCouch = function*(next) {
    const dbname = this.params.dbname;
    this.state.userEmail = yield auth.getUserEmail(this);
    this.state.couch = getCouch(dbname);
    yield next;
};

exports.getDocumentByUuid = function*() {
    try {
        const doc = yield this.state.couch.getEntryByUuid(this.params.id, this.state.userEmail);
        this.status = 200;
        this.body = doc;
    } catch (e) {
        onGetError(this, e);
    }
};

exports.newEntry = function*() {
    const body = this.request.body;
    if (body) body._id = this.params.id;
    try {
        yield this.state.couch.insertEntry(this.request.body, this.state.userEmail);
        this.status = 200;
    } catch (e) {
        switch (e.reason) {
            case 'unauthorized':
                this.status = 401;
                this.body = 'unauthorized';
                break;
            default:
                this.status = 500;
                console.error(e);
                this.body = 'internal server error';
                break;
        }
    }
};

exports.getAttachmentById = function*() {
    try {
        console.log('get att by id')
        const entries = yield this.state.couch.getAttachmentByIdAndName(this.params.id, this.params.attachment, this.state.userEmail, true);
        this.status = 200;
        this.body = entries;
    } catch (e) {
        onGetError(this, e);
    }
};

exports.allEntries = function*() {
    try {
        const entries = yield this.state.couch.getEntriesByUserAndRights(this.state.userEmail, 'read');
        this.status = 200;
        this.body = entries;
    } catch (e) {
        console.log(e);
        onGetError(this, e);
    }
};

exports.queryViewByUser = function*() {
    try {
        processCouchQuery(this);
        this.body = yield this.state.couch.queryViewByUser(this.state.userEmail, this.params.view, this.query);
        this.status = 200;
    } catch (e) {
        onGetError(this, e);
    }
};

function getCouch(dbname) {
    if (!couchMap[dbname]) {
        couchMap[dbname] = new Couch(dbconfig.database(dbname));
    }
    return couchMap[dbname];
}

function onGetError(ctx, e) {
    switch (e.reason) {
        case 'not found':
        case 'unauthorized':
            ctx.status = 404;
            ctx.body = 'not found';
            break;
        default:
            ctx.status = 500;
            ctx.body = 'internal server error';
            console.error(e);
            break;
    }
}

function processCouchQuery(ctx) {
    for (let i = 0; i < couchToProcess.length; i++) {
        if (ctx.query[couchToProcess[i]]) {
            ctx.query[couchToProcess[i]] = JSON.parse(ctx.query[couchToProcess[i]])
        }
    }
}
<|endoftext|>


<commit_before>let path = require('path');
let mergeWith = require('lodash').mergeWith;
let Paths = require('./Paths');
let File = require('./File');
let Manifest = require('./Manifest');
let Versioning = require('./Versioning');
let concatenate = require('concatenate');

class Mix {
    /**
     * Create a new Laravel Mix instance.
     */
    constructor() {
        this.File = File;
        this.Paths = new Paths;
        this.hmr = false;
        this.sourcemaps = false;
        this.notifications = true;
        this.cssPreprocessor = false;
        this.versioning = false;
        this.inProduction = process.env.NODE_ENV === 'production';
        this.publicPath = this.isUsingLaravel() ? 'public' : './';
    }

    /**
     * Initialize the user's webpack.mix.js configuration file.
     */
    initialize(rootPath = '') {
        // We'll first load the user's webpack.mix.js file.
        if (rootPath) this.Paths.setRootPath(rootPath);
        require(this.Paths.mix());

        if (this.versioning) {
            this.versioning = new Versioning(
                new Manifest(this.publicPath + '/manifest.json')
            )
        }

        this.detectHotReloading();
    }

    /**
     * Finalize the Webpack configuration.
     *
     * @param {object} webpackConfig
     */
    finalize(webpackConfig) {
        if (! this.webpackConfig) return;

        mergeWith(webpackConfig, this.webpackConfig,
            (objValue, srcValue) => {
                if (Array.isArray(objValue)) {
                    return objValue.concat(srcValue);
                }
            }
        );
    }

    /**
     * Determine the Webpack entry file(s).
     */
    entry() {
        // We'll build up an entry object that the webpack.config.js
        // file will want to see. It'll include all mix.js() calls.

        if (!this.js) {
            throw new Error(
                `Laravel Mix: You must call "mix.js()" once or more.`
            );
        }

        let entry = this.js.reduce((result, paths) => {
            result[paths.output.name] = paths.entry.map(src => src.path);

            return result;
        }, {});

        // Allow us to have multiple .sass() or .less() calls with each
        // chunk having it's own unique entry[chunk] name.
        if (this.cssPreprocessor) {
            let stylesheets = this[this.cssPreprocessor].reduce((result, paths) => {
                result[paths.output.name] = paths.src.path;

                return result;
            }, {});
            Object.keys(stylesheets).map(name => {
                entry[name] = stylesheets[name];
            });
        }

        return entry;
    }

    /**
     * Determine the Webpack output path.
     */
    output() {
        // We'll only apply a chunkhash in production, as it's a costly step.
        let filename = (this.inProduction && this.versioning) ? '[name].[chunkhash].js' : '[name].js';

        return {
            path: this.hmr ? '/' : this.publicPath,
            filename: path.join(this.js[0].output.base, filename).replace(this.publicPath, ''),
            publicPath: this.hmr ? 'http://localhost:8080/' : './'
        };
    }

    /**
     * Determine the appropriate CSS output path.
     *
     * @param {object} segments
     */
    cssOutput(segments) {
        let regex = new RegExp('^(\.\/)?' + this.publicPath);
        let path = (this.inProduction && this.versioning) ? 'hashedPath' : 'path';

        return segments.output[path].replace(regex, '');
    }

    /**
     * Minify the given files, or those from Mix.minify().
     *
     * @param {array|null} files
     */
    minifyAll(files = null) {
        if (! this.inProduction) return;

        files = files || this.minify || [];

        files.forEach(file => new File(file).minify());

        return this;
    }

    /**
     * Combine the given files, or those from Mix.combine().
     *
     * @param {array|null} files
     */
    concatenateAll(files = null) {
        files = files || this.combine || [];

        files.forEach(file => {
            concatenate.sync(file.src, file.output);

            if (! this.inProduction) return;

            new this.File(file.output).minify();
        });

        return this;
    }

    /**
     * Detect if the user desires hot reloading.
     */
    detectHotReloading() {
        let file = new this.File(this.publicPath + '/hot');

        file.delete();

        // If the user wants hot module replacement, we'll create
        // a temporary file, so that Laravel can detect it, and
        // reference the proper base URL for any assets.
        if (process.argv.includes('--hot')) {
            this.hmr = true;

            file.write('hot reloading enabled');
        } else {
            this.hmr = false;
        }
    }

    /**
     * Fetch the appropriate Babel config for babel-loader.
     */
    babelConfig() {
        let file = this.Paths.root('.babelrc');

        // If the user has defined their own .babelrc file,
        // the babel-loader will automatically fetch it.
        // Otherwise, we'll use these defaults.
        return this.File.exists(file) ? '?cacheDirectory' : '?' + JSON.stringify({
            'cacheDirectory': true,
            'presets': [
                ['es2015', { 'modules': false }]
            ]
        });
    }

    /**
     * Determine if we are working with a Laravel project.
     */
    isUsingLaravel() {
        return this.File.exists('./artisan');
    }
};

module.exports = new Mix;
<commit_msg>refactor: few necessary changes for testing purposes.<commit_after>let path = require('path');
let mergeWith = require('lodash').mergeWith;
let Paths = require('./Paths');
let File = require('./File');
let Manifest = require('./Manifest');
let Versioning = require('./Versioning');
let concatenate = require('concatenate');

class Mix {
    /**
     * Create a new Laravel Mix instance.
     */
    constructor() {
        this.File = File;
        this.Paths = new Paths;
        this.hmr = false;
        this.sourcemaps = false;
        this.notifications = true;
        this.cssPreprocessor = false;
        this.versioning = false;
        this.inProduction = process.env.NODE_ENV === 'production';
        this.publicPath = './';
    }

    /**
     * Initialize the user's webpack.mix.js configuration file.
     */
    initialize(rootPath = '') {
        // set public path here so we can test :)
        if (this.isUsingLaravel()) {
            this.publicPath = 'public';
        }
        // We'll first load the user's webpack.mix.js file.
        if (rootPath) this.Paths.setRootPath(rootPath);
        require(this.Paths.mix());

        if (this.versioning) {
            this.versioning = new Versioning(
                new Manifest(this.publicPath + '/manifest.json')
            )
        }

        this.detectHotReloading();
    }

    /**
     * Finalize the Webpack configuration.
     *
     * @param {object} webpackConfig
     */
    finalize(webpackConfig) {
        if (! this.webpackConfig) return;

        mergeWith(this.webpackConfig, webpackConfig,
            (objValue, srcValue) => {
                if (Array.isArray(objValue)) {
                    return objValue.concat(srcValue);
                }
            }
        );
    }

    /**
     * Determine the Webpack entry file(s).
     */
    entry() {
        // We'll build up an entry object that the webpack.config.js
        // file will want to see. It'll include all mix.js() calls.

        if (!this.js) {
            throw new Error(
                `Laravel Mix: You must call "mix.js()" once or more.`
            );
        }

        let entry = this.js.reduce((result, paths) => {
            result[paths.output.name] = paths.entry.map(src => src.path);

            return result;
        }, {});

        // Allow us to have multiple .sass() or .less() calls with each
        // chunk having it's own unique entry[chunk] name.
        if (this.cssPreprocessor) {
            let stylesheets = this[this.cssPreprocessor].reduce((result, paths) => {
                result[paths.output.name] = paths.src.path;

                return result;
            }, {});
            Object.keys(stylesheets).map(name => {
                entry[name] = stylesheets[name];
            });
        }

        return entry;
    }

    /**
     * Determine the Webpack output path.
     */
    output() {
        // We'll only apply a chunkhash in production, as it's a costly step.
        let filename = (this.inProduction && this.versioning) ? '[name].[chunkhash].js' : '[name].js';

        return {
            path: this.hmr ? '/' : this.publicPath,
            filename: path.join(this.js[0].output.base, filename).replace(this.publicPath, ''),
            publicPath: this.hmr ? 'http://localhost:8080/' : './'
        };
    }

    /**
     * Determine the appropriate CSS output path.
     *
     * @param {object} segments
     */
    cssOutput(segments) {
        let regex = new RegExp('^(\.\/)?' + this.publicPath);
        let path = (this.inProduction && this.versioning) ? 'hashedPath' : 'path';

        return segments.output[path].replace(regex, '');
    }

    /**
     * Minify the given files, or those from Mix.minify().
     *
     * @param {array|null} files
     */
    minifyAll(files = null) {
        if (! this.inProduction) return;

        files = files || this.minify || [];

        files.forEach(file => new File(file).minify());

        return this;
    }

    /**
     * Combine the given files, or those from Mix.combine().
     *
     * @param {array|null} files
     */
    concatenateAll(files = null) {
        files = files || this.combine || [];

        files.forEach(file => {
            concatenate.sync(file.src, file.output);

            if (! this.inProduction) return;

            new this.File(file.output).minify();
        });

        return this;
    }

    /**
     * Detect if the user desires hot reloading.
     */
    detectHotReloading(force = false) {
        let file = new this.File(this.publicPath + '/hot');

        file.delete();

        // If the user wants hot module replacement, we'll create
        // a temporary file, so that Laravel can detect it, and
        // reference the proper base URL for any assets.
        if (process.argv.includes('--hot') || force) {
            this.hmr = true;

            file.write('hot reloading enabled');
        } else {
            this.hmr = false;
        }
    }

    /**
     * Fetch the appropriate Babel config for babel-loader.
     */
    babelConfig() {
        let file = this.Paths.root('.babelrc');

        // If the user has defined their own .babelrc file,
        // the babel-loader will automatically fetch it.
        // Otherwise, we'll use these defaults.
        return this.File.exists(file) ? '?cacheDirectory' : '?' + JSON.stringify({
            'cacheDirectory': true,
            'presets': [
                ['es2015', { 'modules': false }]
            ]
        });
    }

    /**
     * Determine if we are working with a Laravel project.
     */
    isUsingLaravel() {
        return this.File.exists('./artisan');
    }
};

module.exports = new Mix;
<|endoftext|>


<commit_before>// Main connection to backend host
//

angular
	.module('app')
	.service('feathersService', [
		'$q',
	function ($q) {
		var self = this;
    self.hostUrl = '';
    self.socket = null;
    // start up socket.io host connection
    self.connect = function( hostUrl ){
      self.hostUrl = hostUrl;
      if( self.socket !== null ){
        return;
			}

      self.socket = io(hostUrl);
      self.app =
        feathers()
          .configure(feathers.hooks())
          .configure(feathers.socketio(self.socket))
          .configure(feathers.authentication({
            storage: window.localStorage}
          })
          ;

      // self.app.authenticate({
      //   type: 'token',
      //   endpoint: '/auth/google'
      // }).then( function(result){
      //   console.log(result);
      //   console.log('token='+self.app.get('token'));
      // }).catch(function(error){
      //   console.error('Error authenticating!', error);
      // });
    //  console.log(self.app);
    };

    self.service = function( name ){
      return self.app.service(name);
    };

    self.connected = function(){
      return self.socket !== null;
    };

    self.loginValid = function() {
      return self.app.get('token') !== undefined;
    };

    self.authenticate = function(){
      self.app.authenticate().then( function(result){
        console.log(result);
        console.log('token='+self.app.get('token'));
      }).catch(function(error){
        console.error('Error authenticating!', error);
      });
    };

		//if( process.env.NODE_ENV==='production')
		// TODO: data drive in some way. selectable?
    self.connect('http://hamexam.herokuapp.com');
    //self.connect('http://localhost:3030');
	}
]);
<commit_msg>Build fix<commit_after>// Main connection to backend host
//

angular
	.module('app')
	.service('feathersService', [
		'$q',
	function ($q) {
		var self = this;
    self.hostUrl = '';
    self.socket = null;
    // start up socket.io host connection
    self.connect = function( hostUrl ){
      self.hostUrl = hostUrl;
      if( self.socket !== null ){
        return;
			}

      self.socket = io(hostUrl);
      self.app =
        feathers()
          .configure(feathers.hooks())
          .configure(feathers.socketio(self.socket))
          .configure(feathers.authentication({
            storage: window.localStorage}
          })
          ;

      // self.app.authenticate({
      //   type: 'token',
      //   endpoint: '/auth/google'
      // }).then( function(result){
      //   console.log(result);
      //   console.log('token='+self.app.get('token'));
      // }).catch(function(error){
      //   console.error('Error authenticating!', error);
      // });
    //  console.log(self.app);
    };

    self.service = function( name ){
      return self.app.service(name);
    };

    self.connected = function(){
      return self.socket !== null;
    };

    self.loginValid = function() {
      return self.app.get('token') !== undefined;
    };

    self.authenticate = function(){
      self.app
          .authenticate()
          .then( function(result){
            console.log(result);
            console.log('token='+self.app.get('token'));
          }).catch(function(error){
            console.error('Error authenticating!', error);
          });
    };

		//if( process.env.NODE_ENV==='production')
		// TODO: data drive in some way. selectable?
    self.connect('http://hamexam.herokuapp.com');
    //self.connect('http://localhost:3030');
	}
]);
<|endoftext|>


<commit_before><commit_msg>FIO-4194: fixed submit button for PDF in FVP (#4899)<commit_after><|endoftext|>


<commit_before>import Cookies from 'js-cookie';

class PTT {
  constructor() {
    this._init = this._init.bind(this);

    this.ptt = {};
  }

  // initialize our object
  _init() {
    this.ptt = Cookies.getJSON( '_ptt' ) || {};
    console.log('cookies:');console.log(this.ptt);
  }

  // Set whole ptt object or
  // only an attribute by passing the key param.
  set( ptt, key ) {
    if ( this.ptt && key ) {

      this.ptt[ key ] = ptt;

    } else if ( ptt ) {

      for ( var i in ptt ) {
        this.ptt[ i ] = ptt[ i ];
      }

    }
  }

  // get an attribute set in this object
  // Notcie we do not retrieve from cookies
  // directly.
  get( key ) {
    if ( key && key in this.ptt ) {
      return this.ptt[ key ];
    } else {
      return false;
    }
  }

  // set the attributes of this object
  // as cookies in our browser.
  // called by DiscoverWpApi -> _maybeAuthenticated
  setCookies() {
    const _cookies = {
      authenticated: this.ptt.auth && this.ptt.auth.authenticated() ? true : false,
      creds: this.ptt.creds,
      site: {
        url: this.ptt.site.url,
        name: this.ptt.site.name,
        home: this.ptt.site.home,
        description: this.ptt.site.description,
      },
      user: this.ptt.user,
    };
    Cookies.set( '_ptt', _cookies );
    // console.log( 'Cookies set!' );
  }

  reset() {
    // Remove _ptt cookie, reset PTT.
    Cookies.remove('_ptt');

    // this._init();
  }
}

// Export new singleton class!
// http://stackoverflow.com/questions/33550380/react-flux-dispatcher-as-singleton-in-typescript#34377957
export default new PTT();
<commit_msg>updates to PTT<commit_after>import Cookies from 'js-cookie';

class PTT {
  constructor() {
    this._init = this._init.bind(this);

    this.ptt = {};
  }

  // initialize our object
  _init() {
    this.ptt = Cookies.getJSON( '_ptt' ) || {};
    console.log('cookies:');console.log(this.ptt);
  }

  /**
   * Set whole ptt object or only an attribute by passing the key param.
   *
   * @param {mixed}  value typically an object. can be a string or array if used with a key.
   * @param {string} key   name to use as the key for the parameter being added to ptt. if passed, the object ptt will not be overwritten.
   */
  set( value, key ) {
    if ( value && key ) {

      this.ptt[ key ] = value;

    }
    else if ( value ) {

      for ( var i in value ) {
        this.ptt[ i ] = value[ i ];
      }

    }
  }

  /**
   * get an attribute set in this object Notcie we do not retrieve from cookies directly.
   * sf
   * @param  {string} key name of param to get from ptt
   * @return {mixed}      false, or whatever value was found.
   */
  get( key ) {
    if ( ! key || 0 === key.length ) {
      return this.ptt;
    }
    else if ( key && key in this.ptt ) {
      return this.ptt[ key ];
    }
    else {
      return false;
    }
  }

  /**
   * set the attributes of this object as cookies in our browser.
   *
   * called by DiscoverWpApi -> _maybeAuthenticated
   *
   * Note: An additional property will be added to our object called 'auth'. This property is not part of the _cookies const; not all of the auth property could be saved as part of our cookies. So we save it to the active window.
   *
   * This is a single page, fully AJAX app anyways.
   */
  setCookies() {
    this._reset();
    const _cookies = {
      user          : this.ptt.user,
      current_timer : this.ptt.current_timer,
      site          : {
        url:         this.ptt.site.url,
        name:        this.ptt.site.name,
        home:        this.ptt.site.home,
        description: this.ptt.site.description,
      },
      creds         : this.ptt.creds,
    };
    Cookies.set( '_ptt', _cookies );
  }

  // Remove _ptt cookie
  _reset() {
    Cookies.remove('_ptt');
  }
}

// Export new singleton class!
// http://stackoverflow.com/questions/33550380/react-flux-dispatcher-as-singleton-in-typescript#34377957
export default new PTT();
<|endoftext|>


<commit_before>import stencilaJs from 'stencila-js'

import ComponentDelegate from '../component/ComponentDelegate'

/**
 * A session client for a local Javascript session
 *
 * This provides inteface compatability with other, remote, session types that
 * are accessed via `SessionClient` (in particular, returning a `Promise` from
 * a call to `execute`)
 */
class SessionClientJs extends ComponentDelegate {

  constructor () {
    super()
    this.impl = new stencilaJs.JsSession()
  }

  execute (code, inputs) {
    return Promise.resolve(this.impl.execute(
      code, inputs
    ))
  }

}

export default SessionClientJs
<commit_msg>Renaming<commit_after>import stencilaJs from 'stencila-js'

import ComponentDelegate from '../component/ComponentDelegate'

/**
 * A session client for a local Javascript session
 *
 * This provides inteface compatability with other, remote, session types that
 * are accessed via `SessionClient` (in particular, returning a `Promise` from
 * a call to `execute`)
 */
class SessionClientJs extends ComponentDelegate {

  constructor () {
    super()
    this.impl = new stencilaJs.JsContext()
  }

  execute (code, inputs) {
    return Promise.resolve(this.impl.execute(
      code, inputs
    ))
  }

}

export default SessionClientJs
<|endoftext|>


<commit_before>'use strict';

const Promise = require('bluebird');

/**
 * MessageManager for
 */
class MessaageManager {

  /**
   * Construct a message manager for sending and managing messages
   * @param {Genesis} bot bot containing necessary settings
   */
  constructor(bot) {
    this.client = bot.client;
    this.logger = bot.logger;
    this.settings = bot.settings;
    this.owner = bot.owner;

    /**
     * Zero space whitespace character to prepend to any messages sent
     * to prevent a command from inadvertantly being triggered.
     * @type {string}
     */
    this.zSWC = '\u200B';
  }

  /**
   * Send a message, with options to delete messages after calling
   * @param {Message} message original message being responded to
   * @param {string} content String to send to a channel
   * @param {boolean} deleteOriginal True to delete the original message
   * @param {boolean} deleteResponse True to delete the sent message after time
   */
  sendMessage(message, content, deleteOriginal, deleteResponse) {
    const promises = [];
    if ((message.channel.type === 'text' &&
        message.channel.permissionsFor(this.client.user.id).has('SEND_MESSAGES'))
        || message.channel.type === 'dm') {
      promises.push(message.channel.send(`${this.zSWC}${content}`).then((msg) => {
        this.deleteCallAndResponse(message, msg, deleteOriginal, deleteResponse);
      }));
    }
    Promise.each(promises, () => {}).catch(this.logger.error);
  }

  /**
   * Send a message, with options to delete messages after calling
   * @param {Message} message original message being responded to
   * @param {string} content String to send to a channel
   * @param {boolean} deleteOriginal True to delete the original message
   * @param {boolean} deleteResponse True to delete the sent message after time
   * @returns {null|Promise<Message>}
   */
  replyMessageRetPromise(message, content, deleteOriginal, deleteResponse) {
    if ((message.channel.type === 'text' &&
        message.channel.permissionsFor(this.client.user.id).has('SEND_MESSAGES'))
        || message.channel.type === 'dm') {
      return message.channel.send(`${this.zSWC}${content}`).then((msg) => {
        this.deleteCallAndResponse(message, msg, deleteOriginal, deleteResponse);
      });
    }
    return null;
  }

  /**
   * Send a message, with options to delete messages after calling
   * @param {Message} message original message being responded to
   * @param {string} content String to send to a channel
   * @param {boolean} deleteOriginal True to delete the original message
   * @param {boolean} deleteResponse True to delete the sent message after time
   */
  reply(message, content, deleteOriginal, deleteResponse) {
    const promises = [];
    if ((message.channel && message.channel.type === 'text' &&
        message.channel.permissionsFor(this.client.user.id).has('SEND_MESSAGES'))
        || message.channel.type === 'dm') {
      promises.push(message.reply(`${this.zSWC}${content}`).then((msg) => {
        this.deleteCallAndResponse(message, msg, deleteOriginal, deleteResponse);
      }));
    }
    Promise.each(promises, () => {}).catch(this.logger.error);
  }

  /**
   * Send an embed, with options to delete messages after calling
   * @param {Message} message original message being responded to
   * @param {Object} embed Embed object to send
   * @param {boolean} deleteOriginal True to delete the original message
   * @param {boolean} deleteResponse True to delete the sent message after time
   */
  embed(message, embed, deleteOriginal, deleteResponse) {
    const promises = [];
    if ((message.channel.type === 'text' &&
      message.channel.permissionsFor(this.client.user.id)
        .has(['SEND_MESSAGES', 'EMBED_LINKS']))
      || message.channel.type === 'dm') {
      promises.push(message.channel.send('', { embed }).then((msg) => {
        this.deleteCallAndResponse(message, msg, deleteOriginal, deleteResponse);
      }));
    }
    Promise.each(promises, () => {}).catch(this.logger.error);
  }

  /**
   * Send an embed
   * @param {Channel} channel channel to send message to
   * @param {Object} embed Embed object to send
   * @param {string} prepend String to prepend to the embed
   * @param {nunber} deleteAfter delete after a specified time
   * @returns {Promise<Message>}
   */
  embedToChannel(channel, embed, prepend, deleteAfter) {
    if (channel
      && ((channel.type === 'text'
      && channel.permissionsFor(this.client.user.id).has(['SEND_MESSAGES', 'EMBED_LINKS']))
      || channel.type === 'dm')) {
      return channel.send(prepend, { embed })
        .then((msg) => {
          if (msg.deletable && deleteAfter > 0) {
            this.settings.getChannelSetting(channel, 'deleteExpired')
              .then((deleteExpired) => {
                if (parseInt(deleteExpired, 10)) {
                  msg.delete(deleteAfter);
                }
              });
          }
        });
    }
    return null;
  }

  /**
   * Send a message, with options to delete messages after calling
   * @param {Message} message original message being responded to
   * @param {string} content String to send to a channel
   * @param {boolean} deleteResponse True to delete the sent message after time
   */
  sendDirectMessageToAuthor(message, content, deleteResponse) {
    const promises = [];
    promises.push(message.author.send(content).then((msg) => {
      this.deleteCallAndResponse(message, msg, false, deleteResponse);
    }));
    Promise.each(promises, () => {}).catch(this.logger.error);
  }

  /**
   * Send a message, with options to delete messages after calling
   * @param {TextChannel} user user being sent a message
   * @param {string} content String to send to a channel
   * @param {boolean} deleteResponse True to delete the sent message after time
   */
  sendDirectMessageToUser(user, content, deleteResponse) {
    const promises = [];
    promises.push(user.send(content).then((msg) => {
      this.deleteCallAndResponse(user, msg, false, deleteResponse);
    }));
    Promise.each(promises, () => {}).catch(this.logger.error);
  }

  /**
   * Send a message, with options to delete messages after calling
   * @param {Message} message original message being responded to
   * @param {Object} embed Embed object to send
   * @param {boolean} deleteResponse True to delete the sent message after time
   */
  sendDirectEmbedToAuthor(message, embed, deleteResponse) {
    const promises = [];
    promises.push(message.author.send('', { embed }).then((msg) => {
      this.deleteCallAndResponse(message, msg, false, deleteResponse);
    }));
    Promise.each(promises, () => {}).catch(this.logger.error);
  }

  sendDirectEmbedToOwner(embed) {
    this.client.users.get(this.owner).send('', { embed }).catch(this.logger.error);
  }

  sendFileToAuthor(message, file, fileName, deleteCall) {
    message.author.send('', { file: { attachment: file, name: fileName } })
      .then((msg) => {
        this.deleteCallAndResponse(message, msg, deleteCall, false);
      });
  }

  sendFile(message, prepend, file, fileName, deleteCall) {
    message.channel.send(prepend || '', { file: { attachment: file, name: fileName } })
      .then((msg) => {
        this.deleteCallAndResponse(message, msg, deleteCall, false);
      });
  }

  /**
   * Notify channel of settings change if enabled
   * @param {Message} message Message to reply to and fetch channel settings from
   * @param {boolean} deleteOriginal whether or not to delete the original message
   * @param {boolean} deleteResponse whether or not to delete the response message
   */
  notifySettingsChange(message, deleteOriginal, deleteResponse) {
    message.react('\u2705');
    this.settings.getChannelResponseToSettings(message.channel)
      .then((respondToSettings) => {
        if (respondToSettings === '1') {
          return message.reply('Settings updated')
            .then((msg) => {
              this.deleteCallAndResponse(message, msg, deleteOriginal, deleteResponse);
            });
        }
        return new Promise(resolve => resolve(true));
      })
      .catch(this.logger.error);
  }

  /**
   * Delete call and response for a command, depending on settings
   * @param  {Message} call           calling command
   * @param  {Message} response       response message
   * @param  {boolean} deleteCall     whether or not to delete the calling message
   * @param  {boolean} deleteResponse whether or not to delete the message response
   */
  deleteCallAndResponse(call, response, deleteCall, deleteResponse) {
    if (call.channel) {
      this.settings.getChannelDeleteAfterResponse(call.channel)
        .then((deleteAfterRespond) => {
          if (deleteAfterRespond === '1' && deleteCall && call.deletable) {
            call.delete(10000).catch(() => this.logger.error(`Couldn't delete ${call}`));
          }
          return this.settings.getChannelSetting(call.channel, 'delete_response');
        })
        .then((deleteResponseAfterRespond) => {
          if (deleteResponseAfterRespond === '1' && deleteResponse && response.deletable) {
            response.delete(10000).catch(() => this.logger.error(`Couldn't delete ${response}`));
          }
        })
        .catch(this.logger.error);
    }
  }

  webhook(webhookId, embed) {
    this.bot.client.fetchWebhook(webhookId).sendSlackMessage({
      username: this.bot.client.user.username,
      attachments: [embed],
    })
    .catch(this.logger.error);
  }
}

module.exports = MessaageManager;
<commit_msg>make response stay for 30 seconds instead of 10<commit_after>'use strict';

const Promise = require('bluebird');

/**
 * MessageManager for
 */
class MessaageManager {

  /**
   * Construct a message manager for sending and managing messages
   * @param {Genesis} bot bot containing necessary settings
   */
  constructor(bot) {
    this.client = bot.client;
    this.logger = bot.logger;
    this.settings = bot.settings;
    this.owner = bot.owner;

    /**
     * Zero space whitespace character to prepend to any messages sent
     * to prevent a command from inadvertantly being triggered.
     * @type {string}
     */
    this.zSWC = '\u200B';
  }

  /**
   * Send a message, with options to delete messages after calling
   * @param {Message} message original message being responded to
   * @param {string} content String to send to a channel
   * @param {boolean} deleteOriginal True to delete the original message
   * @param {boolean} deleteResponse True to delete the sent message after time
   */
  sendMessage(message, content, deleteOriginal, deleteResponse) {
    const promises = [];
    if ((message.channel.type === 'text' &&
        message.channel.permissionsFor(this.client.user.id).has('SEND_MESSAGES'))
        || message.channel.type === 'dm') {
      promises.push(message.channel.send(`${this.zSWC}${content}`).then((msg) => {
        this.deleteCallAndResponse(message, msg, deleteOriginal, deleteResponse);
      }));
    }
    Promise.each(promises, () => {}).catch(this.logger.error);
  }

  /**
   * Send a message, with options to delete messages after calling
   * @param {Message} message original message being responded to
   * @param {string} content String to send to a channel
   * @param {boolean} deleteOriginal True to delete the original message
   * @param {boolean} deleteResponse True to delete the sent message after time
   * @returns {null|Promise<Message>}
   */
  replyMessageRetPromise(message, content, deleteOriginal, deleteResponse) {
    if ((message.channel.type === 'text' &&
        message.channel.permissionsFor(this.client.user.id).has('SEND_MESSAGES'))
        || message.channel.type === 'dm') {
      return message.channel.send(`${this.zSWC}${content}`).then((msg) => {
        this.deleteCallAndResponse(message, msg, deleteOriginal, deleteResponse);
      });
    }
    return null;
  }

  /**
   * Send a message, with options to delete messages after calling
   * @param {Message} message original message being responded to
   * @param {string} content String to send to a channel
   * @param {boolean} deleteOriginal True to delete the original message
   * @param {boolean} deleteResponse True to delete the sent message after time
   */
  reply(message, content, deleteOriginal, deleteResponse) {
    const promises = [];
    if ((message.channel && message.channel.type === 'text' &&
        message.channel.permissionsFor(this.client.user.id).has('SEND_MESSAGES'))
        || message.channel.type === 'dm') {
      promises.push(message.reply(`${this.zSWC}${content}`).then((msg) => {
        this.deleteCallAndResponse(message, msg, deleteOriginal, deleteResponse);
      }));
    }
    Promise.each(promises, () => {}).catch(this.logger.error);
  }

  /**
   * Send an embed, with options to delete messages after calling
   * @param {Message} message original message being responded to
   * @param {Object} embed Embed object to send
   * @param {boolean} deleteOriginal True to delete the original message
   * @param {boolean} deleteResponse True to delete the sent message after time
   */
  embed(message, embed, deleteOriginal, deleteResponse) {
    const promises = [];
    if ((message.channel.type === 'text' &&
      message.channel.permissionsFor(this.client.user.id)
        .has(['SEND_MESSAGES', 'EMBED_LINKS']))
      || message.channel.type === 'dm') {
      promises.push(message.channel.send('', { embed }).then((msg) => {
        this.deleteCallAndResponse(message, msg, deleteOriginal, deleteResponse);
      }));
    }
    Promise.each(promises, () => {}).catch(this.logger.error);
  }

  /**
   * Send an embed
   * @param {Channel} channel channel to send message to
   * @param {Object} embed Embed object to send
   * @param {string} prepend String to prepend to the embed
   * @param {nunber} deleteAfter delete after a specified time
   * @returns {Promise<Message>}
   */
  embedToChannel(channel, embed, prepend, deleteAfter) {
    if (channel
      && ((channel.type === 'text'
      && channel.permissionsFor(this.client.user.id).has(['SEND_MESSAGES', 'EMBED_LINKS']))
      || channel.type === 'dm')) {
      return channel.send(prepend, { embed })
        .then((msg) => {
          if (msg.deletable && deleteAfter > 0) {
            this.settings.getChannelSetting(channel, 'deleteExpired')
              .then((deleteExpired) => {
                if (parseInt(deleteExpired, 10)) {
                  msg.delete(deleteAfter);
                }
              });
          }
        });
    }
    return null;
  }

  /**
   * Send a message, with options to delete messages after calling
   * @param {Message} message original message being responded to
   * @param {string} content String to send to a channel
   * @param {boolean} deleteResponse True to delete the sent message after time
   */
  sendDirectMessageToAuthor(message, content, deleteResponse) {
    const promises = [];
    promises.push(message.author.send(content).then((msg) => {
      this.deleteCallAndResponse(message, msg, false, deleteResponse);
    }));
    Promise.each(promises, () => {}).catch(this.logger.error);
  }

  /**
   * Send a message, with options to delete messages after calling
   * @param {TextChannel} user user being sent a message
   * @param {string} content String to send to a channel
   * @param {boolean} deleteResponse True to delete the sent message after time
   */
  sendDirectMessageToUser(user, content, deleteResponse) {
    const promises = [];
    promises.push(user.send(content).then((msg) => {
      this.deleteCallAndResponse(user, msg, false, deleteResponse);
    }));
    Promise.each(promises, () => {}).catch(this.logger.error);
  }

  /**
   * Send a message, with options to delete messages after calling
   * @param {Message} message original message being responded to
   * @param {Object} embed Embed object to send
   * @param {boolean} deleteResponse True to delete the sent message after time
   */
  sendDirectEmbedToAuthor(message, embed, deleteResponse) {
    const promises = [];
    promises.push(message.author.send('', { embed }).then((msg) => {
      this.deleteCallAndResponse(message, msg, false, deleteResponse);
    }));
    Promise.each(promises, () => {}).catch(this.logger.error);
  }

  sendDirectEmbedToOwner(embed) {
    this.client.users.get(this.owner).send('', { embed }).catch(this.logger.error);
  }

  sendFileToAuthor(message, file, fileName, deleteCall) {
    message.author.send('', { file: { attachment: file, name: fileName } })
      .then((msg) => {
        this.deleteCallAndResponse(message, msg, deleteCall, false);
      });
  }

  sendFile(message, prepend, file, fileName, deleteCall) {
    message.channel.send(prepend || '', { file: { attachment: file, name: fileName } })
      .then((msg) => {
        this.deleteCallAndResponse(message, msg, deleteCall, false);
      });
  }

  /**
   * Notify channel of settings change if enabled
   * @param {Message} message Message to reply to and fetch channel settings from
   * @param {boolean} deleteOriginal whether or not to delete the original message
   * @param {boolean} deleteResponse whether or not to delete the response message
   */
  notifySettingsChange(message, deleteOriginal, deleteResponse) {
    message.react('\u2705');
    this.settings.getChannelResponseToSettings(message.channel)
      .then((respondToSettings) => {
        if (respondToSettings === '1') {
          return message.reply('Settings updated')
            .then((msg) => {
              this.deleteCallAndResponse(message, msg, deleteOriginal, deleteResponse);
            });
        }
        return new Promise(resolve => resolve(true));
      })
      .catch(this.logger.error);
  }

  /**
   * Delete call and response for a command, depending on settings
   * @param  {Message} call           calling command
   * @param  {Message} response       response message
   * @param  {boolean} deleteCall     whether or not to delete the calling message
   * @param  {boolean} deleteResponse whether or not to delete the message response
   */
  deleteCallAndResponse(call, response, deleteCall, deleteResponse) {
    if (call.channel) {
      this.settings.getChannelDeleteAfterResponse(call.channel)
        .then((deleteAfterRespond) => {
          if (deleteAfterRespond === '1' && deleteCall && call.deletable) {
            call.delete(10000).catch(() => this.logger.error(`Couldn't delete ${call}`));
          }
          return this.settings.getChannelSetting(call.channel, 'delete_response');
        })
        .then((deleteResponseAfterRespond) => {
          if (deleteResponseAfterRespond === '1' && deleteResponse && response.deletable) {
            response.delete(30000).catch(() => this.logger.error(`Couldn't delete ${response}`));
          }
        })
        .catch(this.logger.error);
    }
  }

  webhook(webhookId, embed) {
    this.bot.client.fetchWebhook(webhookId).sendSlackMessage({
      username: this.bot.client.user.username,
      attachments: [embed],
    })
    .catch(this.logger.error);
  }
}

module.exports = MessaageManager;
<|endoftext|>