<commit_before>/**
 * jquery.scrollbox.js
 *
 * @version    1.0.0-alpha
 * @author     Max Invis1ble
 * @copyright  (c) 2013-2016, Max Invis1ble
 * @license    MIT http://www.opensource.org/licenses/mit-license.php
 */
+function ($, window, document, undefined) {

    'use strict';

    var name = 'scrollbox',
        Scrollbox = function ($element, options) {
            var o = this.options = $.extend({}, $.fn[name].defaults, options);

            this.$element = $element;
            this.$rail = $(o.templates.rail);
            this.$bar = $(o.templates.bar);

            this.init = o.init || this.init;
            this.addListeners = o.addListeners || this.addListeners;
            this.removeListeners = o.removeListeners || this.removeListeners;
            this.scroll = o.scroll || this.scroll;
            this.jump = o.jump || this.jump;
            this.update = o.update || this.update;
            this.destroy = o.destroy || this.destroy;

            this._isOver = this._isBarCaptured = this._isShown = false;
            this._prevY = 0;
            this._isReachTriggered = { top: false, bottom: false };
            this._scrollHeight = undefined;
            this._setScrolledToY();
            this._barTouchId = this._elementTouchId = this._swipeStartY = this._swipeStartedAt = null;

            this._listeners = {};

            this.init();
        };

    Scrollbox.prototype = {

        init: function () {
            var options = this.options;

            this.$wrapper = this.$element
                .trigger('init.' + name)
                .css('overflow', 'hidden')
                .wrap(options.templates.wrapper).parent()
                .append(this.$rail)
                .append(this.$bar);

            this._updateBarHeight();

            if ('top' !== options.start) {
                this.jump(options.start);
            }

            if (this._isShown) {
                this.addListeners();
            }
        },

        addListeners: function () {
            this._listeners.wheel = $.proxy(this._onWheel, this);

            this.$wrapper.on({
                mouseenter: $.proxy(this._onEnter, this),
                mouseleave: $.proxy(this._onLeave, this)
            });

            if (window.addEventListener) {
                window.addEventListener('DOMMouseScroll', this._listeners.wheel, false);
                window.addEventListener('mousewheel', this._listeners.wheel, false);
            } else {
                document.attachEvent('onmousewheel', this._listeners.wheel);
            }

            this.$bar.on({
                mousedown: $.proxy(this._onBarMouseDown, this),
                touchstart: $.proxy(this._onBarTouchStart, this)
            });

            this.$element.on({
                scroll: $.proxy(this._onElementScroll, this),
                touchstart: $.proxy(this._onElementTouchStart, this)
            });

            $(document).on({
                mouseup: $.proxy(this._onDocumentMouseUp, this),
                mousemove: $.proxy(this._onDocumentMouseMove, this),
                touchend: $.proxy(this._onDocumentTouchEnd, this),
                touchmove: $.proxy(this._onDocumentTouchMove, this)
            });
        },

        removeListeners: function () {
            this.$wrapper.off({
                mouseenter: this._onEnter,
                mouseleave: this._onLeave
            });

            if (window.removeEventListener) {
                window.removeEventListener('DOMMouseScroll', this._listeners.wheel, false);
                window.removeEventListener('mousewheel', this._listeners.wheel, false);
            } else {
                document.detachEvent('onmousewheel', this._listeners.wheel);
            }

            this.$bar.off({
                mousedown: this._onBarMouseDown,
                touchstart: this._onBarTouchStart
            });

            this.$element.off({
                scroll: this._onElementScroll,
                touchstart: this._onElementTouchStart
            });

            $(document).off({
                mouseup: this._onDocumentMouseUp,
                mousemove: this._onDocumentMouseMove,
                touchend: this._onDocumentTouchEnd,
                touchmove: this._onDocumentTouchMove
            });
        },

        _onEnter: function (e) {
            e.preventDefault();

            this._isOver = true;
        },

        _onLeave: function (e) {
            e.preventDefault();

            this._isOver = false;
        },

        _onWheel: function (e) {
            if (this._isOver) {
                if (undefined === e) {
                    e = window.event;
                }

                if (e.preventDefault) {
                    e.preventDefault();
                } else {
                    e.returnValue = false;
                }

                this.scroll((e.detail ? e.detail / 3 : -e.wheelDelta / 120) * this.options.wheelSensitivity);
            }
        },

        _onBarMouseDown: function (e) {
            if (1 === e.which) {
                e.preventDefault();

                this._dragStart(e.pageY);
            }
        },

        _onDocumentMouseMove: function (e) {
            if (this._isBarCaptured) {
                e.preventDefault();

                this._drag(e.pageY);
            }
        },

        _onDocumentMouseUp: function (e) {
            if (this._isBarCaptured && 1 === e.which) {
                e.preventDefault();

                this._dragStop();
            }
        },

        _onBarTouchStart: function (e) {
            var touches = e.originalEvent.targetTouches;

            if (1 == touches.length) {
                e.preventDefault();

                this._barTouchId = touches[0].identifier;
                this._dragStart(touches[0].pageY);
            }
        },

        _onDocumentTouchMove: function (e) {
            var touches = e.originalEvent.targetTouches,
                i;

            if (this._isBarCaptured) {
                for (i in touches) {
                    if (touches[i].identifier === this._barTouchId) {
                        e.preventDefault();

                        this._drag(touches[i].pageY);
                        break;
                    }
                }
            }

            if (null !== this._elementTouchId) {
                for (i in touches) {
                    if (touches[i].identifier === this._elementTouchId) {
                        e.preventDefault();

                        this._swipe(touches[i].pageY);
                        break;
                    }
                }
            }
        },

        _onDocumentTouchEnd: function (e) {
            var touches = e.originalEvent.changedTouches,
                swipeDuration,
                swipeDistance,
                swipeSpeed,
                offset,
                i;

            if (this._isBarCaptured) {
                for (i in touches) {
                    if (touches[i].identifier === this._barTouchId) {
                        e.preventDefault();

                        this._dragStop();
                        this._barTouchId = null;
                        break;
                    }
                }
            }

            if (null !== this._elementTouchId) {
                for (i in touches) {
                    if (touches[i].identifier === this._elementTouchId) {
                        e.preventDefault();

                        swipeDuration = Date.now() - this._swipeStartedAt;

                        if (swipeDuration <= this.options.momentum.thresholdTime) {
                            swipeDistance = this._swipeStartY - touches[i].pageY;
                            swipeSpeed = Math.abs(swipeDistance / swipeDuration);
                            offset = swipeSpeed * swipeSpeed * 2 * this.options.momentum.acceleration;

                            if (swipeDistance < 0) {
                                offset = -offset;
                            }

                            this.scroll(offset, {
                                duration: swipeSpeed * this.options.momentum.acceleration,
                                easing: 'momentum'
                            });
                        }

                        this._swipeStartY = this._swipeStartedAt = this._elementTouchId = null;
                        break;
                    }
                }
            }
        },

        _onElementScroll: function (e) {
            e.preventDefault();

            this._updateBarPosition();
        },

        _onElementTouchStart: function (e) {
            var touches = e.originalEvent.targetTouches;

            if (1 == touches.length) {
                e.preventDefault();

                this.$element.stop(true, false);

                this._elementTouchId = touches[0].identifier;
                this._swipeStartY = this._prevY = touches[0].pageY;
                this._swipeStartedAt = new Date();
            }
        },

        _dragStart: function (y) {
            this._isBarCaptured = true;
            this._prevY = y;

            this.$bar.addClass(name + '-bar-captured');
        },

        _drag: function (y) {
            var elementHeight = this.$element.outerHeight();

            this.scroll((y - this._prevY) * ((this._getScrollHeight() - elementHeight) / (elementHeight - this.$bar.height())));
            this._prevY = y;
        },

        _dragStop: function () {
            this._isBarCaptured = false;

            this.$bar.removeClass(name + '-bar-captured');
        },

        _swipe: function (y) {
            this.scroll(this._prevY - y);
            this._prevY = y;
        },

        scroll: function (delta, animationOptions) {
            var max = this._getScrollHeight() - this.$element.outerHeight(),
                scrollToY = this._getScrolledToY() + delta,
                options = this.options,
                position;

            this.$element.trigger('scroll.' + name);

            if (scrollToY >= max) {
                scrollToY = max;
            } else if (scrollToY <= 0) {
                scrollToY = 0;
            }

            this._setScrolledToY(scrollToY);

            if (undefined === animationOptions) {
                this.$element.scrollTop(scrollToY);
            } else {
                this.$element.stop(true, false).animate({
                    scrollTop: scrollToY
                }, animationOptions);
            }

            if (!this._isReachTriggered.bottom && scrollToY + options.distanceToReach >= max) {
                position = 'bottom';
            } else if (!this._isReachTriggered.top && scrollToY - options.distanceToReach <= 0) {
                position = 'top';
            }

            if (position) {
                this.$element.trigger($.Event('reach.' + name, { position: position }));
                this._isReachTriggered[position] = true;
            }
        },

        jump: function (y, animationOptions) {
            if ('top' === y) {
                y = 0;
            } else if ('bottom' === y) {
                y = this._getScrollHeight() - this.$element.height();
            }

            this.scroll(y - this._getScrolledToY(), animationOptions);
        },

        update: function () {
            var isShown = this._isShown;

            this._scrollHeight = undefined;
            this._isReachTriggered.top = this._isReachTriggered.bottom = false;
            this._updateBarHeight();

            if (this._isShown) {
                this._updateBarPosition();

                if (!isShown) {
                    this.addListeners();
                }
            }
        },

        _getScrolledToY: function () {
            if (undefined === this._scrolledToY) {
                this._scrolledToY = this.$element.scrollTop();
            }

            return this._scrolledToY;
        },

        _setScrolledToY: function (y) {
            this._scrolledToY = y;
        },

        _getScrollHeight: function () {
            // opera bug workaround
            if (undefined === this._scrollHeight) {
                this._scrollHeight = this.$element[0].scrollHeight;
            }

            return this._scrollHeight;
        },

        _updateBarHeight: function () {
            var elementHeight = this.$element.outerHeight(),
                ratio = elementHeight / this._getScrollHeight();

            if (1 !== ratio) {
                this.$bar.height(elementHeight * ratio);

                if (!this._isShown) {
                    this.$bar.addClass(name + '-bar-in');
                    this.$rail.addClass(name + '-rail-in');
                    this._isShown = true;
                }
            } else if (this._isShown) {
                this.removeListeners();
                this.$bar.removeClass(name + '-bar-in');
                this.$rail.removeClass(name + '-rail-in');
                this._isShown = false;
            }
        },

        _updateBarPosition: function () {
            var elementHeight = this.$element.outerHeight();

            this.$bar.css(
                'top',
                (elementHeight - this.$bar.outerHeight()) * (this._getScrolledToY() / (this._getScrollHeight() - elementHeight))
            );
        },

        destroy: function () {
            this.$wrapper
                .off('.' + name)
                .find('*').off('.' + name);

            this.removeListeners();

            this.$element
                .unwrap()
                .removeData(name);

            this.$rail.remove();
            this.$bar.remove();

            this.$bar = this.$rail = this.$element = this.$wrapper = null;
        }

    };

    if ($.easing.momentum === undefined) {
        $.easing.momentum = function (x, t, b, c, d) {
            var ts = (t /= d) * t,
                tc = ts * t;

            return b + c * (-1 * ts * ts + 4 * tc + -6 * ts + 4 * t);
        };
    }

    $.fn[name] = function (option) {
        var args = Array.prototype.slice.call(arguments, 1);

        return this.each(function () {
            var $this = $(this),
                data = $this.data(name),
                options;

            if ('object' === typeof option) {
                options = option;
            }

            if (!data) {
                $this.data(name, (data = new Scrollbox($this, options)));
            }

            if ('string' === typeof option) {
                data[option].apply(data, args);
            }
        });
    };

    $.fn[name].Constructor = Scrollbox;

    $.fn[name].defaults = {
        distanceToReach: 0,
        wheelSensitivity: 20,
        momentum: {
            acceleration: 1600,
            thresholdTime: 500
        },
        start: 'top',
        templates: {
            bar: '

',
            rail: '

',
            wrapper: '

'
        }
    };

}(jQuery, window, document);<commit_msg>Fixed bugs<commit_after>/**
 * jquery.scrollbox.js
 *
 * @version    1.0.0-alpha
 * @author     Max Invis1ble
 * @copyright  (c) 2013-2016, Max Invis1ble
 * @license    MIT http://www.opensource.org/licenses/mit-license.php
 */
