<commit_before>/**
 * @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
 * @fileoverview Shape module
 */
'use strict';

var Component = require('../interface/component');
var consts = require('../consts');

var util = tui.util;
var extend = util.extend;
var bind = util.bind;

var KEY_CODES = consts.keyCodes;
var SELECTION_STYLE = consts.fObjectOptions.SELECTION_STYLE;

/**
 * Shape
 * @class Shape
 * @param {Component} parent - parent component
 * @extends {Component}
 */
var Shape = tui.util.defineClass(Component, /** @lends Shape.prototype */{
    init: function(parent) {
        this.setParent(parent);

        /**
         * Object of current drawing shape
         * @type {fabric.Object}
         * @private
         */
        this._shapeObj = null;

        /**
         * Type for drawing shape
         * @type {string}
         * @private
         */
        this._type = 'rect';

        /**
         * Options for drawing shape
         * @type {object}
         * @private
         */
        this._options = {};

        /**
         * Whether drawing shpae is to be 1:1 ratio or not
         * @type {boolean}
         * @private
         */
        this._isRegularRatio = false;

        /**
         * Pointer for drawing shape (x, y)
         * @type {object}
         * @private
         */
        this._startPoint = {};

        /**
         * Using shortcut
         * @type {boolean}
         * @private
         */
        this._withShiftKey = false;

        /**
         * Event handler list
         * @type {object}
         * @private
         */
        this._handlers = {
            select: bind(this._onFabricSelect, this),
            deselect: bind(this._onFabricDeselect, this),
            mousedown: bind(this._onFabricMouseDown, this),
            mousemove: bind(this._onFabricMouseMove, this),
            mouseup: bind(this._onFabricMouseUp, this),
            keydown: bind(this._onKeyDown, this),
            keyup: bind(this._onKeyUp, this)
        };
    },

    /**
     * Component name
     * @type {string}
     */
    name: consts.componentNames.SHAPE,

    /**
     * Start drawing shape on canvas
     */
    start: function() {
        var canvas = this.getCanvas();

        canvas.defaultCursor = 'crosshair';
        canvas.on({
            'mouse:down': this._handlers.mousedown
        });

        fabric.util.addListener(document, 'keydown', this._handlers.keydown);
        fabric.util.addListener(document, 'keyup', this._handlers.keyup);
    },

    /**
     * End drawing shape on canvas
     */
    end: function() {
        var canvas = this.getCanvas();

        canvas.defaultCursor = 'default';
        canvas.off({
            'mouse:down': this._handlers.mousedown
        });

        fabric.util.removeListener(document, 'keydown', this._handlers.keydown);
        fabric.util.removeListener(document, 'keyup', this._handlers.keyup);
    },

    /**
     * Set states of current drawing shape
     * @param {string} type - Shape type (ex: 'rect', 'circle')
     * @param {object} [options] - Shape options
     *      @param {string} [options.fill] - Shape foreground color (ex: '#fff', 'transparent')
     *      @param {string} [options.stoke] - Shape outline color
     *      @param {number} [options.strokeWidth] - Shape outline width
     *      @param {number} [options.width] - Width value (When type option is 'rect', this options can use)
     *      @param {number} [options.height] - Height value (When type option is 'rect', this options can use)
     *      @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use)
     *      @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use)
     * @param {boolean} isRegularRatio - Whether drawing shape is to be 1:1 ratio or not
     */
    setStates: function(type, options, isRegularRatio) {
        this._type = type;

        if (options) {
            this._options = options;
        }

        if (isRegularRatio) {
            this._isRegularRatio = isRegularRatio;
        }
    },

    /**
     * Add shape
     * @param {string} type - Shape type (ex: 'rect', 'circle')
     * @param {object} options - Shape options
     *      @param {string} [options.fill] - Shape foreground color (ex: '#fff', 'transparent')
     *      @param {string} [options.stoke] - Shape outline color
     *      @param {number} [options.strokeWidth] - Shape outline width
     *      @param {number} [options.width] - Width value (When type option is 'rect', this options can use)
     *      @param {number} [options.height] - Height value (When type option is 'rect', this options can use)
     *      @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use)
     *      @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use)
     * @returns {fabric.Object} New shape object
     */
    add: function(type, options) {
        var canvas = this.getCanvas();
        var newShape;

        options = extend({}, SELECTION_STYLE, (options || this._options));

        this._setPosition(options);

        newShape = this._getShapeInstance(type, options);

        newShape.on({
            'selected': this._handlers.select,
            'deselected': this._handlers.deselect,
            'scaling': this._onFabricScaling
        });

        canvas.add(newShape);

        return newShape;
    },

    /**
     * Change shape
     * @param {fabric.Object} activeObj - Selected object on canvas
     * @param {object} options - Shape options
     *      @param {string} [options.fill] - Shape foreground color (ex: '#fff', 'transparent')
     *      @param {string} [options.stoke] - Shape outline color
     *      @param {number} [options.strokeWidth] - Shape outline width
     *      @param {number} [options.width] - Width value (When type option is 'rect', this options can use)
     *      @param {number} [options.height] - Height value (When type option is 'rect', this options can use)
     *      @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use)
     *      @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use)
     */
    change: function(activeObj, options) {
        activeObj.set(options);

        this.getCanvas().renderAll();
    },

    /**
     * Scaling object event handler on canvas
     * @private
     */
    _onFabricScaling: function() {
        var type = this.type;
        var scaleX = this.scaleX;
        var scaleY = this.scaleY;
        var options = {
            scaleX: 1,
            scaleY: 1
        };

        if (type === 'rect') {
            options = extend(options, {
                width: this.width * scaleX,
                height: this.height * scaleY
            });
        } else if (type === 'circle') {
            options = extend(options, {
                rx: this.rx * scaleX,
                ry: this.ry * scaleY
            });
        }

        this.set(options);
    },

    /**
     * Select object event handler on canvas
     * @private
     */
    _onFabricSelect: function() {
        this._isSelected = true;
    },

    /**
     * Deselect object event handler on canvas
     * @private
     */
    _onFabricDeselect: function() {
        this._isSelected = false;
    },

    /**
     * MouseDown event handler on canvas
     * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event
     * @private
     */
    _onFabricMouseDown: function(fEvent) {
        var canvas = this.getCanvas();
        var currentPointer = canvas.getPointer(fEvent.e);
        var shapeType = this._type;
        var options;

        if (!this._isSelected) {
            this._startPoint = currentPointer;

            options = this._getInitOptions(shapeType, currentPointer);

            this._shapeObj = this.add(shapeType, options);

            canvas.selection = false;
            canvas.on({
                'mouse:move': this._handlers.mousemove,
                'mouse:up': this._handlers.mouseup
            });
        }
    },

    /**
     * MouseDown event handler on canvas
     * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event
     * @private
     */
    _onFabricMouseMove: function(fEvent) {
        var canvas = this.getCanvas();
        var pointer = canvas.getPointer(fEvent.e);
        var shapeType = this._type;

        if (shapeType === 'rect') {
            this._setRectOptions(pointer);
        } else if (shapeType === 'circle') {
            this._setCircleOptions(pointer);
        }

        this._adjustOrigins(pointer);

        this._shapeObj.setCoords();

        canvas.renderAll();
    },

    /**
     * MouseUp event handler on canvas
     * @private
     */
    _onFabricMouseUp: function() {
        var canvas = this.getCanvas();

        this._adjustPosition(); // set origin position

        this._shapeObj = null;

        canvas.renderAll();
        canvas.off({
            'mouse:move': this._handlers.mousemove,
            'mouse:up': this._handlers.mouseup
        });
    },

    /**
     * Get options for drawing shape
     * @param {string} type - Shape type
     * @param {object} pointer - Current mouse pointer
     * @returns {object} Options
     * @private
     */
    _getInitOptions: function(type, pointer) {
        var initX = pointer.x - this._startPoint.x;
        var initY = pointer.y - this._startPoint.y;
        var options = extend({
            originX: 'left',
            originY: 'top',
            left: pointer.x,
            top: pointer.y
        }, this._options);

        if (type === 'rect') {
            options.width = initX;
            options.height = initY;
        } else if (type === 'circle') {
            options.rx = initX;
            options.ry = initY;
        }

        return options;
    },

    /**
     * Set circle options while drawing shape
     * @param {{x: number, y: number}} pointer - Current pointer
     * @private
     */
    _setCircleOptions: function(pointer) {
        var currentShape = this._shapeObj;
        var startPoint = this._startPoint;
        var radiusX = Math.abs(startPoint.x - pointer.x) / 2;
        var radiusY = Math.abs(startPoint.y - pointer.y) / 2;

        if (this._withShiftKey || this._isRegularRatio) {
            radiusX = radiusY = Math.max(radiusX, radiusY);
        }

        if (radiusX > currentShape.strokeWidth) {
            radiusX -= currentShape.strokeWidth / 2;
        }

        if (radiusY > currentShape.strokeWidth) {
            radiusY -= currentShape.strokeWidth / 2;
        }

        currentShape.set({
            rx: radiusX,
            ry: radiusY
        });
    },

    /**
     * Set rectangle options while drawing shape
     * @param {{x: number, y: number}} pointer - Current pointer
     * @private
     */
    _setRectOptions: function(pointer) {
        var currentShape = this._shapeObj;
        var startPoint = this._startPoint;
        var width = Math.abs(startPoint.x - pointer.x);
        var height = Math.abs(startPoint.y - pointer.y);

        if (this._withShiftKey || this._isRegularRatio) {
            width = height = Math.max(width, height);
        }

        if (width > currentShape.strokeWidth) {
            width -= currentShape.strokeWidth * 2;
        }

        if (height > currentShape.strokeWidth) {
            height -= currentShape.strokeWidth * 2;
        }

        currentShape.set({
            width: width,
            height: height
        });
    },

    /**
     * Adjust "originX" or "originY" value on shape
     * @param {{x: number, y: number}} pointer - Current pointer
     * @private
     */
    _adjustOrigins: function(pointer) {
        var currentShape = this._shapeObj;
        var startPoint = this._startPoint;

        if (startPoint.x > pointer.x) {
            currentShape.set({originX: 'right'});
        } else {
            currentShape.set({originX: 'left'});
        }

        if (startPoint.y > pointer.y) {
            currentShape.set({originY: 'bottom'});
        } else {
            currentShape.set({originY: 'top'});
        }
    },

    /**
     * Adjust position of shape
     * @private
     */
    _adjustPosition: function() {
        var currentShape = this._shapeObj;
        var originX = currentShape.getOriginX();
        var originY = currentShape.getOriginY();
        var currentPoint = currentShape.getPointByOrigin(originX, originY);
        var nextPoint = currentShape.getPointByOrigin('center', 'center');
        var left = nextPoint.x - currentPoint.x;
        var top = nextPoint.y - currentPoint.y;

        currentShape.set({
            originX: 'center',
            originY: 'center',
            left: currentShape.getLeft() + left,
            top: currentShape.getTop() + top
        });
    },

    /**
     * Get instance of creating shape
     * @param {string} type - Shape type
     * @param {object} options - Shape options
     * @returns {fabric.Object} Instance of shape
     * @private
     */
    _getShapeInstance: function(type, options) {
        var instance;

        if (type === 'rect') {
            instance = new fabric.Rect(options);
        } else if (type === 'circle') {
            instance = new fabric.Ellipse(extend({type: 'circle'}, options));
        }

        return instance;
    },

    /**
     * Set position of shape
     * @param {object} options - Shape
     * @private
     */
    _setPosition: function(options) {
        var centerPoint = this.getCanvas().getCenter();

        if (!options.left) {
            options.left = centerPoint.left;
        }

        if (!options.top) {
            options.top = centerPoint.top;
        }
    },

    /**
     * Keydown event handler on document
     * @param {KeyboardEvent} e - Event object
     * @private
     */
    _onKeyDown: function(e) {
        if (e.keyCode === KEY_CODES.SHIFT) {
            this._withShiftKey = true;
        }
    },

    /**
     * Keyup event handler on document
     * @param {KeyboardEvent} e - Event object
     * @private
     */
    _onKeyUp: function(e) {
        if (e.keyCode === KEY_CODES.SHIFT) {
            this._withShiftKey = false;
        }
    }
});

module.exports = Shape;
<commit_msg>feat: edit calculate width and height of rectangle<commit_after>/**
 * @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
 * @fileoverview Shape module
 */
'use strict';

var Component = require('../interface/component');
var consts = require('../consts');

var util = tui.util;
var extend = util.extend;
var bind = util.bind;

var KEY_CODES = consts.keyCodes;
var SELECTION_STYLE = consts.fObjectOptions.SELECTION_STYLE;

/**
 * Shape
 * @class Shape
 * @param {Component} parent - parent component
 * @extends {Component}
 */
var Shape = tui.util.defineClass(Component, /** @lends Shape.prototype */{
    init: function(parent) {
        this.setParent(parent);

        /**
         * Object of current drawing shape
         * @type {fabric.Object}
         * @private
         */
        this._shapeObj = null;

        /**
         * Type for drawing shape
         * @type {string}
         * @private
         */
        this._type = 'rect';

        /**
         * Options for drawing shape
         * @type {object}
         * @private
         */
        this._options = {};

        /**
         * Whether drawing shpae is to be 1:1 ratio or not
         * @type {boolean}
         * @private
         */
        this._isRegularRatio = false;

        /**
         * Pointer for drawing shape (x, y)
         * @type {object}
         * @private
         */
        this._startPoint = {};

        /**
         * Using shortcut
         * @type {boolean}
         * @private
         */
        this._withShiftKey = false;

        /**
         * Event handler list
         * @type {object}
         * @private
         */
        this._handlers = {
            select: bind(this._onFabricSelect, this),
            deselect: bind(this._onFabricDeselect, this),
            mousedown: bind(this._onFabricMouseDown, this),
            mousemove: bind(this._onFabricMouseMove, this),
            mouseup: bind(this._onFabricMouseUp, this),
            keydown: bind(this._onKeyDown, this),
            keyup: bind(this._onKeyUp, this)
        };
    },

    /**
     * Component name
     * @type {string}
     */
    name: consts.componentNames.SHAPE,

    /**
     * Start drawing shape on canvas
     */
    start: function() {
        var canvas = this.getCanvas();

        canvas.defaultCursor = 'crosshair';
        canvas.on({
            'mouse:down': this._handlers.mousedown
        });

        fabric.util.addListener(document, 'keydown', this._handlers.keydown);
        fabric.util.addListener(document, 'keyup', this._handlers.keyup);
    },

    /**
     * End drawing shape on canvas
     */
    end: function() {
        var canvas = this.getCanvas();

        canvas.defaultCursor = 'default';
        canvas.off({
            'mouse:down': this._handlers.mousedown
        });

        fabric.util.removeListener(document, 'keydown', this._handlers.keydown);
        fabric.util.removeListener(document, 'keyup', this._handlers.keyup);
    },

    /**
     * Set states of current drawing shape
     * @param {string} type - Shape type (ex: 'rect', 'circle')
     * @param {object} [options] - Shape options
     *      @param {string} [options.fill] - Shape foreground color (ex: '#fff', 'transparent')
     *      @param {string} [options.stoke] - Shape outline color
     *      @param {number} [options.strokeWidth] - Shape outline width
     *      @param {number} [options.width] - Width value (When type option is 'rect', this options can use)
     *      @param {number} [options.height] - Height value (When type option is 'rect', this options can use)
     *      @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use)
     *      @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use)
     * @param {boolean} isRegularRatio - Whether drawing shape is to be 1:1 ratio or not
     */
    setStates: function(type, options, isRegularRatio) {
        this._type = type;

        if (options) {
            this._options = options;
        }

        if (isRegularRatio) {
            this._isRegularRatio = isRegularRatio;
        }
    },

    /**
     * Add shape
     * @param {string} type - Shape type (ex: 'rect', 'circle')
     * @param {object} options - Shape options
     *      @param {string} [options.fill] - Shape foreground color (ex: '#fff', 'transparent')
     *      @param {string} [options.stoke] - Shape outline color
     *      @param {number} [options.strokeWidth] - Shape outline width
     *      @param {number} [options.width] - Width value (When type option is 'rect', this options can use)
     *      @param {number} [options.height] - Height value (When type option is 'rect', this options can use)
     *      @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use)
     *      @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use)
     * @returns {fabric.Object} New shape object
     */
    add: function(type, options) {
        var canvas = this.getCanvas();
        var newShape;

        options = extend({}, SELECTION_STYLE, (options || this._options));

        this._setPosition(options);

        newShape = this._getShapeInstance(type, options);

        newShape.on({
            'selected': this._handlers.select,
            'deselected': this._handlers.deselect,
            'scaling': this._onFabricScaling
        });

        canvas.add(newShape);

        return newShape;
    },

    /**
     * Change shape
     * @param {fabric.Object} activeObj - Selected object on canvas
     * @param {object} options - Shape options
     *      @param {string} [options.fill] - Shape foreground color (ex: '#fff', 'transparent')
     *      @param {string} [options.stoke] - Shape outline color
     *      @param {number} [options.strokeWidth] - Shape outline width
     *      @param {number} [options.width] - Width value (When type option is 'rect', this options can use)
     *      @param {number} [options.height] - Height value (When type option is 'rect', this options can use)
     *      @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use)
     *      @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use)
     */
    change: function(activeObj, options) {
        activeObj.set(options);

        this.getCanvas().renderAll();
    },

    /**
     * Scaling object event handler on canvas
     * @private
     */
    _onFabricScaling: function() {
        var type = this.type;
        var scaleX = this.scaleX;
        var scaleY = this.scaleY;
        var options = {
            scaleX: 1,
            scaleY: 1
        };

        if (type === 'rect') {
            options = extend(options, {
                width: this.width * scaleX,
                height: this.height * scaleY
            });
        } else if (type === 'circle') {
            options = extend(options, {
                rx: this.rx * scaleX,
                ry: this.ry * scaleY
            });
        }

        this.set(options);
    },

    /**
     * Select object event handler on canvas
     * @private
     */
    _onFabricSelect: function() {
        this._isSelected = true;
    },

    /**
     * Deselect object event handler on canvas
     * @private
     */
    _onFabricDeselect: function() {
        this._isSelected = false;
    },

    /**
     * MouseDown event handler on canvas
     * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event
     * @private
     */
    _onFabricMouseDown: function(fEvent) {
        var canvas = this.getCanvas();
        var currentPointer = canvas.getPointer(fEvent.e);
        var shapeType = this._type;
        var options;

        if (!this._isSelected) {
            this._startPoint = currentPointer;

            options = this._getInitOptions(shapeType, currentPointer);

            this._shapeObj = this.add(shapeType, options);

            canvas.selection = false;
            canvas.on({
                'mouse:move': this._handlers.mousemove,
                'mouse:up': this._handlers.mouseup
            });
        }
    },

    /**
     * MouseDown event handler on canvas
     * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event
     * @private
     */
    _onFabricMouseMove: function(fEvent) {
        var canvas = this.getCanvas();
        var pointer = canvas.getPointer(fEvent.e);
        var shapeType = this._type;

        if (shapeType === 'rect') {
            this._setRectOptions(pointer);
        } else if (shapeType === 'circle') {
            this._setCircleOptions(pointer);
        }

        this._adjustOrigins(pointer);

        this._shapeObj.setCoords();

        canvas.renderAll();
    },

    /**
     * MouseUp event handler on canvas
     * @private
     */
    _onFabricMouseUp: function() {
        var canvas = this.getCanvas();

        this._adjustPosition(); // set origin position

        this._shapeObj = null;

        canvas.renderAll();
        canvas.off({
            'mouse:move': this._handlers.mousemove,
            'mouse:up': this._handlers.mouseup
        });
    },

    /**
     * Get options for drawing shape
     * @param {string} type - Shape type
     * @param {object} pointer - Current mouse pointer
     * @returns {object} Options
     * @private
     */
    _getInitOptions: function(type, pointer) {
        var initX = pointer.x - this._startPoint.x;
        var initY = pointer.y - this._startPoint.y;
        var options = extend({
            originX: 'left',
            originY: 'top',
            left: pointer.x,
            top: pointer.y
        }, this._options);

        if (type === 'rect') {
            options.width = initX;
            options.height = initY;
        } else if (type === 'circle') {
            options.rx = initX;
            options.ry = initY;
        }

        return options;
    },

    /**
     * Set circle options while drawing shape
     * @param {{x: number, y: number}} pointer - Current pointer
     * @private
     */
    _setCircleOptions: function(pointer) {
        var currentShape = this._shapeObj;
        var startPoint = this._startPoint;
        var radiusX = Math.abs(startPoint.x - pointer.x) / 2;
        var radiusY = Math.abs(startPoint.y - pointer.y) / 2;

        if (this._withShiftKey || this._isRegularRatio) {
            radiusX = radiusY = Math.max(radiusX, radiusY);
        }

        if (radiusX > currentShape.strokeWidth) {
            radiusX -= currentShape.strokeWidth / 2;
        }

        if (radiusY > currentShape.strokeWidth) {
            radiusY -= currentShape.strokeWidth / 2;
        }

        currentShape.set({
            rx: radiusX,
            ry: radiusY
        });
    },

    /**
     * Set rectangle options while drawing shape
     * @param {{x: number, y: number}} pointer - Current pointer
     * @private
     */
    _setRectOptions: function(pointer) {
        var currentShape = this._shapeObj;
        var startPoint = this._startPoint;
        var width = Math.abs(startPoint.x - pointer.x);
        var height = Math.abs(startPoint.y - pointer.y);

        if (this._withShiftKey || this._isRegularRatio) {
            width = height = Math.max(width, height);
        }

        if (width > currentShape.strokeWidth) {
            width -= currentShape.strokeWidth;
        }

        if (height > currentShape.strokeWidth) {
            height -= currentShape.strokeWidth;
        }

        currentShape.set({
            width: width,
            height: height
        });
    },

    /**
     * Adjust "originX" or "originY" value on shape
     * @param {{x: number, y: number}} pointer - Current pointer
     * @private
     */
    _adjustOrigins: function(pointer) {
        var currentShape = this._shapeObj;
        var startPoint = this._startPoint;

        if (startPoint.x > pointer.x) {
            currentShape.set({originX: 'right'});
        } else {
            currentShape.set({originX: 'left'});
        }

        if (startPoint.y > pointer.y) {
            currentShape.set({originY: 'bottom'});
        } else {
            currentShape.set({originY: 'top'});
        }
    },

    /**
     * Adjust position of shape
     * @private
     */
    _adjustPosition: function() {
        var currentShape = this._shapeObj;
        var originX = currentShape.getOriginX();
        var originY = currentShape.getOriginY();
        var currentPoint = currentShape.getPointByOrigin(originX, originY);
        var nextPoint = currentShape.getPointByOrigin('center', 'center');
        var left = nextPoint.x - currentPoint.x;
        var top = nextPoint.y - currentPoint.y;

        currentShape.set({
            originX: 'center',
            originY: 'center',
            left: currentShape.getLeft() + left,
            top: currentShape.getTop() + top
        });
    },

    /**
     * Get instance of creating shape
     * @param {string} type - Shape type
     * @param {object} options - Shape options
     * @returns {fabric.Object} Instance of shape
     * @private
     */
    _getShapeInstance: function(type, options) {
        var instance;

        if (type === 'rect') {
            instance = new fabric.Rect(options);
        } else if (type === 'circle') {
            instance = new fabric.Ellipse(extend({type: 'circle'}, options));
        }

        return instance;
    },

    /**
     * Set position of shape
     * @param {object} options - Shape
     * @private
     */
    _setPosition: function(options) {
        var centerPoint = this.getCanvas().getCenter();

        if (!options.left) {
            options.left = centerPoint.left;
        }

        if (!options.top) {
            options.top = centerPoint.top;
        }
    },

    /**
     * Keydown event handler on document
     * @param {KeyboardEvent} e - Event object
     * @private
     */
    _onKeyDown: function(e) {
        if (e.keyCode === KEY_CODES.SHIFT) {
            this._withShiftKey = true;
        }
    },

    /**
     * Keyup event handler on document
     * @param {KeyboardEvent} e - Event object
     * @private
     */
    _onKeyUp: function(e) {
        if (e.keyCode === KEY_CODES.SHIFT) {
            this._withShiftKey = false;
        }
    }
});