+function ($, window, document, undefined) {

    'use strict';

    var name = 'scrollbox',
        Scrollbox = function ($element, options) {
            var o = this.options = $.extend({}, $.fn[name].defaults, options);

            this.$element = $element;
            this.$rail = $(o.templates.rail);
            this.$bar = $(o.templates.bar);

            this.init = o.init || this.init;
            this.addListeners = o.addListeners || this.addListeners;
            this.removeListeners = o.removeListeners || this.removeListeners;
            this.scroll = o.scroll || this.scroll;
            this.jump = o.jump || this.jump;
            this.update = o.update || this.update;
            this.destroy = o.destroy || this.destroy;

            this._isOver = this._isBarCaptured = this._isShown = false;
            this._prevY = 0;
            this._isReachTriggered = { top: false, bottom: false };
            this._scrollHeight = undefined;
            this._setScrolledToY();
            this._barTouchId = this._elementTouchId = this._swipeStartY = this._swipeStartedAt = null;

            this._listeners = {};

            this.init();
        };

    Scrollbox.prototype = {

        init: function () {
            var options = this.options;

            this.$wrapper = this.$element
                .trigger('init.' + name)
                .css('overflow', 'hidden')
                .wrap(options.templates.wrapper).parent()
                .append(this.$rail)
                .append(this.$bar);

            this._updateBarHeight();

            if ('top' !== options.start) {
                this.jump(options.start);
            }

            if (this._isShown) {
                this.addListeners();
            }
        },

        addListeners: function () {
            this._listeners.wheel = $.proxy(this._onWheel, this);

            this.$wrapper.on({
                mouseenter: $.proxy(this._onEnter, this),
                mouseleave: $.proxy(this._onLeave, this)
            });

            if (window.addEventListener) {
                window.addEventListener('DOMMouseScroll', this._listeners.wheel, false);
                window.addEventListener('mousewheel', this._listeners.wheel, false);
            } else {
                document.attachEvent('onmousewheel', this._listeners.wheel);
            }

            this.$bar.on({
                mousedown: $.proxy(this._onBarMouseDown, this),
                touchstart: $.proxy(this._onBarTouchStart, this)
            });

            this.$element.on({
                scroll: $.proxy(this._onElementScroll, this),
                touchstart: $.proxy(this._onElementTouchStart, this)
            });

            $(document).on({
                mouseup: $.proxy(this._onDocumentMouseUp, this),
                mousemove: $.proxy(this._onDocumentMouseMove, this),
                touchend: $.proxy(this._onDocumentTouchEnd, this),
                touchmove: $.proxy(this._onDocumentTouchMove, this)
            });
        },

        removeListeners: function () {
            this.$wrapper.off({
                mouseenter: this._onEnter,
                mouseleave: this._onLeave
            });

            if (window.removeEventListener) {
                window.removeEventListener('DOMMouseScroll', this._listeners.wheel, false);
                window.removeEventListener('mousewheel', this._listeners.wheel, false);
            } else {
                document.detachEvent('onmousewheel', this._listeners.wheel);
            }

            this.$bar.off({
                mousedown: this._onBarMouseDown,
                touchstart: this._onBarTouchStart
            });

            this.$element.off({
                scroll: this._onElementScroll,
                touchstart: this._onElementTouchStart
            });

            $(document).off({
                mouseup: this._onDocumentMouseUp,
                mousemove: this._onDocumentMouseMove,
                touchend: this._onDocumentTouchEnd,
                touchmove: this._onDocumentTouchMove
            });
        },

        _onEnter: function (e) {
            e.preventDefault();

            this._isOver = true;
        },

        _onLeave: function (e) {
            e.preventDefault();

            this._isOver = false;
        },

        _onWheel: function (e) {
            if (this._isOver) {
                if (undefined === e) {
                    e = window.event;
                }

                if (e.preventDefault) {
                    e.preventDefault();
                } else {
                    e.returnValue = false;
                }

                this.scroll((e.detail ? e.detail / 3 : -e.wheelDelta / 120) * this.options.wheelSensitivity);
            }
        },

        _onBarMouseDown: function (e) {
            if (1 === e.which) {
                e.preventDefault();

                this._dragStart(e.pageY);
            }
        },

        _onDocumentMouseMove: function (e) {
            if (this._isBarCaptured) {
                e.preventDefault();

                this._drag(e.pageY);
            }
        },

        _onDocumentMouseUp: function (e) {
            if (this._isBarCaptured && 1 === e.which) {
                e.preventDefault();

                this._dragStop();
            }
        },

        _onBarTouchStart: function (e) {
            var touches = e.originalEvent.targetTouches;

            if (1 == touches.length) {
                e.preventDefault();

                this._barTouchId = touches[0].identifier;
                this._dragStart(touches[0].pageY);
            }
        },

        _onDocumentTouchMove: function (e) {
            var touches = e.originalEvent.targetTouches,
                i;

            if (this._isBarCaptured) {
                for (i in touches) {
                    if (touches[i].identifier === this._barTouchId) {
                        e.preventDefault();

                        this._drag(touches[i].pageY);
                        break;
                    }
                }
            }

            if (null !== this._elementTouchId) {
                for (i in touches) {
                    if (touches[i].identifier === this._elementTouchId) {
                        e.preventDefault();

                        this.foo = touches[i].pageY;

                        this._swipe(touches[i].pageY);
                        break;
                    }
                }
            }
        },

        _onDocumentTouchEnd: function (e) {
            var touches = e.originalEvent.changedTouches,
                swipeDuration,
                swipeDistance,
                swipeSpeed,
                offset,
                i;

            if (this._isBarCaptured) {
                for (i in touches) {
                    if (touches[i].identifier === this._barTouchId) {
                        e.preventDefault();

                        this._dragStop();
                        this._barTouchId = null;
                        break;
                    }
                }
            }

            if (null !== this._elementTouchId) {
                for (i in touches) {
                    if (touches[i].identifier === this._elementTouchId) {
                        e.preventDefault();

                        swipeDuration = Date.now() - this._swipeStartedAt;

                        if (swipeDuration <= this.options.momentum.thresholdTime) {
                            swipeDistance = this._swipeStartY - touches[i].pageY;
                            swipeSpeed = Math.abs(swipeDistance / swipeDuration);
                            offset = swipeSpeed * swipeSpeed * 2 * this.options.momentum.acceleration;

                            if (swipeDistance < 0) {
                                offset = -offset;
                            }

                            this.scroll(offset, {
                                duration: swipeSpeed * this.options.momentum.acceleration,
                                easing: 'momentum'
                            });
                        }

                        this._swipeStartY = this._swipeStartedAt = this._elementTouchId = null;
                        break;
                    }
                }
            }
        },

        _onElementScroll: function (e) {
            e.preventDefault();

            this._updateBarPosition();
        },

        _onElementTouchStart: function (e) {
            var touches = e.originalEvent.targetTouches;

            if (1 == touches.length) {
                e.preventDefault();

                if (this.$element.is(':animated')) {
                    this.$element.stop(true, false);
                    this._setScrolledToY(this.$element.scrollTop());
                }

                this._elementTouchId = touches[0].identifier;
                this._swipeStartY = this._prevY = touches[0].pageY;
                this._swipeStartedAt = new Date();
            }
        },

        _dragStart: function (y) {
            this._isBarCaptured = true;
            this._prevY = y;

            this.$bar.addClass(name + '-bar-captured');
        },

        _drag: function (y) {
            var elementHeight = this.$element.outerHeight();

            this.scroll((y - this._prevY) * ((this._getScrollHeight() - elementHeight) / (elementHeight - this.$bar.height())));
            this._prevY = y;
        },

        _dragStop: function () {
            this._isBarCaptured = false;

            this.$bar.removeClass(name + '-bar-captured');
        },

        _swipe: function (y) {
            this.scroll(this._prevY - y);
            this._prevY = y;
        },

        scroll: function (delta, animationOptions) {
            var max = this._getScrollHeight() - this.$element.outerHeight(),
                scrollToY = this._getScrolledToY() + delta,
                options = this.options,
                position;

            this.$element
                .trigger('scroll.' + name)
                .stop(true, false);

            if (scrollToY >= max) {
                scrollToY = max;
            } else if (scrollToY <= 0) {
                scrollToY = 0;
            }

            this._setScrolledToY(scrollToY);

            if (undefined === animationOptions) {
                this.$element.scrollTop(scrollToY);
            } else {
                this.$element.animate({
                    scrollTop: scrollToY
                }, animationOptions);
            }

            if (!this._isReachTriggered.bottom && scrollToY + options.distanceToReach >= max) {
                position = 'bottom';
            } else if (!this._isReachTriggered.top && scrollToY - options.distanceToReach <= 0) {
                position = 'top';
            }

            if (position) {
                this.$element.trigger($.Event('reach.' + name, { position: position }));
                this._isReachTriggered[position] = true;
            }
        },

        jump: function (y, animationOptions) {
            if ('top' === y) {
                y = 0;
            } else if ('bottom' === y) {
                y = this._getScrollHeight() - this.$element.height();
            }

            this.scroll(y - this._getScrolledToY(), animationOptions);
        },

        update: function () {
            var isShown = this._isShown;

            this._scrollHeight = undefined;
            this._isReachTriggered.top = this._isReachTriggered.bottom = false;
            this._updateBarHeight();

            if (this._isShown) {
                this._updateBarPosition();

                if (!isShown) {
                    this.addListeners();
                }
            }
        },

        _getScrolledToY: function () {
            if (undefined === this._scrolledToY) {
                this._scrolledToY = this.$element.scrollTop();
            }

            return this._scrolledToY;
        },

        _setScrolledToY: function (y) {
            this._scrolledToY = y;
        },

        _getScrollHeight: function () {
            // opera bug workaround
            if (undefined === this._scrollHeight) {
                this._scrollHeight = this.$element[0].scrollHeight;
            }

            return this._scrollHeight;
        },

        _updateBarHeight: function () {
            var elementHeight = this.$element.outerHeight(),
                ratio = elementHeight / this._getScrollHeight();

            if (1 !== ratio) {
                this.$bar.height(elementHeight * ratio);

                if (!this._isShown) {
                    this.$bar.addClass(name + '-bar-in');
                    this.$rail.addClass(name + '-rail-in');
                    this._isShown = true;
                }
            } else if (this._isShown) {
                this.removeListeners();
                this.$bar.removeClass(name + '-bar-in');
                this.$rail.removeClass(name + '-rail-in');
                this._isShown = false;
            }
        },

        _updateBarPosition: function () {
            var elementHeight = this.$element.outerHeight();

            this.$bar.css(
                'top',
                (elementHeight - this.$bar.outerHeight()) * (this.$element.scrollTop() / (this._getScrollHeight() - elementHeight))
            );
        },

        destroy: function () {
            this.$wrapper
                .off('.' + name)
                .find('*').off('.' + name);

            this.removeListeners();

            this.$element
                .unwrap()
                .removeData(name);

            this.$rail.remove();
            this.$bar.remove();

            this.$bar = this.$rail = this.$element = this.$wrapper = null;
        }

    };

    if ($.easing.momentum === undefined) {
        $.easing.momentum = function (x, t, b, c, d) {
            var ts = (t /= d) * t,
                tc = ts * t;

            return b + c * (-1 * ts * ts + 4 * tc + -6 * ts + 4 * t);
        };
    }

    $.fn[name] = function (option) {
        var args = Array.prototype.slice.call(arguments, 1);

        return this.each(function () {
            var $this = $(this),
                data = $this.data(name),
                options;

            if ('object' === typeof option) {
                options = option;
            }

            if (!data) {
                $this.data(name, (data = new Scrollbox($this, options)));
            }

            if ('string' === typeof option) {
                data[option].apply(data, args);
            }
        });
    };

    $.fn[name].Constructor = Scrollbox;

    $.fn[name].defaults = {
        distanceToReach: 0,
        wheelSensitivity: 20,
        momentum: {
            acceleration: 1600,
            thresholdTime: 500
        },
        start: 'top',
        templates: {
            bar: '

',
            rail: '

',
            wrapper: '

'
        }
    };

}(jQuery, window, document);<|endoftext|>