module.exports = Shape;
<|endoftext|>


<commit_before>(function () {
    "use strict";

    angular.module("app.services").factory("stringCalculator", [stringCalculatorFactory]);

    function stringCalculatorFactory() {
        return new StringCalculator();
    }

    function StringCalculator() {
    }

    StringCalculator.prototype.add = function (numbers) {
        var DEFAULT_DELIMITER = ",",
            ESCAPED_NEWLINE_CHARACTER = "\\n",
            CUSTOM_DELIMITER_TRAILING_HEADER = "//",
            CUSTOM_DELIMITER_AND_NUMBERS_SEPARATOR = "\n",
            CUSTOM_DELIMITER_PATTERN_STRING = "\\[([^\\]]+)\\]",
            MAXIMUM_NUMBER_TO_ADD = 1000;

        if (numbers) {
            var parsedNumbers = parseNumbers(numbers);

            ensureNoNegatives(parsedNumbers);

            return calculateSum(parsedNumbers);
        }

        return 0;

        function parseNumbers(numbers) {
            var numbersInfo = analyzeNumbers(numbers);

            var rawNumbers = numbersInfo.rawNumberList.split(numbersInfo.delimiter);

            var parsedNumbers = rawNumbers.map(function (s) {
                return parseInt(s, 10);
            });

            var numbersUptoMaximum = parsedNumbers.filter(function (n) {
                return n <= MAXIMUM_NUMBER_TO_ADD;
            });

            return numbersUptoMaximum;
        }

        function analyzeNumbers(numbers) {
            var delimiter,
                rawNumbers;

            if (hasCustomDelimiterTrailingHeader(numbers)) {
                var delimiterHeaderAndNumbers = numbers.split(CUSTOM_DELIMITER_AND_NUMBERS_SEPARATOR);

                delimiter = extractCustomDelimiter(delimiterHeaderAndNumbers[0]);
                rawNumbers = delimiterHeaderAndNumbers[1];
            } else {
                delimiter = createDefaultDelimiterPattern();
                rawNumbers = numbers;
            }

            return {
                rawNumberList: rawNumbers,
                delimiter: delimiter
            };
        }

        function extractCustomDelimiter(customDelimiterHeader) {
            var rawCustomDelimiter = removeTrailingHeader(customDelimiterHeader);

            if (1 === rawCustomDelimiter.length) {
                return rawCustomDelimiter;
            }

            var delimiterMatches = rawCustomDelimiter.match(new RegExp(CUSTOM_DELIMITER_PATTERN_STRING, "g"));

            if (1 === delimiterMatches.length) {
                return unwrapSingleCustomDelimiter(rawCustomDelimiter, CUSTOM_DELIMITER_PATTERN_STRING);
            }

            return convertMultipleCustomDelimitersToRegularExpression(delimiterMatches, CUSTOM_DELIMITER_PATTERN_STRING);
        }

        function convertMultipleCustomDelimitersToRegularExpression(delimiterMatches, delimiterPatternString) {
            var delimiters = unwrapCustomDelimiters(delimiterMatches, delimiterPatternString);

            var escapedDelimiters = escapeDelimitersForRegularExpressions(delimiters);

            var combinedDelimiterPattern = escapedDelimiters.join("|");

            return new RegExp(combinedDelimiterPattern);
        }

        function escapeDelimitersForRegularExpressions(delimiters) {
            return delimiters.map(function (delimiter) {
                var delimiterCharacters = delimiter.split("");

                var escapedCharacters = delimiterCharacters.map(escapeForUseInRegularExpression);

                return escapedCharacters.join("");
            });
        }

        function escapeForUseInRegularExpression(s) {
            return "\\" + s;
        }

        function unwrapCustomDelimiters(rawDelimiters, customDelimiterPatternString) {
            return rawDelimiters.map(function (s) {
                return unwrapSingleCustomDelimiter(s, customDelimiterPatternString);
            });
        }

        function unwrapSingleCustomDelimiter(rawDelimiter, delimiterPatternString) {
            return rawDelimiter.match(new RegExp(delimiterPatternString))[1]
        }

        function removeTrailingHeader(customDelimiterHeader) {
            if (customDelimiterHeader.indexOf(CUSTOM_DELIMITER_TRAILING_HEADER) === 0) {
                return customDelimiterHeader.substring(CUSTOM_DELIMITER_TRAILING_HEADER.length);
            }

            return customDelimiterHeader;
        }

        function calculateSum(numberList) {
            return numberList.reduce(function (currentSum, currentNumber) {
                return currentSum + currentNumber;
            });
        }

        function createDefaultDelimiterPattern() {
            var delimiterPatternString = DEFAULT_DELIMITER + "|" + ESCAPED_NEWLINE_CHARACTER;

            return new RegExp(delimiterPatternString);
        }

        function ensureNoNegatives(numberList) {
            var negativeNumbers = numberList.filter(function (n) {
                return n < 0;
            });

            if (negativeNumbers.length) {
                throw new Error("Negatives not allowed: " + negativeNumbers.join(", "));
            }
        }

        function hasCustomDelimiterTrailingHeader(rawNumbers) {
            return rawNumbers.indexOf(CUSTOM_DELIMITER_TRAILING_HEADER) === 0;
        }
    };
}());<commit_msg>Separated parsing logic into a StringCalculatorParser helper class.<commit_after>(function () {
    "use strict";

    angular.module("app.services").factory("stringCalculator", [stringCalculatorFactory]);

    function stringCalculatorFactory() {
        return new StringCalculator();
    }

    function StringCalculator() {
    }

    StringCalculator.prototype.add = function (numbers) {
        if (numbers) {
            var numberStringParser = new StringCalculatorParser();

            var parsedNumbers = numberStringParser.parse(numbers);

            ensureNoNegatives(parsedNumbers);

            return calculateSum(parsedNumbers);
        }

        return 0;

        function ensureNoNegatives(numberList) {
            var negativeNumbers = numberList.filter(function (n) {
                return n < 0;
            });

            if (negativeNumbers.length) {
                throw new Error("Negatives not allowed: " + negativeNumbers.join(", "));
            }
        }

        function calculateSum(numberList) {
            return numberList.reduce(function (currentSum, currentNumber) {
                return currentSum + currentNumber;
            });
        }
    };

    function StringCalculatorParser() {
    }

    StringCalculatorParser.prototype.parse = function (numbers) {
        var DEFAULT_DELIMITER = ",",
            ESCAPED_NEWLINE_CHARACTER = "\\n",
            CUSTOM_DELIMITER_TRAILING_HEADER = "//",
            CUSTOM_DELIMITER_AND_NUMBERS_SEPARATOR = "\n",
            CUSTOM_DELIMITER_PATTERN_STRING = "\\[([^\\]]+)\\]",
            MAXIMUM_NUMBER_TO_ADD = 1000;

        return parseNumbers(numbers);

        function parseNumbers(numbers) {
            var numbersInfo = analyzeNumbers(numbers);

            var rawNumbers = numbersInfo.rawNumberList.split(numbersInfo.delimiter);

            var parsedNumbers = rawNumbers.map(function (s) {
                return parseInt(s, 10);
            });

            var numbersUptoMaximum = parsedNumbers.filter(function (n) {
                return n <= MAXIMUM_NUMBER_TO_ADD;
            });

            return numbersUptoMaximum;
        }

        function analyzeNumbers(numbers) {
            var delimiter,
                rawNumbers;

            if (hasCustomDelimiterTrailingHeader(numbers)) {
                var delimiterHeaderAndNumbers = numbers.split(CUSTOM_DELIMITER_AND_NUMBERS_SEPARATOR);

                delimiter = extractCustomDelimiter(delimiterHeaderAndNumbers[0]);
                rawNumbers = delimiterHeaderAndNumbers[1];
            } else {
                delimiter = createDefaultDelimiterPattern();
                rawNumbers = numbers;
            }

            return {
                rawNumberList: rawNumbers,
                delimiter: delimiter
            };
        }

        function extractCustomDelimiter(customDelimiterHeader) {
            var rawCustomDelimiter = removeTrailingHeader(customDelimiterHeader);

            if (1 === rawCustomDelimiter.length) {
                return rawCustomDelimiter;
            }

            var delimiterMatches = rawCustomDelimiter.match(new RegExp(CUSTOM_DELIMITER_PATTERN_STRING, "g"));

            if (1 === delimiterMatches.length) {
                return unwrapSingleCustomDelimiter(rawCustomDelimiter, CUSTOM_DELIMITER_PATTERN_STRING);
            }

            return convertMultipleCustomDelimitersToRegularExpression(delimiterMatches, CUSTOM_DELIMITER_PATTERN_STRING);
        }

        function convertMultipleCustomDelimitersToRegularExpression(delimiterMatches, delimiterPatternString) {
            var delimiters = unwrapCustomDelimiters(delimiterMatches, delimiterPatternString);

            var escapedDelimiters = escapeDelimitersForRegularExpressions(delimiters);

            var combinedDelimiterPattern = escapedDelimiters.join("|");

            return new RegExp(combinedDelimiterPattern);
        }

        function escapeDelimitersForRegularExpressions(delimiters) {
            return delimiters.map(function (delimiter) {
                var delimiterCharacters = delimiter.split("");

                var escapedCharacters = delimiterCharacters.map(escapeForUseInRegularExpression);

                return escapedCharacters.join("");
            });
        }

        function escapeForUseInRegularExpression(s) {
            return "\\" + s;
        }

        function unwrapCustomDelimiters(rawDelimiters, customDelimiterPatternString) {
            return rawDelimiters.map(function (s) {
                return unwrapSingleCustomDelimiter(s, customDelimiterPatternString);
            });
        }

        function unwrapSingleCustomDelimiter(rawDelimiter, delimiterPatternString) {
            return rawDelimiter.match(new RegExp(delimiterPatternString))[1]
        }

        function removeTrailingHeader(customDelimiterHeader) {
            if (customDelimiterHeader.indexOf(CUSTOM_DELIMITER_TRAILING_HEADER) === 0) {
                return customDelimiterHeader.substring(CUSTOM_DELIMITER_TRAILING_HEADER.length);
            }

            return customDelimiterHeader;
        }

        function createDefaultDelimiterPattern() {
            var delimiterPatternString = DEFAULT_DELIMITER + "|" + ESCAPED_NEWLINE_CHARACTER;

            return new RegExp(delimiterPatternString);
        }

        function hasCustomDelimiterTrailingHeader(rawNumbers) {
            return rawNumbers.indexOf(CUSTOM_DELIMITER_TRAILING_HEADER) === 0;
        }
    };
}());<|endoftext|>


<commit_before>(function () {
    "use strict";

    angular.module("app.services").factory("stringCalculator", [stringCalculatorFactory]);

    var DEFAULT_DELIMITER = ",",
        ESCAPED_NEWLINE_CHARACTER = "\\n",
        CUSTOM_DELIMITER_TRAILING_HEADER = "//",
        CUSTOM_DELIMITER_AND_NUMBERS_SEPARATOR = "\n",
        MAXIMUM_NUMBER_TO_ADD = 1000;

    function stringCalculatorFactory() {
        return {
            add: add
        };
    }

    function add(numbers) {
        if (numbers) {
            var parsedNumbers = parseNumbers(numbers);

            ensureNoNegatives(parsedNumbers);

            return calculateSum(parsedNumbers);
        }

        return 0;
    }

    function parseNumbers(numbers) {
        var numbersInfo = analyzeNumbers(numbers);

        var rawNumbers = numbersInfo.rawNumberList.split(numbersInfo.delimiter);

        var parsedNumbers = rawNumbers.map(function (s) {
            return parseInt(s, 10);
        });

        var numbersUptoMaximum = parsedNumbers.filter(function (n) {
            return n <= MAXIMUM_NUMBER_TO_ADD;
        });

        return numbersUptoMaximum;
    }

    function analyzeNumbers(numbers) {
        var delimiter,
            rawNumbers;

        if (hasCustomDelimiterTrailingHeader(numbers)) {
            var delimiterHeaderAndNumbers = numbers.split(CUSTOM_DELIMITER_AND_NUMBERS_SEPARATOR);

            delimiter = extractCustomDelimiter(delimiterHeaderAndNumbers[0]);
            rawNumbers = delimiterHeaderAndNumbers[1];
        } else {
            delimiter = createDefaultDelimiterPattern();
            rawNumbers = numbers;
        }

        return {
            rawNumberList: rawNumbers,
            delimiter: delimiter
        };
    }

    function extractCustomDelimiter(customDelimiterHeader) {
        customDelimiterHeader = removeTrailingHeader(customDelimiterHeader);

        var customDelimiterPatternString = "\\[([^\\]]+)\\]";

        var delimiterMatches = customDelimiterHeader.match(new RegExp(customDelimiterPatternString, "g"));

        if (null === delimiterMatches) {
            return customDelimiterHeader;
        } else if (customDelimiterHeader === "[@][**][$$$]") {
            return new RegExp("\\@|\\*\\*|\\$\\$\\$");
        } else if (delimiterMatches.length > 1) {
            var delimiters = delimiterMatches.map(function (s) {
                return extractCustomDelimiterWithPattern(s, customDelimiterPatternString);
            });

            var escapedDelimiters = delimiters.map(function (s) {
                return "\\" + s;
            });

            var combinedDelimiterPattern = escapedDelimiters.join("|");

            return new RegExp(combinedDelimiterPattern);
        }

        return extractCustomDelimiterWithPattern(customDelimiterHeader, customDelimiterPatternString);
    }

    function extractCustomDelimiterWithPattern(rawDelimiter, delimiterPatternString) {
        return rawDelimiter.match(new RegExp(delimiterPatternString))[1]
    }

    function removeTrailingHeader(customDelimiterHeader) {
        if (customDelimiterHeader.indexOf(CUSTOM_DELIMITER_TRAILING_HEADER) === 0) {
            return customDelimiterHeader.substring(CUSTOM_DELIMITER_TRAILING_HEADER.length);
        }

        return customDelimiterHeader;
    }

    function calculateSum(numberList) {
        var sum = 0;

        numberList.forEach(function (n) {
            sum += n;
        });

        return sum;
    }

    function createDefaultDelimiterPattern() {
        var delimiterPatternString = DEFAULT_DELIMITER + "|" + ESCAPED_NEWLINE_CHARACTER;

        return new RegExp(delimiterPatternString);
    }

    function ensureNoNegatives(numberList) {
        var negativeNumbers = numberList.filter(function (n) {
            return n < 0;
        });

        if (negativeNumbers.length) {
            throw new Error("Negatives not allowed: " + negativeNumbers.join(", "));
        }
    }

    function hasCustomDelimiterTrailingHeader(rawNumbers) {
        return rawNumbers.indexOf(CUSTOM_DELIMITER_TRAILING_HEADER) === 0;
    }
})();<commit_msg>Added support for any number of custom delimiters of any length.<commit_after>(function () {
    "use strict";

    angular.module("app.services").factory("stringCalculator", [stringCalculatorFactory]);

    var DEFAULT_DELIMITER = ",",
        ESCAPED_NEWLINE_CHARACTER = "\\n",
        CUSTOM_DELIMITER_TRAILING_HEADER = "//",
        CUSTOM_DELIMITER_AND_NUMBERS_SEPARATOR = "\n",
        MAXIMUM_NUMBER_TO_ADD = 1000;

    function stringCalculatorFactory() {
        return {
            add: add
        };
    }

    function add(numbers) {
        if (numbers) {
            var parsedNumbers = parseNumbers(numbers);

            ensureNoNegatives(parsedNumbers);

            return calculateSum(parsedNumbers);
        }

        return 0;
    }

    function parseNumbers(numbers) {
        var numbersInfo = analyzeNumbers(numbers);

        var rawNumbers = numbersInfo.rawNumberList.split(numbersInfo.delimiter);

        var parsedNumbers = rawNumbers.map(function (s) {
            return parseInt(s, 10);
        });

        var numbersUptoMaximum = parsedNumbers.filter(function (n) {
            return n <= MAXIMUM_NUMBER_TO_ADD;
        });

        return numbersUptoMaximum;
    }

    function analyzeNumbers(numbers) {
        var delimiter,
            rawNumbers;

        if (hasCustomDelimiterTrailingHeader(numbers)) {
            var delimiterHeaderAndNumbers = numbers.split(CUSTOM_DELIMITER_AND_NUMBERS_SEPARATOR);

            delimiter = extractCustomDelimiter(delimiterHeaderAndNumbers[0]);
            rawNumbers = delimiterHeaderAndNumbers[1];
        } else {
            delimiter = createDefaultDelimiterPattern();
            rawNumbers = numbers;
        }

        return {
            rawNumberList: rawNumbers,
            delimiter: delimiter
        };
    }

    function extractCustomDelimiter(customDelimiterHeader) {
        customDelimiterHeader = removeTrailingHeader(customDelimiterHeader);

        var customDelimiterPatternString = "\\[([^\\]]+)\\]";

        var delimiterMatches = customDelimiterHeader.match(new RegExp(customDelimiterPatternString, "g"));

        if (null === delimiterMatches) {
            return customDelimiterHeader;
        } else if (delimiterMatches.length > 1) {
            var delimiters = separateCustomDelimiters(delimiterMatches, customDelimiterPatternString);

            var escapedDelimiters = escapeDelimitersForRegularExpressions(delimiters);

            var combinedDelimiterPattern = escapedDelimiters.join("|");

            return new RegExp(combinedDelimiterPattern);
        }

        return extractCustomDelimiterWithPattern(customDelimiterHeader, customDelimiterPatternString);
    }

    function escapeDelimitersForRegularExpressions(delimiters) {
        return delimiters.map(function (delimiter) {
            var delimiterCharacters = delimiter.split("");

            var escapedCharacters = delimiterCharacters.map(escapeForUseInRegularExpression);

            return escapedCharacters.join("");
        });
    }

    function escapeForUseInRegularExpression(s) {
        return "\\" + s;
    }

    function separateCustomDelimiters(rawDelimiters, customDelimiterPatternString) {
        return rawDelimiters.map(function (s) {
            return extractCustomDelimiterWithPattern(s, customDelimiterPatternString);
        });
    }

    function extractCustomDelimiterWithPattern(rawDelimiter, delimiterPatternString) {
        return rawDelimiter.match(new RegExp(delimiterPatternString))[1]
    }

    function removeTrailingHeader(customDelimiterHeader) {
        if (customDelimiterHeader.indexOf(CUSTOM_DELIMITER_TRAILING_HEADER) === 0) {
            return customDelimiterHeader.substring(CUSTOM_DELIMITER_TRAILING_HEADER.length);
        }

        return customDelimiterHeader;
    }

    function calculateSum(numberList) {
        var sum = 0;

        numberList.forEach(function (n) {
            sum += n;
        });

        return sum;
    }

    function createDefaultDelimiterPattern() {
        var delimiterPatternString = DEFAULT_DELIMITER + "|" + ESCAPED_NEWLINE_CHARACTER;

        return new RegExp(delimiterPatternString);
    }

    function ensureNoNegatives(numberList) {
        var negativeNumbers = numberList.filter(function (n) {
            return n < 0;
        });

        if (negativeNumbers.length) {
            throw new Error("Negatives not allowed: " + negativeNumbers.join(", "));
        }
    }

    function hasCustomDelimiterTrailingHeader(rawNumbers) {
        return rawNumbers.indexOf(CUSTOM_DELIMITER_TRAILING_HEADER) === 0;
    }
})();<|endoftext|>