<commit_before>'use strict';

const getSetMembersInfo = require('../../db/redis.js').getSetMembersInfo;
const filterHarnessTalent = require('../utils/app.js').filterHarnessTalent;

const cleanPayload = require('../utils/app.js').cleanPayload;
const interviewSchema = require('../utils/joiSchema.js').interviewSchema;
const client = require('../../db/client.js');
const getInterviewDetails = require('../../db/redis/getInterviewDetails.js');
const moveToNextInterviewStage = require('../../db/redis/moveToNextInterviewStage');
const uuid = require('uuid');

const fs = require('fs');
const changeInterview = require('../utils/mailgun.js').changeInterview;
const interviewConfirmation = require('../utils/mailgun.js').interviewConfirmation;
const proposedInterview = require('../utils/mailgun.js').proposedInterview;

const mailgun = require('../utils/mailgun.js');

exports.register = (server, options, next) => {

    server.route(
        [{
                method: 'GET',
                path: '/harnesstalent',
                config: {
                    auth: {
                        strategy: 'hrns-cookie'
                    },
                    handler: (request, reply) => {
                        reply.file('./public/views/harnesstalent.html')
                    }

                }
            }, {
                method: 'GET',
                path: '/harnesstalent/results',
                config: {
                    auth: {
                        strategy: 'hrns-cookie'
                    },
                    handler: (request, reply) => {
                        let query = request.query
                        console.log('QUERY >>>>>>>>>>>>>', query);
                        let set = 'HarnessTalent';
                        let response = {};
                        response.userType = request.auth.type;

                        if (response.userType !== 'client') {
                            response.userType = 'admin';
                        }
                        getSetMembersInfo(set, (harnessTalentList) => {

                            if (Object.keys(harnessTalentList).length === 0 || Object.keys(query).length === 0) {
                                console.log('Initial Render and no query Render', Object.keys(harnessTalentList), query);
                                response.array = harnessTalentList;
                                reply(response);

                            } else {

                                let filterKeys = findKeysWithoutValueAll(query);

                                let filterKeyExcSalary = removeSalaryMinMax(filterKeys);

                                // if all queris are 'All';
                                let candidatesFilteredExcSalary = harnessTalentList.filter(checkCandidate);
                                let filterKeyExcSalaryLength = filterKeyExcSalary.length;

                                switch (true) {

                                    case (filterKeyExcSalaryLength === 0 && query.salaryMax !== 'All' && query.salaryMin === 'All'):
                                        console.log('I\'m in only max');
                                        response.array =   filterBySalaryMax(harnessTalentList, query)
                                        return reply(response);

                                    case (filterKeyExcSalaryLength > 0 && query.salaryMax !== 'All' && query.salaryMin === 'All'):
                                        response.array = filterBySalaryMax(candidatesFilteredExcSalary, query);
                                        return reply(response);

                                    case (filterKeyExcSalaryLength === 0 && query.salaryMin !== 'All' && query.salaryMax === 'All'):
                                        response.array = filterBySalaryMin(harnessTalentList, query);
                                        return reply(response);

                                    case (filterKeyExcSalaryLength > 0 && query.salaryMax === 'All' && query.salaryMin !== 'All') :

                                        response.array = filterBySalaryMin(candidatesFilteredExcSalary, query);
                                        return reply(response);

                                    case (filterKeyExcSalaryLength === 0 && query.salaryMin !== 'All' && query.salaryMax !== 'All') :
                                        response.array = filterBySalaryRange(harnessTalentList, query);
                                        return reply(response);

                                    case (filterKeyExcSalaryLength > 0 && query.salaryMin !== 'All' && query.salaryMax !== 'All'):
                                        response.array = filterBySalaryRange(candidatesFilteredExcSalary, query);
                                        return reply(response);

                                    case (filterKeyExcSalaryLength > 0):
                                        response.array = candidatesFilteredExcSalary;
                                        return reply(response);

                                    case (filterKeyExcSalaryLength  === 0):
                                        response.array = harnessTalentList ;
                                        return reply(response);
                                }

                                // salary Max

                                // salary Min

                                // salary Range
                                //let candidatesFilteredExcSalary = harnessTalentList.filter(checkCandidate);

                                //let candidatesFilteredOnlyMax = filterBySalaryMax(candidatesFilteredExcSalary, query);

                                //let candidatesFilteredOnlyMin = filterBySalaryMin(candidatesFilteredExcSalary, query);

                                function findKeysWithoutValueAll(query) {
                                    let filterKeys = Object.keys(query).filter((key) => {
                                        return query[key] !== 'All'
                                    });
                                    return filterKeys;
                                }

                                function removeSalaryMinMax(keys) {
                                    let lessMinMax = keys.filter((ele) => {
                                        return ele !== 'salaryMin' && ele !== 'salaryMax';
                                    })
                                    return lessMinMax;
                                }

                                function checkCandidate(candidate) {
                                    for (var i = 0; i < filterKeyExcSalary.length; i++) {
                                        return candidate[filterKeyExcSalary[i]] === query[filterKeyExcSalary[i]] &&
                                            candidate[filterKeyExcSalary[i + 1]] === query[filterKeyExcSalary[i + 1]] &&
                                            candidate[filterKeyExcSalary[i + 2]] === query[filterKeyExcSalary[i + 2]] &&
                                            candidate[filterKeyExcSalary[i + 3]] === query[filterKeyExcSalary[i + 3]] &&
                                            candidate[filterKeyExcSalary[i + 4]] === query[filterKeyExcSalary[i + 4]]
                                    }
                                }

                                function convertSalaryToNumber(salaryString){
                                    let salary = salaryString.split('£')[1].replace(/\,/g, '');
                                    salary = parseInt(salary);
                                    return salary;
                                }

                                function filterBySalaryMax(array, query) {
                                    let candidatesFiltered = array.filter((candidate) => {
                                        let salary = convertSalaryToNumber(candidate.salary);
                                        return salary <= query.salaryMax
                                    });
                                    return candidatesFiltered;
                                }

                                function filterBySalaryMin(array, query) {
                                    let candidatesFiltered = array.filter((candidate) => {
                                        let salary = convertSalaryToNumber(candidate.salary);
                                        return salary >= query.salaryMin
                                    })

                                    return candidatesFiltered;
                                }

                                function filterBySalaryRange(array, query) {
                                    let candidatesFiltered = array.filter((candidate) => {
                                        let salary = convertSalaryToNumber(candidate.salary);
                                        return salary >= query.salaryMin && salary <= query.salaryMax;
                                    })
                                    return candidatesFiltered;
                                }

                            }

                        });
                    }
                }

            }, {
                method: 'POST',
                path: '/harnesstalent/interview/proposed',
                config: {
                    auth: {
                        strategy: 'hrns-cookie'
                            // scope: ['client', 'agent']
                    },
                    validate: {
                        payload: interviewSchema
                    },
                    handler: (request, reply) => {
                        ///  must update stage in db;
                        const newTimes = request.payload;
                        const clientId = request.auth.credentials.profile.id;
                        console.log(clientId);

                        const interviewId = uuid.v1() + 'interviewId';
                        newTimes.interviewId = interviewId;
                        newTimes.confirmed = false;

                        /// get the agency email and then send an email with a link to the agency with proposed
                        // job title and salary also link back to interview page. need to create interview hash include in link
                        let agencyId = newTimes.agencyId;
                        let cvid = newTimes.cvid;

                        client.hgetAsync(agencyId, 'email')
                            .then((agencyEmail) => {
                                newTimes.agencyEmail = agencyEmail;

                                client.hgetAsync(clientId, 'companyName')
                                    .then((clientCompanyName) => {
                                        newTimes.clientCompanyName = clientCompanyName;

                                        let newProposedInterview = Object.assign({}, proposedInterview);

                                        newProposedInterview.html = newProposedInterview.html
                                            .replace('-candidateName-', newTimes.candidateName)
                                            .replace('-jobTitle-', newTimes.jobTitle) //switch to client jobTitle.
                                            .replace('-companyName-', newTimes.clientCompanyName)
                                            .replace('-interviewId-', newTimes.interviewId);

                                        newProposedInterview.to = agencyEmail;
                                        mailgun.messages().send(newProposedInterview)

                                    })
                                    .then(() => {
                                        console.log('>>>>>>>>>>>>', interviewId , newTimes);
                                        let interview = cleanPayload(newTimes);
                                        client.hincrby(cvid, 'interviewsRequested',1);
                                        client.hmsetAsync(interviewId, interview);
                                    })
                                    .then(() => {
                                        return reply(cvid);
                                    })
                                    .catch(() => {
                                        return reply(false)
                                    });
                            })
                    }
                }
            }

        ]);
    return next();
};

exports.register.attributes = {
    name: 'Clientharnesstalent'
};
<commit_msg>refactored filter<commit_after>'use strict';

const getSetMembersInfo = require('../../db/redis.js').getSetMembersInfo;
const filterHarnessTalent = require('../utils/app.js').filterHarnessTalent;

const cleanPayload = require('../utils/app.js').cleanPayload;
const interviewSchema = require('../utils/joiSchema.js').interviewSchema;
const client = require('../../db/client.js');
const getInterviewDetails = require('../../db/redis/getInterviewDetails.js');
const moveToNextInterviewStage = require('../../db/redis/moveToNextInterviewStage');
const uuid = require('uuid');

const fs = require('fs');
const changeInterview = require('../utils/mailgun.js').changeInterview;
const interviewConfirmation = require('../utils/mailgun.js').interviewConfirmation;
const proposedInterview = require('../utils/mailgun.js').proposedInterview;

const mailgun = require('../utils/mailgun.js');

exports.register = (server, options, next) => {

    server.route(
        [{
                method: 'GET',
                path: '/harnesstalent',
                config: {
                    auth: {
                        strategy: 'hrns-cookie'
                    },
                    handler: (request, reply) => {
                        reply.file('./public/views/harnesstalent.html')
                    }

                }
            }, {
                method: 'GET',
                path: '/harnesstalent/results',
                config: {
                    auth: {
                        strategy: 'hrns-cookie'
                    },
                    handler: (request, reply) => {
                        let query = request.query
                        console.log('QUERY >>>>>>>>>>>>>', query);
                        let set = 'HarnessTalent';
                        let response = {};
                        response.userType = request.auth.type;

                        if (response.userType !== 'client') {
                            response.userType = 'admin';
                        }
                        getSetMembersInfo(set, (harnessTalentList) => {

                            if (Object.keys(harnessTalentList).length === 0 || Object.keys(query).length === 0) {
                                console.log('Initial Render and no query Render', Object.keys(harnessTalentList), query);
                                response.array = harnessTalentList;
                                reply(response);

                            } else {

                                let filterKeys = findKeysWithoutValueAll(query);

                                let filterKeyExcSalary = removeSalaryMinMax(filterKeys);

                                // if all queris are 'All';
                                let candidatesFilteredExcSalary = harnessTalentList.filter(checkCandidate);
                                let filterKeyExcSalaryLength = filterKeyExcSalary.length;

                                response.array = filtereredArray(filterKeyExcSalaryLength, query);
                                reply(response);

                                function findKeysWithoutValueAll(query) {
                                    let filterKeys = Object.keys(query).filter((key) => {
                                        return query[key] !== 'All'
                                    });
                                    return filterKeys;
                                }

                                function removeSalaryMinMax(keys) {
                                    let lessMinMax = keys.filter((ele) => {
                                        return ele !== 'salaryMin' && ele !== 'salaryMax';
                                    })
                                    return lessMinMax;
                                }

                                function checkCandidate(candidate) {
                                    for (var i = 0; i < filterKeyExcSalary.length; i++) {
                                        return candidate[filterKeyExcSalary[i]] === query[filterKeyExcSalary[i]] &&
                                            candidate[filterKeyExcSalary[i + 1]] === query[filterKeyExcSalary[i + 1]] &&
                                            candidate[filterKeyExcSalary[i + 2]] === query[filterKeyExcSalary[i + 2]] &&
                                            candidate[filterKeyExcSalary[i + 3]] === query[filterKeyExcSalary[i + 3]] &&
                                            candidate[filterKeyExcSalary[i + 4]] === query[filterKeyExcSalary[i + 4]]
                                    }
                                }

                                function convertSalaryToNumber(salaryString) {
                                    let salary = salaryString.split('£')[1].replace(/\,/g, '');
                                    salary = parseInt(salary);
                                    return salary;
                                }

                                function filterBySalaryMax(array, query) {
                                    let candidatesFiltered = array.filter((candidate) => {
                                        let salary = convertSalaryToNumber(candidate.salary);
                                        return salary <= query.salaryMax
                                    });
                                    return candidatesFiltered;
                                }

                                function filterBySalaryMin(array, query) {
                                    let candidatesFiltered = array.filter((candidate) => {
                                        let salary = convertSalaryToNumber(candidate.salary);
                                        return salary >= query.salaryMin
                                    })

                                    return candidatesFiltered;
                                }

                                function filterBySalaryRange(array, query) {
                                    let candidatesFiltered = array.filter((candidate) => {
                                        let salary = convertSalaryToNumber(candidate.salary);
                                        return salary >= query.salaryMin && salary <= query.salaryMax;
                                    })
                                    return candidatesFiltered;
                                }

                                function filtereredArray(filterKeyExcSalaryLength, query) {
                                    switch (true) {
                                        case (filterKeyExcSalaryLength === 0 && query.salaryMax !== 'All' && query.salaryMin === 'All'):
                                            return filterBySalaryMax(harnessTalentList, query)

                                        case (filterKeyExcSalaryLength > 0 && query.salaryMax !== 'All' && query.salaryMin === 'All'):
                                            return filterBySalaryMax(candidatesFilteredExcSalary, query);

                                        case (filterKeyExcSalaryLength === 0 && query.salaryMin !== 'All' && query.salaryMax === 'All'):
                                            return filterBySalaryMin(harnessTalentList, query);

                                        case (filterKeyExcSalaryLength > 0 && query.salaryMax === 'All' && query.salaryMin !== 'All'):
                                            return filterBySalaryMin(candidatesFilteredExcSalary, query);

                                        case (filterKeyExcSalaryLength === 0 && query.salaryMin !== 'All' && query.salaryMax !== 'All'):
                                            return filterBySalaryRange(harnessTalentList, query);

                                        case (filterKeyExcSalaryLength > 0 && query.salaryMin !== 'All' && query.salaryMax !== 'All'):
                                            return filterBySalaryRange(candidatesFilteredExcSalary, query);

                                        case (filterKeyExcSalaryLength > 0):
                                            return candidatesFilteredExcSalary;

                                        case (filterKeyExcSalaryLength === 0):
                                            return harnessTalentList;
                                    }
                                }
                            }
                        });
                    }
                }

            }, {
                method: 'POST',
                path: '/harnesstalent/interview/proposed',
                config: {
                    auth: {
                        strategy: 'hrns-cookie'
                            // scope: ['client', 'agent']
                    },
                    validate: {
                        payload: interviewSchema
                    },
                    handler: (request, reply) => {
                        ///  must update stage in db;
                        const newTimes = request.payload;
                        const clientId = request.auth.credentials.profile.id;
                        console.log(clientId);

                        const interviewId = uuid.v1() + 'interviewId';
                        newTimes.interviewId = interviewId;
                        newTimes.confirmed = false;

                        /// get the agency email and then send an email with a link to the agency with proposed
                        // job title and salary also link back to interview page. need to create interview hash include in link
                        let agencyId = newTimes.agencyId;
                        let cvid = newTimes.cvid;

                        client.hgetAsync(agencyId, 'email')
                            .then((agencyEmail) => {
                                newTimes.agencyEmail = agencyEmail;

                                client.hgetAsync(clientId, 'companyName')
                                    .then((clientCompanyName) => {
                                        newTimes.clientCompanyName = clientCompanyName;

                                        let newProposedInterview = Object.assign({}, proposedInterview);

                                        newProposedInterview.html = newProposedInterview.html
                                            .replace('-candidateName-', newTimes.candidateName)
                                            .replace('-jobTitle-', newTimes.jobTitle) //switch to client jobTitle.
                                            .replace('-companyName-', newTimes.clientCompanyName)
                                            .replace('-interviewId-', newTimes.interviewId);

                                        newProposedInterview.to = agencyEmail;
                                        mailgun.messages().send(newProposedInterview)

                                    })
                                    .then(() => {
                                        console.log('>>>>>>>>>>>>', interviewId, newTimes);
                                        let interview = cleanPayload(newTimes);
                                        client.hincrby(cvid, 'interviewsRequested', 1);
                                        client.hmsetAsync(interviewId, interview);
                                    })
                                    .then(() => {
                                        return reply(cvid);
                                    })
                                    .catch(() => {
                                        return reply(false)
                                    });
                            })
                    }
                }
            }

        ]);
    return next();
};