<commit_before>/* ========================================================================
 * DOM-based Routing
 * Based on http://goo.gl/EUTi53 by Paul Irish
 *
 * Only fires on body classes that match. If a body class contains a dash,
 * replace the dash with an underscore when adding it to the object below.
 *
 * .noConflict()
 * The routing is enclosed within an anonymous function so that you can
 * always reference jQuery with $, even when in .noConflict() mode.
 * ======================================================================== */

(function($) {

  // Use this variable to set up the common and page specific functions. If you
  // rename this variable, you will also need to rename the namespace below.
  var Sage = {
    // All pages
    'common': {
      init: function() {
        // JavaScript to be fired on all pages
      },
      finalize: function() {
        // JavaScript to be fired on all pages, after page specific JS is fired
      }
    },
    // Home page
    'home': {
      init: function() {
        $('.brand-form-submit').click(function(event) {
          $('#gform_submit_button_3').click();
        });

      },
      finalize: function() {
        // JavaScript to be fired on the home page, after the init JS
      }
    },
    'single_product':{
      init:function(){
        $('.tabella-attributi .reset_variations').click(function(event) {
  event.preventDefault();
  $('.tabella-attributi select').val('').change();
  $('.variations_form.cart').trigger('reset_data');
});
        $('.tabella-attributi select').change(function(e){
          var val = $(this).val();
          var id = e.target.id;
          $('.buy-container #'+id).val(val).change();
        });
        $("form.cart").on("change", "input.qty", function() {
    if (this.value === "0")
        this.value = "1";

    $(this.form).find(".single_add_to_cart_button[data-quantity]").data("quantity", this.value);
});
        $(document.body).on("added_to_cart", function() {
          var val=Number($('.wcmenucart-text>.cart-length').text());

    $("a.added_to_cart").remove();
});
      }
    },
    'um_page_account':{
      init:function(){
        if($('.gform_wrapper').length){
        $('.gfield.hidden').hide();

        var max_rows=$('.gfield_list_group').first().find('option').length;

        gform.addFilter( 'gform_list_item_pre_add', function ( clone ) {

            clone.find('.datepicker').removeClass('hasDatepicker').removeAttr('id');
            set_max_rows(clone.find('.gfield_list_icons img'));
            return clone;
        });

        function set_max_rows(buttons){

          if(buttons){
            buttons.first().attr('onclick',"gformAddListItem(this, "+max_rows+")");
            buttons.first().attr('onkeypress',"gformAddListItem(this, "+max_rows+")");
            buttons.last().attr('onclick',"gformDeleteListItem(this, "+max_rows+")");
            buttons.last().attr('onkeypress',"gformDeleteListItem(this, "+max_rows+")");
          }
        }

        $('.gfield_list_icons').each(function(index, el) {

              var buttons = $(el).children('img');
              set_max_rows(buttons);
        });

        function disable_option(){
          var rows=$('.gfield_list_group');
          var options=rows.find('option');
          var selected=[];
          var disabled=[];

          rows.each(function(index, el) {
            var val =$(this).find('select').val();
            if(val)selected.push(val);
          });

          options.each(function(index) {
            if($(this).attr('disabled')==='disabled') disabled.push($(this).val());
          });

          options.each(function(index, el) {
            if(selected.indexOf($(el).val())!==-1 && $(el).parent().val() !== $(el).val()){
              $(el).attr('disabled','disabled');
            }else if( disabled.indexOf($(el).val())!==-1 ){
              $(el).attr('disabled',null);
            }
          });
        }

        disable_option();

        $('.ginput_list').on('click','.gfield_list_icons img',function(event) { disable_option(); });
        $('.ginput_list').on('focus','.datepicker',function(e){ gformInitDatepicker(); })
        $('.ginput_list').on('change focus mousedown keydown touchstart','.gfield_list_group select',function(event) { disable_option(); });
      }
      }
    },
    // About us page, note the change from about-us to about_us.
    'about_us': {
      init: function() {
        // JavaScript to be fired on the about us page
      }
    }
  };

  // The routing fires all common scripts, followed by the page specific scripts.
  // Add additional events for more control over timing e.g. a finalize event
  var UTIL = {
    fire: function(func, funcname, args) {
      var fire;
      var namespace = Sage;
      funcname = (funcname === undefined) ? 'init' : funcname;
      fire = func !== '';
      fire = fire && namespace[func];
      fire = fire && typeof namespace[func][funcname] === 'function';

      if (fire) {
        namespace[func][funcname](args);
      }
    },
    loadEvents: function() {
      // Fire common init JS
      UTIL.fire('common');

      // Fire page-specific init JS, and then finalize JS
      $.each(document.body.className.replace(/-/g, '_').split(/\s+/), function(i, classnm) {
        UTIL.fire(classnm);
        UTIL.fire(classnm, 'finalize');
      });

      // Fire common finalize JS
      UTIL.fire('common', 'finalize');
    }
  };

  // Load Events
  $(document).ready(UTIL.loadEvents);

})(jQuery); // Fully reference jQuery after this point.
<commit_msg>Ordini produttori form ajax<commit_after>/* ========================================================================
 * DOM-based Routing
 * Based on http://goo.gl/EUTi53 by Paul Irish
 *
 * Only fires on body classes that match. If a body class contains a dash,
 * replace the dash with an underscore when adding it to the object below.
 *
 * .noConflict()
 * The routing is enclosed within an anonymous function so that you can
 * always reference jQuery with $, even when in .noConflict() mode.
 * ======================================================================== */

(function($) {

  // Use this variable to set up the common and page specific functions. If you
  // rename this variable, you will also need to rename the namespace below.
  var Sage = {
    // All pages
    'common': {
      init: function() {
        // JavaScript to be fired on all pages
      },
      finalize: function() {
        // JavaScript to be fired on all pages, after page specific JS is fired
      }
    },
    // Home page
    'home': {
      init: function() {
        $('.brand-form-submit').click(function(event) {
          $('#gform_submit_button_3').click();
        });

      },
      finalize: function() {
        // JavaScript to be fired on the home page, after the init JS
      }
    },
    'single_product':{
      init:function(){
        $('.tabella-attributi .reset_variations').click(function(event) {
  event.preventDefault();
  $('.tabella-attributi select').val('').change();
  $('.variations_form.cart').trigger('reset_data');
});
        $('.tabella-attributi select').change(function(e){
          var val = $(this).val();
          var id = e.target.id;
          $('.buy-container #'+id).val(val).change();
        });
        $("form.cart").on("change", "input.qty", function() {
    if (this.value === "0")
        this.value = "1";

    $(this.form).find(".single_add_to_cart_button[data-quantity]").data("quantity", this.value);
});
        $(document.body).on("added_to_cart", function() {
          var val=Number($('.wcmenucart-text>.cart-length').text());

    $("a.added_to_cart").remove();
});
      }
    },
    'um_page_account':{
      init:function(){

        $('.um-account-main #gform_submit_button_6').on('click', function (event) {
          event.preventDefault();
          $('#gform_6 .gform_fields').replaceWith($('.um-account-main .gform_fields').clone())
          $('#gform_6').submit();
        });
        $('#gform_6').on('submit', function (event) {
            $('.gforms_confirmation_message').remove();
        })

        if($('.gform_wrapper').length){
        $('.gfield.hidden').hide();

        var max_rows=$('.gfield_list_group').first().find('option').length;

        gform.addFilter( 'gform_list_item_pre_add', function ( clone ) {

            clone.find('.datepicker').removeClass('hasDatepicker').removeAttr('id');
            set_max_rows(clone.find('.gfield_list_icons img'));
            return clone;
        });

        function set_max_rows(buttons){

          if(buttons){
            buttons.first().attr('onclick',"gformAddListItem(this, "+max_rows+")");
            buttons.first().attr('onkeypress',"gformAddListItem(this, "+max_rows+")");
            buttons.last().attr('onclick',"gformDeleteListItem(this, "+max_rows+")");
            buttons.last().attr('onkeypress',"gformDeleteListItem(this, "+max_rows+")");
          }
        }

        $('.gfield_list_icons').each(function(index, el) {

              var buttons = $(el).children('img');
              set_max_rows(buttons);
        });

        function disable_option(){
          var rows=$('.um-account-tab .gfield_list_group');
          var options=rows.find('option');
          var selected=[];
          var disabled=[];

          rows.each(function(index, el) {
            var val =$(this).find('select').val();
            if(val)selected.push(val);
          });

          options.each(function(index) {
            if($(this).attr('disabled')==='disabled') disabled.push($(this).val());
          });

          options.each(function(index, el) {
            if(selected.indexOf($(el).val())!==-1 && $(el).parent().val() !== $(el).val()){
              $(el).attr('disabled','disabled');
            }else if( disabled.indexOf($(el).val())!==-1 ){
              $(el).attr('disabled',null);
            }
          });
        }

        disable_option();

        $('.ginput_list').on('click','.gfield_list_icons img',function(event) { disable_option(); });
        $('.ginput_list').on('focus','.datepicker',function(e){ gformInitDatepicker(); })
        $('.ginput_list').on('change focus mousedown keydown touchstart','.gfield_list_group select',function(event) { disable_option(); });
      }
      }
    },
    // About us page, note the change from about-us to about_us.
    'about_us': {
      init: function() {
        // JavaScript to be fired on the about us page
      }
    }
  };

  // The routing fires all common scripts, followed by the page specific scripts.
  // Add additional events for more control over timing e.g. a finalize event
  var UTIL = {
    fire: function(func, funcname, args) {
      var fire;
      var namespace = Sage;
      funcname = (funcname === undefined) ? 'init' : funcname;
      fire = func !== '';
      fire = fire && namespace[func];
      fire = fire && typeof namespace[func][funcname] === 'function';

      if (fire) {
        namespace[func][funcname](args);
      }
    },
    loadEvents: function() {
      // Fire common init JS
      UTIL.fire('common');

      // Fire page-specific init JS, and then finalize JS
      $.each(document.body.className.replace(/-/g, '_').split(/\s+/), function(i, classnm) {
        UTIL.fire(classnm);
        UTIL.fire(classnm, 'finalize');
      });

      // Fire common finalize JS
      UTIL.fire('common', 'finalize');
    }
  };

  // Load Events
  $(document).ready(UTIL.loadEvents);

})(jQuery); // Fully reference jQuery after this point.
<|endoftext|>


<commit_before>import Reload from './data-reload';