exports.register.attributes = {
    name: 'Clientharnesstalent'
};
<|endoftext|>


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

var emailSchema = new mongoose.Schema ({
    messageId: String,
    from: [{
        address: String,
        name: String
    }],
    to: [{
        address: String,
        name: String
    }],
    subject: String,
    html: String,
    text: String,
    date: Date
});

emailSchema.methods.toClient = function(){
    var obj = this.toObject();
    obj.id = obj._id;
    delete obj._id;
    return obj;
};

var Email = mongoose.model('email', emailSchema);

module.exports = Email;
<commit_msg>backend email model date adapted to ISO String<commit_after>var mongoose = require('mongoose');

var emailSchema = new mongoose.Schema ({
    messageId: String,
    from: [{
        address: String,
        name: String
    }],
    to: [{
        address: String,
        name: String
    }],
    subject: String,
    html: String,
    text: String,
    date: Date
});

emailSchema.methods.toClient = function(){
    var obj = this.toObject();
    obj.id = obj._id;
    obj.date = obj.date.toISOString();
    delete obj._id;
    return obj;
};

var Email = mongoose.model('email', emailSchema);

module.exports = Email;
<|endoftext|>


<commit_before>function Bullet(tt, bulletIndex, startx, starty, targetx, targety, speed) {
    var SELF = this;

    /** @type ThunderTanks */
    this.tt = tt;

    /** @type JSGameSoup */
    this.game = tt.game;

    var _private = {
        bulletIndex: bulletIndex,
        x: startx || this.game.width/2,
        y: starty || this.game.height/2,
        targetx: targetx || this.game.random(0,this.game.width),
        targety: targety || this.game.random(0,this.game.height),
        speed: speed || 10,
        radius: 3,
        angle: MathUtil.getAngle(startx,starty,targetx,targety),
        bounces: 1,
        animation: new Sprite(["center","center"], {
            "move": [[SELF.tt.urlPath + '/images/bullet1.png', 7],[SELF.tt.urlPath + '/images/bullet2.png', 7]]
        }, function() {
            _private.animation.action("move");
            _private.animation.angle(_private.angle);
        })
    };

    var _events = {
        /** change direction of bullet (anvil is the entity the bullet is hitting) */
        richochet: function(anvil) { // take your aim, fire away, fire away!
            entity_aabb = anvil.get_collision_aabb();
            bullet_aabb = SELF.get_collision_aabb();

            var topDiff = Math.abs(entity_aabb[1] - bullet_aabb[1]);
            var bottomDiff = Math.abs(entity_aabb[1] + entity_aabb[3] - bullet_aabb[1] + bullet_aabb[3]);
            var leftDiff = Math.abs(entity_aabb[0] - bullet_aabb[0]);
            var rightDiff = Math.abs(entity_aabb[0] + entity_aabb[2] - bullet_aabb[0] + bullet_aabb[2]);

            // if bullet is between entity top and bottom, its probably a side collision
            if (topDiff < leftDiff && topDiff < rightDiff ||
                bottomDiff < leftDiff && bottomDiff < rightDiff) {
                _private.angle *= -1;
            } else {
                _private.angle = MathUtil.degreesToRadians(180 - MathUtil.radiansToDegrees(_private.angle));
            }
            _private.animation.angle(_private.angle);
        }
    }

    /**
     * @param {JSGameSoup} gs JSGameSoup instance
     */
    this.update = function(gs) {
        // move bullet
        _private.x = _private.x + _private.speed * Math.cos(_private.angle);
        _private.y = _private.y + _private.speed * Math.sin(_private.angle);

        // update sprite
        _private.animation.update();

        var numSides = 8;
        _private.poly = [];
        for (var i = 0; i < numSides; i++) {
            var angle = i * Math.PI / (numSides / 2);
            var x = _private.x + _private.radius * Math.sin(angle);
            var y = _private.y + _private.radius * Math.cos(angle);
            _private.poly.push([x, y]);
        }
    }

    /**
     * @param {CanvasRenderingContext2D} c canvas context
     * @param {JSGameSoup} gs JSGameSoup instance
     */
    this.draw = function(c, gs) {
        // draw bullet
        c.beginPath();
        c.arc(_private.x, _private.y, _private.radius + 1, 0, 2 * Math.PI, false);
        c.lineWidth = 1;
        c.stroke();

        // draw sprite
        c.save(); //save the current draw state
        _private.animation.draw(c,[_private.x,_private.y]);
        c.restore(); //restore the previous draw state

        /** draw collision areas */
        if (tt.debug) {
            c.strokeStyle = '#ff00ff';
            c.beginPath();
            c.moveTo(_private.poly[0][0],_private.poly[0][1]);
            for(var p = 1; p < _private.poly.length; p++) {
              c.lineTo(_private.poly[p][0],_private.poly[p][1]);
            }
            c.closePath();
            c.stroke();
        }
    }

    this.kill = function() {
        this.tt.removeBullet(_private.bulletIndex);
    }

    /* @returns[Array] a rectangle of the boundaries of the entity with the form [x, y, w, h] */
    this.get_collision_aabb = function() {
        return [_private.x, _private.y, _private.radius, _private.radius];
    }

    /* @returns {Array} the center of the circle and the radius like this: return [[x, y], r] */
    this.get_collision_circle = function() {
        return [[_private.x,_private.y],_private.radius];
    }

    /** @returns {Array}  An array of lines of the form [[x1, y1], [x2, y2], ... [xn, yn]] */
    this.get_collision_poly = function() {
		return _private.poly;
    }

    this.collide_aabb = function(entity, result) {
        // bullet vs bullet (handled in collide_circle)

        // bullet vs tank = dead
        if (entity instanceof Tank) {
            SELF.kill();

        // bullet vs obstacle = bounce or die
        } else if (entity instanceof Block || entity instanceof Poly) {
            if (!_private.bounces) {
                this.kill();
            } else {
                _private.bounces--;
            }

            _events.richochet(entity);

            //if (entity instanceof Poly) {
            //    var polycollision = collide.collide_poly_entities(this,entity);
            //    if (polycollision) {
            //        _events.richochet(entity);
            //    }
            //} else {
            //    _events.richochet(entity);
            //}
        }
    }

    this.collide_circle = function(entity, result) {
        if (entity !== this) {
            this.kill();
        }
    }

    this.collide_polygon = function(entity, result) {
        console.log('bullet collide_polygon', entity, result);
    }
}<commit_msg>created Bullet moveForward event<commit_after>function Bullet(tt, bulletIndex, startx, starty, targetx, targety, speed) {
    var SELF = this;

    /** @type ThunderTanks */
    this.tt = tt;

    /** @type JSGameSoup */
    this.game = tt.game;

    var _private = {
        bulletIndex: bulletIndex,
        x: startx || this.game.width/2,
        y: starty || this.game.height/2,
        targetx: targetx || this.game.random(0,this.game.width),
        targety: targety || this.game.random(0,this.game.height),
        speed: speed || 10,
        radius: 3,
        angle: MathUtil.getAngle(startx,starty,targetx,targety),
        bounces: 1,
        animation: new Sprite(["center","center"], {
            "move": [[SELF.tt.urlPath + '/images/bullet1.png', 7],[SELF.tt.urlPath + '/images/bullet2.png', 7]]
        }, function() {
            _private.animation.action("move");
            _private.animation.angle(_private.angle);
        })
    };

    var _events = {
        moveForward: function(frames) {
            // move bullet
            _private.x = _private.x + (_private.speed * frames) * Math.cos(_private.angle);
            _private.y = _private.y + (_private.speed * frames) * Math.sin(_private.angle);
        },
        /** change direction of bullet (anvil is the entity the bullet is hitting) */
        richochet: function(anvil) { // take your aim, fire away, fire away!
            entity_aabb = anvil.get_collision_aabb();
            bullet_aabb = SELF.get_collision_aabb();

            var topDiff = Math.abs(entity_aabb[1] - bullet_aabb[1]);
            var bottomDiff = Math.abs(entity_aabb[1] + entity_aabb[3] - bullet_aabb[1] + bullet_aabb[3]);
            var leftDiff = Math.abs(entity_aabb[0] - bullet_aabb[0]);
            var rightDiff = Math.abs(entity_aabb[0] + entity_aabb[2] - bullet_aabb[0] + bullet_aabb[2]);

            // if bullet is between entity top and bottom, its probably a side collision
            if (topDiff < leftDiff && topDiff < rightDiff ||
                bottomDiff < leftDiff && bottomDiff < rightDiff) {
                _private.angle *= -1;
            } else {
                _private.angle = MathUtil.degreesToRadians(180 - MathUtil.radiansToDegrees(_private.angle));
            }
            _private.animation.angle(_private.angle);
        }
    }

    /**
     * @param {JSGameSoup} gs JSGameSoup instance
     */
    this.update = function(gs) {
        _events.moveForward(1);

        // update sprite
        _private.animation.update();

        var numSides = 8;
        _private.poly = [];
        for (var i = 0; i < numSides; i++) {
            var angle = i * Math.PI / (numSides / 2);
            var x = _private.x + _private.radius * Math.sin(angle);
            var y = _private.y + _private.radius * Math.cos(angle);
            _private.poly.push([x, y]);
        }
    }

    /**
     * @param {CanvasRenderingContext2D} c canvas context
     * @param {JSGameSoup} gs JSGameSoup instance
     */
    this.draw = function(c, gs) {
        // draw bullet
        c.beginPath();
        c.arc(_private.x, _private.y, _private.radius + 1, 0, 2 * Math.PI, false);
        c.lineWidth = 1;
        c.stroke();

        // draw sprite
        c.save(); //save the current draw state
        _private.animation.draw(c,[_private.x,_private.y]);
        c.restore(); //restore the previous draw state

        /** draw collision areas */
        if (tt.debug) {
            c.strokeStyle = '#ff00ff';
            c.beginPath();
            c.moveTo(_private.poly[0][0],_private.poly[0][1]);
            for(var p = 1; p < _private.poly.length; p++) {
              c.lineTo(_private.poly[p][0],_private.poly[p][1]);
            }
            c.closePath();
            c.stroke();
        }
    }

    this.kill = function() {
        this.tt.removeBullet(_private.bulletIndex);
    }

    /* @returns[Array] a rectangle of the boundaries of the entity with the form [x, y, w, h] */
    this.get_collision_aabb = function() {
        return [_private.x, _private.y, _private.radius, _private.radius];
    }

    /* @returns {Array} the center of the circle and the radius like this: return [[x, y], r] */
    this.get_collision_circle = function() {
        return [[_private.x,_private.y],_private.radius];
    }

    /** @returns {Array}  An array of lines of the form [[x1, y1], [x2, y2], ... [xn, yn]] */
    this.get_collision_poly = function() {
		return _private.poly;
    }

    this.collide_aabb = function(entity, result) {
        // bullet vs bullet (handled in collide_circle)

        // bullet vs tank = dead
        if (entity instanceof Tank) {
            SELF.kill();

        // bullet vs obstacle = bounce or die
        } else if (entity instanceof Block || entity instanceof Poly) {
            if (!_private.bounces) {
                this.kill();
            } else {
                _private.bounces--;
            }

            _events.richochet(entity);

            //if (entity instanceof Poly) {
            //    var polycollision = collide.collide_poly_entities(this,entity);
            //    if (polycollision) {
            //        _events.richochet(entity);
            //    }
            //} else {
            //    _events.richochet(entity);
            //}
        }
    }

    this.collide_circle = function(entity, result) {
        if (entity !== this) {
            this.kill();
        }
    }

    this.collide_polygon = function(entity, result) {
        console.log('bullet collide_polygon', entity, result);
    }
}<|endoftext|>


<commit_before>/* ============================================================
   tableCopy plugin
   Copy the selected table to the clipboard
   Returns a promise, which resolves true if the copy
   succeeds, false if it is cancelled.
   To Do: clean up hidden table cells, links, etc.
*/
;(function() {
    "use strict";
    jQuery.fn.tableCopy = function() {
        var deferred = new jQuery.Deferred();
        var clone = this.clone();
        var wrapper = $('<div>');
        wrapper.append(clone);
        var html = wrapper.html();

        return qcode.copy(html);
    }
})();<commit_msg>Support filtering table contents before copying<commit_after>/* ============================================================
   tableCopy plugin
   Copy the selected table to the clipboard
   Returns a promise, which resolves true if the copy
   succeeds, false if it is cancelled.
   To Do: clean up hidden table cells, links, etc.
*/
;(function() {
    "use strict";
    jQuery.fn.tableCopy = function(filter) {
        var deferred = new jQuery.Deferred();
        var clone = this.clone();
        if ( typeof filter === "function" ) {
            clone = filter(clone);
        }
        var wrapper = $('<div>');
        wrapper.append(clone);
        var html = wrapper.html();

        return qcode.copy(html);
    }
})();<|endoftext|>


<commit_before>/**
 * Created by paul on 5/7/15.
 */