export default Reload.extend({
	object: null,
	//@override
	shallReload: true,
	/*
		this service starts working with the application. Look "instance-initializer/service-start" for more information
	*/
	//@override
	updateObject(){
		const self = this;

		if(this.get('previousRequestDone')) {
			this.set('previousRequestDone', false);
			this.debug("start request");
			var timestampstorage = this.get("store").queryRecord('timestampstorage', '1');
			timestampstorage.then(success, failure).catch(error);
		}

		//----------------------------- Start of inner functions of updateObject------------------------------------------
		function success(timestampstorage){
			const timestamps = timestampstorage.get('timestamps');
			const sortedTimestamps = timestamps.sortBy('timestamp');
			// define outside loop in case of error
			var timestampList = [];
			var timestampListFormatted = [];
			var callList = [];

			// Parse and format timestamps for timeline
			if (sortedTimestamps) {
				sortedTimestamps.forEach(function(timestamp) {
				const timestampValue = timestamp.get('timestamp');
				timestampList.push(timestampValue);

				const callValue = timestamp.get('calls');
				callList.push(callValue);

				const parsedTimestampValue = moment(timestampValue,"x");
				const timestampValueFormatted = parsedTimestampValue.format("HH:mm:ss").toString();
				timestampListFormatted.push(timestampValueFormatted);
				});
			}

			// maximum number of timestamps displayed in chart at one time
			const maxNumOfChartTimestamps = 30;

			// TODO: error handling (no data etc)

			// Container for charts (limited size)
			var chartTimestamps = [];
			var chartCalls = [];
			const timestampListFormattedSize = timestampListFormatted.length;

			// limit size of displayed data points and labels
			if (timestampListFormattedSize > maxNumOfChartTimestamps) {
				chartTimestamps = timestampListFormatted.slice(timestampListFormattedSize-maxNumOfChartTimestamps,timestampListFormattedSize);
				chartCalls = callList.slice(timestampListFormattedSize-maxNumOfChartTimestamps,timestampListFormattedSize);
			}
			else {
				chartTimestamps = timestampListFormatted;
				chartCalls = callList;
			}

			// get maximum amount of call for scaling the chart
			const maxCalls = Math.max.apply(null, chartCalls);
			const chartData = {
				labels: chartTimestamps,
				values: chartCalls,
				maxValue: maxCalls
			};

			//This will set the object
			self.set("object", chartData);
			self.debug("end request");
			self.set('previousRequestDone', true);
		}

		function failure(){
			self.set('previousRequestDone', true);
			console.log("Timestamps couldn`t be requested");
		}

		function error(e){
			self.set('previousRequestDone', true);
			console.log(e);
		}

		//-------------------------------------------------end of inner functions of getData--------------------------------

	},

	//@override
	reloadObject(timestamp){
		const self = this;
		var timestampstorage = this.get("store").queryRecord('timestampstorage', timestamp);
			timestampstorage.then(success, failure).catch(error);

		function success(timestampStorage){
			console.log(timestampStorage.serialize());
			console.log("success");
		}

		function failure(){
			console.log("Timestamps couldn`t be requested");
		}

		function error(e){
			console.log(e);
		}
	}

});
<commit_msg>Reloaden vorerst gestoppt<commit_after>import Reload from './data-reload';

export default Reload.extend({
	object: null,
	//@override
	//shallReload: true,
	/*
		this service starts working with the application. Look "instance-initializer/service-start" for more information
	*/
	//@override
	updateObject(){
		const self = this;

		if(this.get('previousRequestDone')) {
			this.set('previousRequestDone', false);
			this.debug("start request");
			var timestampstorage = this.get("store").queryRecord('timestampstorage', '1');
			timestampstorage.then(success, failure).catch(error);
		}

		//----------------------------- Start of inner functions of updateObject------------------------------------------
		function success(timestampstorage){
			const timestamps = timestampstorage.get('timestamps');
			const sortedTimestamps = timestamps.sortBy('timestamp');
			// define outside loop in case of error
			var timestampList = [];
			var timestampListFormatted = [];
			var callList = [];

			// Parse and format timestamps for timeline
			if (sortedTimestamps) {
				sortedTimestamps.forEach(function(timestamp) {
				const timestampValue = timestamp.get('timestamp');
				timestampList.push(timestampValue);

				const callValue = timestamp.get('calls');
				callList.push(callValue);

				const parsedTimestampValue = moment(timestampValue,"x");
				const timestampValueFormatted = parsedTimestampValue.format("HH:mm:ss").toString();
				timestampListFormatted.push(timestampValueFormatted);
				});
			}

			// maximum number of timestamps displayed in chart at one time
			const maxNumOfChartTimestamps = 30;

			// TODO: error handling (no data etc)

			// Container for charts (limited size)
			var chartTimestamps = [];
			var chartCalls = [];
			const timestampListFormattedSize = timestampListFormatted.length;

			// limit size of displayed data points and labels
			if (timestampListFormattedSize > maxNumOfChartTimestamps) {
				chartTimestamps = timestampListFormatted.slice(timestampListFormattedSize-maxNumOfChartTimestamps,timestampListFormattedSize);
				chartCalls = callList.slice(timestampListFormattedSize-maxNumOfChartTimestamps,timestampListFormattedSize);
			}
			else {
				chartTimestamps = timestampListFormatted;
				chartCalls = callList;
			}

			// get maximum amount of call for scaling the chart
			const maxCalls = Math.max.apply(null, chartCalls);
			const chartData = {
				labels: chartTimestamps,
				values: chartCalls,
				maxValue: maxCalls
			};

			//This will set the object
			self.set("object", chartData);
			self.debug("end request");
			self.set('previousRequestDone', true);
		}

		function failure(){
			self.set('previousRequestDone', true);
			console.log("Timestamps couldn`t be requested");
		}

		function error(e){
			self.set('previousRequestDone', true);
			console.log(e);
		}

		//-------------------------------------------------end of inner functions of getData--------------------------------

	},

	//@override
	reloadObject(timestamp){
		const self = this;
		var timestampstorage = this.get("store").queryRecord('timestampstorage', timestamp);
			timestampstorage.then(success, failure).catch(error);

		function success(timestampStorage){
			console.log(timestampStorage.serialize());
			console.log("success");
		}

		function failure(){
			console.log("Timestamps couldn`t be requested");
		}

		function error(e){
			console.log(e);
		}
	}

});
<|endoftext|>


<commit_before>/**
 * Plugin to handle the site's drag&drop (top/left/right/bottom) toolbar
 */
(function ($, document, window) {
    var
    defaults = {
        position: 'top'
    },
    fwtoolbar = 'fwtoolbar',
    positions = ['top','bottom','left','right'],
    settings,
    element,
    $boxes = []
    ;

    function makeDraggable(el) {
        $(el)
        .draggable({ revert: "invalid", cancel: "li", cursorAt: {top: 30, left: 30} });

        var position = defaults.position;

        // get position from user/session
        ajax.genericAction('preference_get', {
                key: 'toolbar_pos'
            },
            function(val){
                if (val) {
                    position = val;
                }
                publicMethod.reposition($(el), position, false);
            },
            function(msg){
                error(msg);
                publicMethod.reposition($(el), position, false);
            },
            'get'
        );
    };

    // ****************
    // PUBLIC FUNCTIONS
    // ****************

    publicMethod = $.fn[fwtoolbar] = $[fwtoolbar] = function (options) {
        var $this = this;

        options = options || {};

        publicMethod.init();

        if (!$this[0]) {
            // if no selector was given, or no element matches the selector, exit
            return $this;
        }

        element = $this[0];

        $this.each(function () {
            $.data(this, fwtoolbar, $.extend({}, $.data(this, fwtoolbar) || defaults, options));
            makeDraggable(this);
        });

        return $this;
    };

    publicMethod.reposition = function (bar, position, save) {
        bar.removeClass(positions.join(' ') + ' ui-draggable-dragging')
        .removeAttr('style')
        .addClass(position);

        // class for padding to avoid hiding content under the toolbar, etc
        var frame = $('#main-content-frame');
        frame
        .removeClass(positions.join(' '))
        .addClass(position);

        // save settings to user/session
        if (typeof save == 'undefined') save = true;

        if (save) {
            ajax.genericAction('preference_set', {
                    key: 'toolbar_pos',
                    value: position
                },
                function(){},
                function(msg){
                    error(msg);
                }
            );
        }
    };

    // Initialize toolbar
    publicMethod.init = function () {
        if (!$boxes.length) {

            // If the body is not present yet, wait for DOM ready
            if (!$('body')[0]) {
                $(publicMethod.init);
                return;
            }

            // append global drop targets
            $.each(positions, function(){
                var droptarget = $('<div>')
                    .addClass('toolbardrop ' + this)
                    .attr('data-position', this)
                    // make target droppable
                    .droppable({
                        activeClass: "drop-hover",
                        hoverClass: "drop-active",
                        drop: function( event, ui ) {
                            var bar = ui.draggable;
                            var position = $(this).attr('data-position');

                            publicMethod.reposition(bar, position);
                        }
                    });

                $boxes.push(droptarget);
                $('body').append(droptarget);
            });

        }
    };

    publicMethod.settings = defaults;

    // Setup FWToolbar
    publicMethod.init();

    $(function(){
        $('[data-fwtoolbar]').fwtoolbar();
    });
}( jQuery, document, this ));<commit_msg>- Fix toolbar style en drag stop<commit_after>/**
 * Plugin to handle the site's drag&drop (top/left/right/bottom) toolbar
 */
(function ($, document, window) {
    var
    defaults = {
        position: 'top'
    },
    fwtoolbar = 'fwtoolbar',
    positions = ['top','bottom','left','right'],
    settings,
    element,
    $boxes = []
    ;

    function makeDraggable(el) {
        $(el)
        .draggable({
            revert: "invalid",
            cancel: "li",
            cursorAt: {top: 30, left: 30},
            stop: function( event, ui ) {
                $(this).removeAttr('style');
            }
        });

        var position = defaults.position;

        // get position from user/session
        ajax.genericAction('preference_get', {
                key: 'toolbar_pos'
            },
            function(val){
                if (val) {
                    position = val;
                }
                publicMethod.reposition($(el), position, false);
            },
            function(msg){
                error(msg);
                publicMethod.reposition($(el), position, false);
            },
            'get'
        );
    };

    // ****************
    // PUBLIC FUNCTIONS
    // ****************

    publicMethod = $.fn[fwtoolbar] = $[fwtoolbar] = function (options) {
        var $this = this;

        options = options || {};

        publicMethod.init();

        if (!$this[0]) {
            // if no selector was given, or no element matches the selector, exit
            return $this;
        }

        element = $this[0];

        $this.each(function () {
            $.data(this, fwtoolbar, $.extend({}, $.data(this, fwtoolbar) || defaults, options));
            makeDraggable(this);
        });

        return $this;
    };

    publicMethod.reposition = function (bar, position, save) {
        bar.removeClass(positions.join(' ') + ' ui-draggable-dragging')
        .removeAttr('style')
        .addClass(position);

        // class for padding to avoid hiding content under the toolbar, etc
        var frame = $('#main-content-frame');
        frame
        .removeClass(positions.join(' '))
        .addClass(position);

        // save settings to user/session
        if (typeof save == 'undefined') save = true;

        if (save) {
            ajax.genericAction('preference_set', {
                    key: 'toolbar_pos',
                    value: position
                },
                function(){},
                function(msg){
                    error(msg);
                }
            );
        }
    };

    // Initialize toolbar
    publicMethod.init = function () {
        if (!$boxes.length) {

            // If the body is not present yet, wait for DOM ready
            if (!$('body')[0]) {
                $(publicMethod.init);
                return;
            }

            // append global drop targets
            $.each(positions, function(){
                var droptarget = $('<div>')
                    .addClass('toolbardrop ' + this)
                    .attr('data-position', this)
                    // make target droppable
                    .droppable({
                        activeClass: "drop-hover",
                        hoverClass: "drop-active",
                        drop: function( event, ui ) {
                            var bar = ui.draggable;
                            var position = $(this).attr('data-position');

                            publicMethod.reposition(bar, position);
                        }
                    });

                $boxes.push(droptarget);
                $('body').append(droptarget);
            });

        }
    };

    publicMethod.settings = defaults;

    // Setup FWToolbar
    publicMethod.init();

    $(function(){
        $('[data-fwtoolbar]').fwtoolbar();
    });
}( jQuery, document, this ));<|endoftext|>