'use strict';
Models.Build = function (doc) {
	this._doc = doc;
	if (!this._doc.displayCounter) {
		this._doc.displayCounter = 0;
	}
	if (this._doc.isLastBuildSuccess === undefined) {
		this._doc.isLastBuildSuccess = true;
	}
	if (this._doc.watchers === undefined) {
		this._doc.watchers = [];
	}
};

Models.Build.prototype = {
	//region Properties
	get _id() {
		return this._doc._id;
	},

	get serverId() {
		return this._doc.serverId;
	},

	get projectId() {
		return this._doc.projectId;
	},
	set projectId(value) {
		this._doc.projectId = value;
	},

	get serviceBuildId() {
		return this._doc.serviceBuildId;
	},

	get name() {
		return this._doc.name;
	},

	get href() {
		return this._doc.href;
	},

	get watchers() {
		return this._doc.watchers;
	},

	/**
	 * @returns {boolean}
	 */
	get isDisplayed() {
		return this.watchers.length > 0;
	},

	/**
	 * @returns {boolean}
	 */
	get isLastBuildSuccess() {
		return this._doc.isLastBuildSuccess;
	},

	/**
	 * @returns {boolean}
	 */
	get isBuilding() {
		return this._doc.isBuilding;
	},

	get builds() {
		return this._doc.builds;
	},
	set builds(value) {
		this._doc.builds = value;
	},
	//endregion

	//region Methods
	toJson: function () {
		return this._doc;
	},

	/**
	 *
	 * @param {Models.BuildDetail} buildDetail
	 * @private
	 */
	_updateBuild: function (buildDetail) {
		// Ensure that our build was started.
		if (this.builds.length > 0 && this.builds[0].id !== buildDetail.id) {
			return;
		}

		var set = {
			'builds.0.isBuilding': buildDetail.isBuilding,
			'builds.0.isSuccess': buildDetail.isSuccess,
			'builds.0.statusText': buildDetail.statusText,
			'builds.0.percentageComplete': buildDetail.percentageComplete
		};

		if (this.isLastBuildSuccess && !buildDetail.isSuccess) {
			set.isLastBuildSuccess = false;
			set.whoBrokeIt = buildDetail.usernames;
		}

		Collections.Builds.update({_id: this._id}, {$set: set});
	},

	/**
	 *
	 * @param {Models.BuildDetail} buildDetail
	 * @private
	 */
	_finishBuild: function (buildDetail) {
		Collections.Builds.update({_id: this._id}, {
			$set: {
				isLastBuildSuccess: buildDetail.isSuccess,
				isBuilding: false,
				'builds.0.isBuilding': buildDetail.isBuilding,
				'builds.0.isSuccess': buildDetail.isSuccess,
				'builds.0.statusText': buildDetail.statusText,
				'builds.0.percentageComplete': buildDetail.percentageComplete,
				'builds.0.finishDate': buildDetail.finishDate
			}
		});
	},

	/**
	 * Refreshes the build history data for this build.
	 *
	 * @param service
	 */
	refreshBuildData: function (service) {
		var self = this;
		service.getBuildData(self.href, 10, function (buildDetailsArray) {
			var isLastBuildSuccess = true,
				whoBrokeIt = null;
			if (buildDetailsArray.length > 0) {
				if (!buildDetailsArray[0].isSuccess) {
					isLastBuildSuccess = false;
					whoBrokeIt = buildDetailsArray[0].usernames;
				} else if (buildDetailsArray[0].isBuilding && buildDetailsArray.length > 1) {
					isLastBuildSuccess = buildDetailsArray[1].isSuccess;
					whoBrokeIt = buildDetailsArray[1].usernames;
				}
			}

			var buildData = _.map(buildDetailsArray, function (bd) {
				return bd.toJson();
			});

			Collections.Builds.update({_id: self._id}, {
				$set: {
					isLastBuildSuccess: isLastBuildSuccess,
					whoBrokeIt: whoBrokeIt,
					builds: buildData
				}
			});
		});
	},

	/**
	 * Starts a new build for this buildType.
	 *
	 * @param service
	 * @param href
	 */
	startBuild: function (service, href) {
		var self = this;
		service.getBuildDetails(href, function (buildDetail) {
			if (!self.builds) {
				self.builds = [];
			}

			self.builds.splice(0, 0, buildDetail.toJson());
			while (self.builds.length > 10) {
				self.builds.pop();
			}

			Collections.Builds.update({_id: self._id}, {$set: {isBuilding: true, builds: self.builds}});
		});
	},

	/**
	 * Updates the latest build information.
	 *
	 * @param service
	 */
	updateRunningBuild: function (service) {
		var self = this,
			build = self.builds[0];
		service.getBuildDetails(build.href, function (buildDetail) {
			self._updateBuild(buildDetail);
			if (!buildDetail.isBuilding) {
				self._finishBuild(buildDetail);
			}
		});
	},

	addWatcher: function (service, watcher) {
		if (_.contains(this.watchers, watcher)) {
			return;
		}

		this._doc.watchers.push(watcher);
		Collections.Builds.update({_id: this._id}, {
			$addToSet: {watchers: watcher},
			$set: {watcherCount: this.watchers.length}
		});

		if (this.watchers.length === 1 && service) {
			this.refreshBuildData(service);
		}
	},

	removeWatcher: function (watcher) {
		var nWatchers = _.reject(this.watchers, function (w) {
			return w === watcher;
		});

		if (nWatchers.length === this.watchers.length) {
			return;
		}

		this._doc.watchers = nWatchers;
		Collections.Builds.update({_id: this._id}, {$set: {watchers: nWatchers, watcherCount: this.watchers.length}});
	}
	//endregion
};
<commit_msg>Need to refresh build flag on startup.<commit_after>/**
 * Created by paul on 5/7/15.
 */

'use strict';
Models.Build = function (doc) {
	this._doc = doc;
	if (!this._doc.displayCounter) {
		this._doc.displayCounter = 0;
	}
	if (this._doc.isLastBuildSuccess === undefined) {
		this._doc.isLastBuildSuccess = true;
	}
	if (this._doc.watchers === undefined) {
		this._doc.watchers = [];
	}
};

Models.Build.prototype = {
	//region Properties
	get _id() {
		return this._doc._id;
	},

	get serverId() {
		return this._doc.serverId;
	},

	get projectId() {
		return this._doc.projectId;
	},
	set projectId(value) {
		this._doc.projectId = value;
	},

	get serviceBuildId() {
		return this._doc.serviceBuildId;
	},

	get name() {
		return this._doc.name;
	},

	get href() {
		return this._doc.href;
	},

	get watchers() {
		return this._doc.watchers;
	},

	/**
	 * @returns {boolean}
	 */
	get isDisplayed() {
		return this.watchers.length > 0;
	},

	/**
	 * @returns {boolean}
	 */
	get isLastBuildSuccess() {
		return this._doc.isLastBuildSuccess;
	},

	/**
	 * @returns {boolean}
	 */
	get isBuilding() {
		return this._doc.isBuilding;
	},

	get builds() {
		return this._doc.builds;
	},
	set builds(value) {
		this._doc.builds = value;
	},
	//endregion

	//region Methods
	toJson: function () {
		return this._doc;
	},

	/**
	 *
	 * @param {Models.BuildDetail} buildDetail
	 * @private
	 */
	_updateBuild: function (buildDetail) {
		// Ensure that our build was started.
		if (this.builds.length > 0 && this.builds[0].id !== buildDetail.id) {
			return;
		}

		var set = {
			'builds.0.isBuilding': buildDetail.isBuilding,
			'builds.0.isSuccess': buildDetail.isSuccess,
			'builds.0.statusText': buildDetail.statusText,
			'builds.0.percentageComplete': buildDetail.percentageComplete
		};

		if (this.isLastBuildSuccess && !buildDetail.isSuccess) {
			set.isLastBuildSuccess = false;
			set.whoBrokeIt = buildDetail.usernames;
		}

		Collections.Builds.update({_id: this._id}, {$set: set});
	},

	/**
	 *
	 * @param {Models.BuildDetail} buildDetail
	 * @private
	 */
	_finishBuild: function (buildDetail) {
		Collections.Builds.update({_id: this._id}, {
			$set: {
				isLastBuildSuccess: buildDetail.isSuccess,
				isBuilding: false,
				'builds.0.isBuilding': buildDetail.isBuilding,
				'builds.0.isSuccess': buildDetail.isSuccess,
				'builds.0.statusText': buildDetail.statusText,
				'builds.0.percentageComplete': buildDetail.percentageComplete,
				'builds.0.finishDate': buildDetail.finishDate
			}
		});
	},

	/**
	 * Refreshes the build history data for this build.
	 *
	 * @param service
	 */
	refreshBuildData: function (service) {
		var self = this;
		service.getBuildData(self.href, 10, function (buildDetailsArray) {
			var isLastBuildSuccess = true,
				whoBrokeIt = null,
				isBuilding = false;
			if (buildDetailsArray.length > 0) {
				isBuilding = buildDetailsArray[0].isBuilding;

				if (!buildDetailsArray[0].isSuccess) {
					isLastBuildSuccess = false;
					whoBrokeIt = buildDetailsArray[0].usernames;
				} else if (isBuilding && buildDetailsArray.length > 1) {
					isLastBuildSuccess = buildDetailsArray[1].isSuccess;
					whoBrokeIt = buildDetailsArray[1].usernames;
				}
			}

			var buildData = _.map(buildDetailsArray, function (bd) {
				return bd.toJson();
			});

			Collections.Builds.update({_id: self._id}, {
				$set: {
					isLastBuildSuccess: isLastBuildSuccess,
					whoBrokeIt: whoBrokeIt,
					builds: buildData,
					isBuilding: isBuilding
				}
			});
		});
	},

	/**
	 * Starts a new build for this buildType.
	 *
	 * @param service
	 * @param href
	 */
	startBuild: function (service, href) {
		var self = this;
		service.getBuildDetails(href, function (buildDetail) {
			if (!self.builds) {
				self.builds = [];
			}

			self.builds.splice(0, 0, buildDetail.toJson());
			while (self.builds.length > 10) {
				self.builds.pop();
			}

			Collections.Builds.update({_id: self._id}, {$set: {isBuilding: true, builds: self.builds}});
		});
	},

	/**
	 * Updates the latest build information.
	 *
	 * @param service
	 */
	updateRunningBuild: function (service) {
		var self = this,
			build = self.builds[0];
		service.getBuildDetails(build.href, function (buildDetail) {
			self._updateBuild(buildDetail);
			if (!buildDetail.isBuilding) {
				self._finishBuild(buildDetail);
			}
		});
	},

	addWatcher: function (service, watcher) {
		if (_.contains(this.watchers, watcher)) {
			return;
		}

		this._doc.watchers.push(watcher);
		Collections.Builds.update({_id: this._id}, {
			$addToSet: {watchers: watcher},
			$set: {watcherCount: this.watchers.length}
		});

		if (this.watchers.length === 1 && service) {
			this.refreshBuildData(service);
		}
	},

	removeWatcher: function (watcher) {
		var nWatchers = _.reject(this.watchers, function (w) {
			return w === watcher;
		});

		if (nWatchers.length === this.watchers.length) {
			return;
		}

		this._doc.watchers = nWatchers;
		Collections.Builds.update({_id: this._id}, {$set: {watchers: nWatchers, watcherCount: this.watchers.length}});
	}
	//endregion
};
<|endoftext|>