<commit_before>(function () {
  var ns = $.namespace('pskl.utils');

  var stopPropagation = function (e) {
    e.stopPropagation();
  };

  ns.FileUtils = {
    readFile : function (file, callback) {
      var reader = new FileReader();
      reader.onload = function (event) {
        callback(event.target.result);
      };
      reader.readAsDataURL(file);
    },

    readImageFile : function (file, callback) {
      ns.FileUtils.readFile(file, function (content) {
        var image = new Image();
        image.onload = callback.bind(null, image);
        image.src = content;
      });
    },

    downloadAsFile : function (content, filename) {
      var saveAs = window.saveAs || (navigator.msSaveBlob && navigator.msSaveBlob.bind(navigator));
      if (saveAs) {
        saveAs(content, filename);
      } else {
        var downloadLink = document.createElement('a');
        content = window.URL.createObjectURL(content);
        downloadLink.setAttribute('href', content);
        downloadLink.setAttribute('download', filename);
        document.body.appendChild(downloadLink);
        downloadLink.addEventListener('click', stopPropagation);
        downloadLink.click();
        downloadLink.removeEventListener('click', stopPropagation);
        document.body.removeChild(downloadLink);
      }
    }

  };
})();
<commit_msg>Add function for reading file as array buffer<commit_after>(function () {
  var ns = $.namespace('pskl.utils');

  var stopPropagation = function (e) {
    e.stopPropagation();
  };

  ns.FileUtils = {
    readFile : function (file, callback) {
      var reader = new FileReader();
      reader.onload = function (event) {
        callback(event.target.result);
      };
      reader.readAsDataURL(file);
    },

    readFileAsArrayBuffer : function (file, callback) {
      var reader = new FileReader();
      reader.addEventListener("loadend", function() {
        callback(reader.result);
      });
      reader.readAsArrayBuffer(file);
    },

    readImageFile : function (file, callback) {
      ns.FileUtils.readFile(file, function (content) {
        var image = new Image();
        image.onload = callback.bind(null, image);
        image.src = content;
      });
    },

    downloadAsFile : function (content, filename) {
      var saveAs = window.saveAs || (navigator.msSaveBlob && navigator.msSaveBlob.bind(navigator));
      if (saveAs) {
        saveAs(content, filename);
      } else {
        var downloadLink = document.createElement('a');
        content = window.URL.createObjectURL(new Blob([content]));
        downloadLink.setAttribute('href', content);
        downloadLink.setAttribute('download', filename);
        document.body.appendChild(downloadLink);
        downloadLink.addEventListener('click', stopPropagation);
        downloadLink.click();
        downloadLink.removeEventListener('click', stopPropagation);
        document.body.removeChild(downloadLink);
      }
    }

  };
})();
<|endoftext|>


<commit_before>import fetch from 'isomorphic-fetch'
import Remotes from './../util/remotes'
import { extractJson } from './../util/fetch'
import { getToken } from './../util/token'

export const projectActions = {
    CREATE_PROJECT: 'CREATE_PROJECT',
    CREATE_PROJECT_PENDING: 'CREATE_PROJECT_PENDING',
    CREATE_PROJECT_REJECTED: 'CREATE_PROJECT_REJECTED',
    CREATE_PROJECT_FULFILLED: 'CREATE_PROJECT_FULFILLED',

    FETCH_PROJECT: 'FETCH_PROJECT',
    FETCH_PROJECT_PENDING: 'FETCH_PROJECT_PENDING',
    FETCH_PROJECT_REJECTED: 'FETCH_PROJECT_REJECTED',
    FETCH_PROJECT_FULFILLED: 'FETCH_PROJECT_FULFILLED',

    FETCH_PROJECTS: 'FETCH_PROJECTS',
    FETCH_PROJECTS_PENDING: 'FETCH_PROJECTS_PENDING',
    FETCH_PROJECTS_REJECTED: 'FETCH_PROJECTS_REJECTED',
    FETCH_PROJECTS_FULFILLED: 'FETCH_PROJECTS_FULFILLED',

    fetchProjects: (user) => {
        return (dispatch) => {
            dispatch({type: projectActions.FETCH_PROJECTS_PENDING})
            return fetch(Remotes.projectsPath(), {
                method: 'GET',
                headers: {
                    "Accept": 'application/json',
                    "Authorization": getToken()
                }
            })
                .then(res => extractJson(res))
                .then(json => {
                    return dispatch({type: projectActions.FETCH_PROJECTS_FULFILLED, payload: json})
                })
                .catch(err => {
                    return dispatch({type: projectActions.FETCH_PROJECTS_REJECTED, payload: err})
                });
        };
    },

    fetchProject: (id) => {
        return (dispatch) => {
            dispatch({type: projectActions.FETCH_PROJECT_PENDING})
            return fetch(Remotes.projectPath(id), {
                method: 'GET',
                headers: {
                    "Accept": 'application/json',
                    "Authorization": getToken()
                }
            })
                .then(res => extractJson(res))
                .then(json => {
                    return dispatch({type: projectActions.FETCH_PROJECT_FULFILLED, payload: json})
                })
                .catch(err => {
                    return dispatch({type: projectActions.FETCH_PROJECT_REJECTED, payload: err})
                });
        };
    },

    createProject: (project) => {
        return (dispatch) => {
            dispatch({type: projectActions.CREATE_PROJECT_PENDING})
            return fetch(Remotes.projectsPath(), {
                method: 'POST',
                headers: {
                    "Accept": 'application/json',
                    "Authorization": getToken()
                },
                body: JSON.stringify(project)
            })
                .then(res => {
                    if (!res.ok) {
                        throw new Error('request failed');
                    }
                    return extractJson(res);
                })
                .then(json => {
                    console.log(json)
                    return dispatch({type: projectActions.CREATE_PROJECT_FULFILLED, payload: json})
                })
                .catch(err => {
                    return dispatch({type: projectActions.CREATE_PROJECT_REJECTED, payload: err})
                });
        };
    }
};
<commit_msg>Remove debug log<commit_after>import fetch from 'isomorphic-fetch'
import Remotes from './../util/remotes'
import { extractJson } from './../util/fetch'
import { getToken } from './../util/token'

export const projectActions = {
    CREATE_PROJECT: 'CREATE_PROJECT',
    CREATE_PROJECT_PENDING: 'CREATE_PROJECT_PENDING',
    CREATE_PROJECT_REJECTED: 'CREATE_PROJECT_REJECTED',
    CREATE_PROJECT_FULFILLED: 'CREATE_PROJECT_FULFILLED',

    FETCH_PROJECT: 'FETCH_PROJECT',
    FETCH_PROJECT_PENDING: 'FETCH_PROJECT_PENDING',
    FETCH_PROJECT_REJECTED: 'FETCH_PROJECT_REJECTED',
    FETCH_PROJECT_FULFILLED: 'FETCH_PROJECT_FULFILLED',

    FETCH_PROJECTS: 'FETCH_PROJECTS',
    FETCH_PROJECTS_PENDING: 'FETCH_PROJECTS_PENDING',
    FETCH_PROJECTS_REJECTED: 'FETCH_PROJECTS_REJECTED',
    FETCH_PROJECTS_FULFILLED: 'FETCH_PROJECTS_FULFILLED',

    fetchProjects: (user) => {
        return (dispatch) => {
            dispatch({type: projectActions.FETCH_PROJECTS_PENDING})
            return fetch(Remotes.projectsPath(), {
                method: 'GET',
                headers: {
                    "Accept": 'application/json',
                    "Authorization": getToken()
                }
            })
                .then(res => extractJson(res))
                .then(json => {
                    return dispatch({type: projectActions.FETCH_PROJECTS_FULFILLED, payload: json})
                })
                .catch(err => {
                    return dispatch({type: projectActions.FETCH_PROJECTS_REJECTED, payload: err})
                });
        };
    },

    fetchProject: (id) => {
        return (dispatch) => {
            dispatch({type: projectActions.FETCH_PROJECT_PENDING})
            return fetch(Remotes.projectPath(id), {
                method: 'GET',
                headers: {
                    "Accept": 'application/json',
                    "Authorization": getToken()
                }
            })
                .then(res => extractJson(res))
                .then(json => {
                    return dispatch({type: projectActions.FETCH_PROJECT_FULFILLED, payload: json})
                })
                .catch(err => {
                    return dispatch({type: projectActions.FETCH_PROJECT_REJECTED, payload: err})
                });
        };
    },

    createProject: (project) => {
        return (dispatch) => {
            dispatch({type: projectActions.CREATE_PROJECT_PENDING})
            return fetch(Remotes.projectsPath(), {
                method: 'POST',
                headers: {
                    "Accept": 'application/json',
                    "Authorization": getToken()
                },
                body: JSON.stringify(project)
            })
                .then(res => {
                    if (!res.ok) {
                        throw new Error('request failed');
                    }
                    return extractJson(res);
                })
                .then(json => {
                    return dispatch({type: projectActions.CREATE_PROJECT_FULFILLED, payload: json})
                })
                .catch(err => {
                    return dispatch({type: projectActions.CREATE_PROJECT_REJECTED, payload: err})
                });
        };
    }
};
<|endoftext|>


<commit_before>import Label from './label'

export default class LabelGroup {

    constructor (labels) {
        this.labels = labels || [];
    }

    occluded (bboxes) {
        for (var i = this.labels.length - 1; i >= 0; i--){
            var label = this.labels[i];
            var isOccluded = Label.prototype.occluded.apply(label, arguments);
            if (isOccluded) this.remove(i);
        }

        return (this.labels.length > 0);
    }

    add (boxes) {
        for (var i = 0; i < this.labels.length; i++){
            var label = this.labels[i];
            Label.prototype.add.apply(label, arguments);
        }
    }

    inTileBounds () {
        for (var i = 0; i < this.labels.length; i++){
            var label = this.labels[i];
            var isInTile = Label.prototype.inTileBounds.apply(label, arguments);
            if (!isInTile) return false;
        }
        return true;
    }

    discard (bboxes) {
        for (var i = this.labels.length - 1; i >= 0; i--){
            var label = this.labels[i];
            var isDiscarded = Label.prototype.discard.apply(label, arguments);
            if (isDiscarded) {
                this.remove(i);
                return true;
            }
        }
        return (this.labels.length === 0);
    }

    remove (index) {
        this.labels.splice(index, 1);
    }
}<commit_msg>Internal label occlusion in LabelGroup<commit_after>import Label from './label'

export default class LabelGroup {

    constructor (labels) {
        this.labels = labels || [];
        this.aabbs = [];
        this.obbs = [];
    }

    occluded (bboxes) {
        for (var i = this.labels.length - 1; i >= 0; i--){
            var label = this.labels[i];
            var isOccluded = Label.prototype.occluded.apply(label, arguments);
            if (isOccluded) this.remove(i);
        }

        return (this.labels.length > 0);
    }

    add (boxes) {
        // discard before adding
        this.internalDiscard();
        for (var i = 0; i < this.labels.length; i++){
            var label = this.labels[i];
            Label.prototype.add.apply(label, arguments);
        }
    }

    inTileBounds () {
        for (var i = 0; i < this.labels.length; i++){
            var label = this.labels[i];
            var isInTile = Label.prototype.inTileBounds.apply(label, arguments);
            if (!isInTile) return false;
        }
        return true;
    }

    discard (bboxes) {
        for (var i = this.labels.length - 1; i >= 0; i--){
            var label = this.labels[i];
            var isDiscarded = Label.prototype.discard.apply(label, arguments);
            if (isDiscarded) {
                this.remove(i);
            }
        }
        return (this.labels.length === 0);
    }

    internalDiscard () {
        if (this.labels.length < 2) return;

        for (var i = this.labels.length - 1; i >= 0; i--) {
            var label = this.labels[i];
            var isDiscarded = label.occluded({ aabb: this.aabbs, obb: this.obbs });
            if (isDiscarded) {
                this.remove(i);
            }
            else {
                this.aabbs.push(label.aabb);
                this.obbs.push(label.obb);
            }
        }

        this.aabbs = [];
        this.obbs = [];
    }

    remove (index) {
        this.labels.splice(index, 1);
    }
}<|endoftext|>


<commit_before>import React, { PropTypes } from "react"
import Helmet from "react-helmet"
import warning from "warning"
import { BodyContainer, joinUri, Link } from "phenomic"

import Button from "../../components/Button"
import Loading from "../../components/Loading"

import styles from "./index.css"

const Page = (
  {
    __filename,
    __url,
    head,
    body,
    header,
    footer,
    children,
  },
  {
    metadata: { pkg },
  }
) => {
  warning(
    typeof head.title === "string",
    `Your page '${ __filename }' needs a title`
  )

  const metaTitle = head.metaTitle ? head.metaTitle : head.title

  const socialImage = head.hero && head.hero.match("://") ? head.hero
    : joinUri(process.env.PHENOMIC_USER_URL, head.hero)

  const meta = [
    { property: "og:type", content: "article" },
    { property: "og:title", content: metaTitle },
    {
      property: "og:url",
      content: joinUri(process.env.PHENOMIC_USER_URL, __url),
    },
    { property: "og:image", content: socialImage },
    { property: "og:description", content: head.description },
    { name: "twitter:card", content: "summary" },
    { name: "twitter:title", content: metaTitle },
    { name: "twitter:creator", content: `@${ pkg.twitter }` },
    { name: "twitter:description", content: head.description },
    { name: "twitter:image", content: socialImage },
    { name: "description", content: head.description },
  ]

  return (

      <Helmet
        title={ metaTitle }
        meta={ meta }
      />
      {
        <div
          className={ styles.hero }
          style={ head.hero && {
            background: `#111 url(${ head.hero }) 50% 50% / cover`,
          } }
        >

{ head.title }

              {
                head.cta &&
                <Link to={ head.cta.link }>
                  <Button className={ styles.cta } light { ...head.cta.props }>
                    { head.cta.label }
                  </Button>
                </Link>
              }

      }

        { header }

            <BodyContainer>{ body }</BodyContainer>

        { children }
        { footer }

  )
}

Page.propTypes = {
  children: PropTypes.node,
  isLoading: PropTypes.bool,
  __filename: PropTypes.string,
  __url: PropTypes.string,
  head: PropTypes.object.isRequired,
  body: PropTypes.string,
  header: PropTypes.element,
  footer: PropTypes.element,
}

Page.contextTypes = {
  metadata: PropTypes.object.isRequired,
}

export default Page
<commit_msg>layout changes<commit_after>import React, { PropTypes } from "react"
import Helmet from "react-helmet"
import warning from "warning"
import { BodyContainer, joinUri, Link } from "phenomic"

import Button from "../../components/Button"

import styles from "./index.css"

const Page = (
  {
    __filename,
    __url,
    head,
    body,
    header,
    footer,
    children,
  },
  {
    metadata: { pkg },
  }
) => {
  warning(
    typeof head.title === "string",
    `Your page '${ __filename }' needs a title`
  )

  const metaTitle = head.metaTitle ? head.metaTitle : head.title

  const socialImage = head.hero && head.hero.match("://") ? head.hero
    : joinUri(process.env.PHENOMIC_USER_URL, head.hero)

  const meta = [
    { property: "og:type", content: "article" },
    { property: "og:title", content: metaTitle },
    {
      property: "og:url",
      content: joinUri(process.env.PHENOMIC_USER_URL, __url),
    },
    { property: "og:image", content: socialImage },
    { property: "og:description", content: head.description },
    { name: "twitter:card", content: "summary" },
    { name: "twitter:title", content: metaTitle },
    { name: "twitter:creator", content: `@${ pkg.twitter }` },
    { name: "twitter:description", content: head.description },
    { name: "twitter:image", content: socialImage },
    { name: "description", content: head.description },
  ]

  return (

      <Helmet
        title={ metaTitle }
        meta={ meta }
      />
      {
        <div
          className={ styles.hero }
          style={ head.hero && {
            background: `#111 url(${ head.hero }) 50% 50% / cover`,
          } }
        >

{ head.title }

              {
                head.cta &&
                <Link to={ head.cta.link }>
                  <Button className={ styles.cta } light { ...head.cta.props }>
                    { head.cta.label }
                  </Button>
                </Link>
              }

      }

        { header }

            <BodyContainer>{ body }</BodyContainer>

        { children }
        { footer }

  )
}

Page.propTypes = {
  children: PropTypes.node,
  __filename: PropTypes.string,
  __url: PropTypes.string,
  head: PropTypes.object.isRequired,
  body: PropTypes.string,
  header: PropTypes.element,
  footer: PropTypes.element,
}

Page.contextTypes = {
  metadata: PropTypes.object.isRequired,
}

export default Page
<|endoftext|>


<commit_before>import React, { PropTypes } from "react"
import Helmet from "react-helmet"
import warning from "warning"
import { BodyContainer, joinUri, Link } from "phenomic"

import Button from "../../components/Button"
import Loading from "../../components/Loading"

import styles from "./index.css"

const Page = (
  {
    isLoading,
    __filename,
    __url,
    head,
    body,
    header,
    footer,
    children,
  },
  {
    metadata: { pkg },
  }
) => {
  warning(
    typeof head.title === "string",
    `Your page '${ __filename }' needs a title`
  )

  const metaTitle = head.metaTitle ? head.metaTitle : head.title

  const socialImage = head.hero && head.hero.match("://") ? head.hero
    : joinUri(process.env.PHENOMIC_USER_URL, head.hero)

  const meta = [
    { property: "og:type", content: "article" },
    { property: "og:title", content: metaTitle },
    {
      property: "og:url",
      content: joinUri(process.env.PHENOMIC_USER_URL, __url),
    },
    { property: "og:image", content: socialImage },
    { property: "og:description", content: head.description },
    { name: "twitter:card", content: "summary" },
    { name: "twitter:title", content: metaTitle },
    { name: "twitter:creator", content: `@${ pkg.twitter }` },
    { name: "twitter:description", content: head.description },
    { name: "twitter:image", content: socialImage },
    { name: "description", content: head.description },
  ]

  return (

      <Helmet
        title={ metaTitle }
        meta={ meta }
      />
      {
        <div
          className={ styles.hero }
          style={ head.hero && {
            background: `#111 url(${ head.hero }) 50% 50% / cover`,
          } }
        >

{ head.title }

              {
                head.cta &&
                <Link to={ head.cta.link }>
                  <Button className={ styles.cta } light { ...head.cta.props }>
                    { head.cta.label }
                  </Button>
                </Link>
              }

      }

        { header }

          {

            <BodyContainer>{ body }</BodyContainer>
          }

        { children }
        { footer }

  )
}

Page.propTypes = {
  children: PropTypes.node,
  isLoading: PropTypes.bool,
  __filename: PropTypes.string,
  __url: PropTypes.string,
  head: PropTypes.object.isRequired,
  body: PropTypes.string,
  header: PropTypes.element,
  footer: PropTypes.element,
}

Page.contextTypes = {
  metadata: PropTypes.object.isRequired,
}

export default Page
<commit_msg>layout changes<commit_after>import React, { PropTypes } from "react"
import Helmet from "react-helmet"
import warning from "warning"
import { BodyContainer, joinUri, Link } from "phenomic"

import Button from "../../components/Button"
import Loading from "../../components/Loading"

import styles from "./index.css"

const Page = (
  {
    __filename,
    __url,
    head,
    body,
    header,
    footer,
    children,
  },
  {
    metadata: { pkg },
  }
) => {
  warning(
    typeof head.title === "string",
    `Your page '${ __filename }' needs a title`
  )

  const metaTitle = head.metaTitle ? head.metaTitle : head.title

  const socialImage = head.hero && head.hero.match("://") ? head.hero
    : joinUri(process.env.PHENOMIC_USER_URL, head.hero)

  const meta = [
    { property: "og:type", content: "article" },
    { property: "og:title", content: metaTitle },
    {
      property: "og:url",
      content: joinUri(process.env.PHENOMIC_USER_URL, __url),
    },
    { property: "og:image", content: socialImage },
    { property: "og:description", content: head.description },
    { name: "twitter:card", content: "summary" },
    { name: "twitter:title", content: metaTitle },
    { name: "twitter:creator", content: `@${ pkg.twitter }` },
    { name: "twitter:description", content: head.description },
    { name: "twitter:image", content: socialImage },
    { name: "description", content: head.description },
  ]

  return (

      <Helmet
        title={ metaTitle }
        meta={ meta }
      />
      {
        <div
          className={ styles.hero }
          style={ head.hero && {
            background: `#111 url(${ head.hero }) 50% 50% / cover`,
          } }
        >

{ head.title }

              {
                head.cta &&
                <Link to={ head.cta.link }>
                  <Button className={ styles.cta } light { ...head.cta.props }>
                    { head.cta.label }
                  </Button>
                </Link>
              }

      }

        { header }

          {

            <BodyContainer>{ body }</BodyContainer>
          }

        { children }
        { footer }

  )
}

Page.propTypes = {
  children: PropTypes.node,
  isLoading: PropTypes.bool,
  __filename: PropTypes.string,
  __url: PropTypes.string,
  head: PropTypes.object.isRequired,
  body: PropTypes.string,
  header: PropTypes.element,
  footer: PropTypes.element,
}

Page.contextTypes = {
  metadata: PropTypes.object.isRequired,
}

export default Page
<|endoftext|>