<commit_before>/**
 * Copyright 2015-present 650 Industries. All rights reserved.
 *
 * @providesModule Config
 */
'use strict';

export default {
  api: {
    // host: 'https://exp.host',
    host: 'https://ed56a018.ngrok.io',
  },
};
<commit_msg>Fix exponent/js tests, fix up error message in PushRouter<commit_after>/**
 * Copyright 2015-present 650 Industries. All rights reserved.
 *
 * @providesModule Config
 */
'use strict';

export default {
  api: {
    host: 'https://exp.host',
    // host: 'https://ed56a018.ngrok.io',
  },
};
<|endoftext|>


<commit_before>"use strict";

const webpack = require("webpack");
const path = require("path");

const DEV_ENV = "development";
const PRODUCTION_ENV = "production";
const NODE_ENV = process.env.NODE_ENV || DEV_ENV;

const SRC_PATH = path.join(__dirname, "src")
const DEST_PATH = path.join(__dirname, "public");

const COMMON_NAME = "common";

module.exports = {
  context: SRC_PATH,

  entry: {
    home: "./home/home",
    about: "./about/about"
  },

  output: {
    path: DEST_PATH,
    filename: "[name].js",
    library: "[name]"
  },

  watch: NODE_ENV == DEV_ENV,

  watchOptions: {
    aggregateOptions: 100
  },

  devtool: NODE_ENV == DEV_ENV ? "cheap-inline-module-source-map" : null,

  plugins: [
    new webpack.NoErrorsPlugin(),
    new webpack.DefinePlugin({
      NODE_ENV: JSON.stringify(NODE_ENV),
      DEV_ENV: JSON.stringify(DEV_ENV),
      LANG: '"ru"'
    }),
    new webpack.optimize.CommonsChunkPlugin({
      name: COMMON_NAME
    })
  ],

  resolve: {
    modulesDirectories: ["node_modules"],
    extentions: ["", ".js"]
  },

  resolveLoader: {
    modulesDirectories: ["node_modules"],
    moduleTemplates: ["*-loader", "*"],
    extentions: ["", ".js"]
  },

  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel"
      }
    ]
  }
};

if (NODE_ENV == PRODUCTION_ENV) {
  module.exports.plugins.push(
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        // don't show anreachable variables etc
        warnings: false,
        drop_console: false,
        unsafe: true
      }
    })
  )
}
<commit_msg>Work with options for CommonsChunkPlugin<commit_after>"use strict";

const webpack = require("webpack");
const path = require("path");

const DEV_ENV = "development";
const PRODUCTION_ENV = "production";
const NODE_ENV = process.env.NODE_ENV || DEV_ENV;

const SRC_PATH = path.join(__dirname, "src")
const DEST_PATH = path.join(__dirname, "public");

const COMMON_NAME = "common";

module.exports = {
  context: SRC_PATH,

  entry: {
    home: "./home/home",
    about: "./about/about"
  },

  output: {
    path: DEST_PATH,
    filename: "[name].js",
    library: "[name]"
  },

  watch: NODE_ENV == DEV_ENV,

  watchOptions: {
    aggregateOptions: 100
  },

  devtool: NODE_ENV == DEV_ENV ? "cheap-inline-module-source-map" : null,

  plugins: [
    new webpack.NoErrorsPlugin(),
    new webpack.DefinePlugin({
      NODE_ENV: JSON.stringify(NODE_ENV),
      DEV_ENV: JSON.stringify(DEV_ENV),
      LANG: '"ru"'
    }),
    new webpack.optimize.CommonsChunkPlugin({
      name: COMMON_NAME,
      chunks: [
        "about",
        "home"
      ]
    })
  ],

  resolve: {
    modulesDirectories: ["node_modules"],
    extentions: ["", ".js"]
  },

  resolveLoader: {
    modulesDirectories: ["node_modules"],
    moduleTemplates: ["*-loader", "*"],
    extentions: ["", ".js"]
  },

  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel"
      }
    ]
  }
};

if (NODE_ENV == PRODUCTION_ENV) {
  module.exports.plugins.push(
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        // don't show anreachable variables etc
        warnings: false,
        drop_console: false,
        unsafe: true
      }
    })
  )
}
<|endoftext|>


<commit_before>module.exports = function(grunt){
    return {
        "dev-build": ['clean:toolkit', 'compass:toolkit', 'requirejs:toolkit', 'jekyll:build'],
        "dev-spy": ['dev-build', 'watch'],

        //  standard build tasks that lints your JS
        "build": ['jshint', 'dev-build'],
        "spy": ['jshint', 'dev-spy'],

        //  misc tasks
        "fonts": ['clean:css', 'clean:fonts', 'svgmin:fonts', 'webfont', 'compass:toolkit'],
        "svgs": ['svgmin:icons', 'grunticon'],

        //  testing tasks
        "test-with-coverage": ['requirejs:beautify','jekyll:build', 'blanket_mocha'],
        "test-without-coverage": ['requirejs:uglify','jekyll:build', 'mocha'],
        "test-cross-browser": ['jekyll:build','connect', 'exec:browserstack'],
        "test-cross-browser-live": ['jekyll:build','connect', 'exec:browserstack-live'],

        //  alias
        "test": ['test-with-coverage'],
        "default": ['build']
    }
};<commit_msg>fix grunt aliases<commit_after>module.exports = {
    "dev-build": ['clean:toolkit', 'compass:toolkit', 'requirejs:toolkit', 'jekyll:build'],
    "dev-spy": ['dev-build', 'watch'],

    //  standard build tasks that lints your JS
    "build": ['jshint', 'dev-build'],
    "spy": ['jshint', 'dev-spy'],

    //  misc tasks
    "fonts": ['clean:css', 'clean:fonts', 'svgmin:fonts', 'webfont', 'compass:toolkit'],
    "svgs": ['svgmin:icons', 'grunticon'],

    //  testing tasks
    "test-with-coverage": ['requirejs:beautify','jekyll:build', 'blanket_mocha'],
    "test-without-coverage": ['requirejs:uglify','jekyll:build', 'mocha'],
    "test-cross-browser": ['jekyll:build','connect', 'exec:browserstack'],
    "test-cross-browser-live": ['jekyll:build','connect', 'exec:browserstack-live'],

    //  alias
    "test": ['test-with-coverage'],
    "default": ['build']
};<|endoftext|>


<commit_before>export const getViewport = () => ({
  height: window.innerHeight || document.documentElement.offsetHeight,
  width: window.innerWidth || document.documentElement.offsetWidth,
});

export const isElementOverflowing = (element) => element.clientWidth < element.scrollWidth || element.clientHeight < element.scrollHeight;
<commit_msg>Prettier Linting™<commit_after>export const getViewport = () => ({
  height: window.innerHeight || document.documentElement.offsetHeight,
  width: window.innerWidth || document.documentElement.offsetWidth,
});

export const isElementOverflowing = element =>
  element.clientWidth < element.scrollWidth || element.clientHeight < element.scrollHeight;
<|endoftext|>