<commit_before>/*jslint white: true nomen: true plusplus: true */
/*global mx, mxui, mendix, dojo, require, console, define, module, logger */
/**
	Signature
	========================

	@file      : Signature.js
	@version   : 2.0
	@author    : Maxim Oei, Richard Edens, Roeland Salij
	@date      : 22-08-2014
	@copyright : Mendix Technology BV
	@license   : Apache License, Version 2.0, January 2004

	Documentation
    ========================
	Complete any delivery service App with this Signature widget.
    This widget allows you to save a signature to an attribute.
*/
(function() {
    require([

        'mxui/widget/_WidgetBase', 'dijit/_Widget', 'dijit/_TemplatedMixin',
        'mxui/dom', 'dojo/dom', 'dojo/dom-construct', 'dojo/ready', 'dojo/query', 'dojo/dom-prop', 'dojo/dom-geometry', 'dojo/dom-class', 'dojo/dom-style', 'dojo/on', 'dojo/_base/lang', 'dojo/_base/declare', 'dojo/text'

    ], function(_WidgetBase, _Widget, _Templated, domMx,dom, domConstruct, domReady, domQuery, domProp, domGeom, domClass, domStyle, on, lang, declare, text) {

        return declare('Signature.widget.Signature', [ _WidgetBase, _Widget, _Templated ], {
            _wgtNode: null,
            _contextGuid: null,
            _contextObj: null,
            _handle: null,

            _smoothingpct: 0.9,

            _mxObject: null,
            _attribute: null,
            _path: null,

            _canvas: null,
            _reset: null,
            _context: null,

            _timer: null,

            _touchSupport: false,
            _bezierBuf: null,

            templatePath: dojo.moduleUrl('Signature', 'widget/templates/Signature.html'),

            postCreate: function() {
                console.log('Signature - postCreate');

                this._setupWidget();
                this._setupEvents();
            },

            startup: function() {
                this.set('disabled', this.readonly);

                var path = this.dataUrl.split('/');
                this._attribute = path[path.length - 1];
                this._path = path.splice(0, path.length - 1);
            },

            update: function(obj, callback) {
                if (obj) {
                    obj.fetch(this._path, dojo.hitch(this, function(obj) {
                        this._updateObject(obj, callback);
                    }));
                } else {
                    this._updateObject(null, callback);
                }
            },

            enable: function() {
                dojo.attr(this._reset, 'disabled', false);
                dojo.removeClass(this.domNode, 'signhereSignature_disabled');
            },

            disable: function() {
                dojo.attr(this._reset, 'disabled', true);
                dojo.addClass(this.domNode, 'signhereSignature_disabled');
            },

            _setupWidget: function() {
                var t = this._smoothingpct,
                    u = 1 - t;

                this._wgtNode = this.domNode;

                this._bezier1 = t * t * t;
                this._bezier2 = 3 * t * t * u;
                this._bezier3 = 3 * t * u * u;
                this._bezier4 = u * u * u;

                this._bezierBuf = [];

                this._touchSupport = window.hasOwnProperty('ontouchstart');

                this._createUI();
            },

            _updateObject: function(obj, callback) {
                this._mxObject = obj;

                this._resetCanvas();

                if (this._attribute && obj && obj.get(this._attribute)) {
                    this._showImage();
                } else {
                    this._hideImage();
                }

                this.set('disabled', obj ? false : true);

                mendix.lang.nullExec(callback);
            },

            _createUI: function() {
                var $ = domConstruct.create,
                    sizeProperties = {
                        'width': this.width + 'px',
                        'height': this.height + 'px'
                    },
                    allProperties = lang.mixin(sizeProperties, {
                        'style': 'border: ' + this.gridborder + 'px solid ' + this.gridcolor
                    });

                this._canvas = $('canvas', allProperties);
                this._image  = $('img', allProperties);

                this._reset = $('button', {
                    'class': 'btn',
                    'style': {
                        'width': (this.width + 4) + 'px'
                    },
                    'innerHTML':  this.resetcaption
                });

                this.domNode.appendChild(this._canvas);
                this.domNode.appendChild(this._image);
                this.domNode.appendChild(this._reset);

                domStyle.set(this.domNode, sizeProperties);

                this._context = this._canvas.getContext('2d');
            },

            _showImage: function() {
                this._image.src = this._mxObject.get(this.dataUrl);

                dojo.replaceClass(this.domNode, 'signature_set', 'signature_unset');
            },

            _hideImage: function() {
                this._image.src = '';

                domClass.replace(this.domNode, 'signature_unset', 'signature_set');
            },

            _drawGrid: function() {
                if (!this.showgrid) {
                    return;
                }

                var x = this.gridx,
                    y = this.gridy,
                    context = this._context,
                    width   = this._canvas.width,
                    height  = this._canvas.height;

                context.beginPath();

                for (x; x < width; x += this.gridx) {
                    context.moveTo(x, 0);
                    context.lineTo(x, this._canvas.height);
                }

                for (y; y < height; y += this.gridy) {
                    context.moveTo(0, y);
                    context.lineTo(this._canvas.width, y);
                }

                context.lineWidth   = 1;
                context.strokeStyle = this.gridcolor;
                context.stroke();
            },

            _setupEvents: function() {
                this.connect(this._canvas, (this._touchSupport ? 'touchstart' : 'mousedown'), '_eventMouseDown');
                this.connect(this._reset, 'click', dojo.hitch(this, this._eventResetClicked));

                // This prevents the 'dragging image' annoyance when someone tries to
                // draw on the image.
                this.connect(
                    this._image,
                    this._touchSupport ? 'touchstart' : 'mousedown',
                    function(e) {
                        dojo.stopEvent(e);
                        return false;
                    }
                );
            },

            _getCoords: function(e) {
                var pos   = dojo.position(this._canvas, true),
                    pageX = e.targetTouches ? e.targetTouches[0].pageX : e.pageX,
                    pageY = e.targetTouches ? e.targetTouches[0].pageY : e.pageY,
                    x     = Math.floor(pageX - pos.x),
                    y     = Math.floor(pageY - pos.y);

                return { x: x, y: y };
            },

            _beginCurve: function(e) {
                this._bezierBuf = [];
                this._handlers = [];

                this._stopTimeout();

                this._context.strokeStyle = this.pencolor;
                this._context.lineJoin    = 'round';
                this._context.lineWidth   = this.pensize;

                this._context.beginPath();

                this._handlers.push(this.connect(window, this._touchSupport ? 'touchmove' : 'mousemove', dojo.hitch(this, this._eventMouseMove)));
                this._handlers.push(this.connect(window, this._touchSupport ? 'touchend' : 'mouseup', dojo.hitch(this, this._eventMouseUp)));
            },

            _updateCurve: function(e) {
                console.log(this.id + '.updateCurve');

                var context = this._context,
                    buf = this._bezierBuf,
                    pos = this._getCoords(e),
                    bp = null;

                this._stopTimeout();

                if (this._movedTo) {
                    buf.push(pos);

                    if (buf.length === 4) {
                        bp = this._bezierPoint.apply(this, buf);

                        context.lineTo(bp.x, bp.y);
                        context.stroke();

                        buf.shift();
                        buf[0] = bp;
                    }
                } else {
                    context.moveTo(pos.x, pos.y);
                    this._movedTo = true;
                }
            },

            _endCurve: function() {
                var buf = this._bezierBuf,
                    i = 0,
                    pos = null,
                    j = 0,
                    handlers = null;

                this._stopTimeout();

                // Finish last points in Bezier buffer
                while(buf[i]) {
                    pos = buf[i];
                    this._context.lineTo(pos.x, pos.y);
                    i++;
                }
                this._context.stroke();

                this._bezierBuf = null;

                while(this._handlers[j]){
                    handlers = this._handlers[j];
                    this.disconnect(handlers);
                    j++;
                }

                this._timer = setTimeout(dojo.hitch(this, this._finalizeSignature), this.timeout);
            },

            _eventMouseDown: function(e) {
                console.log(this.id + '._eventMouseDown');

                dojo.stopEvent(e);

                if (!this.get('disabled')) {
                    this._beginCurve(e);
                }
            },

            _eventMouseMove: function(e) {
                console.log(this.id + '._eventMouseMove');

                dojo.stopEvent(e);

                this._updateCurve(e);
            },

            _eventMouseUp: function(e) {
                console.log(this.id + '._eventMouseUp');

                dojo.stopEvent(e);

                this._endCurve();
            },

            _eventResetClicked: function(e) {
                console.log(this.id + '._eventResetClicked');

                if (!this.get('disabled')) {
                    this._resetMxObject();
                    this._resetCanvas();

                    this._hideImage();
                }
            },

            _resetCanvas: function() {
                console.log(this.id + '.resetCanvas');

                this._context.clearRect(0, 0, this._canvas.width, this._canvas.height);

                this._bezierBuf = [];

                this._drawGrid();
            },

            _resetMxObject: function() {
                console.log(this.id + '.resetMxObject');

                this._mxObject.set(this.dataUrl, '');
            },

            _stopTimeout: function() {
                console.log(this.id + '._stopTimeout');

                if (this._timer) {
                    clearTimeout(this._timer);
                }
            },

            _finalizeSignature: function() {
                console.log(this.id + '.finalizeSignature');

                var mxobj = this._mxObject;
                if (mxobj) {
                    if (mxobj.has(this.dataUrl)) {
                        mxobj.set(this.dataUrl, this._canvas.toDataURL());
                    } else {
                        logger.error(this.id + '.finalizeSignature: no dataUrl attribute found.');
                    }
                }

                this._showImage();
            },

            _bezierPoint: function(c1, c2, c3, c4) {
                return {
                    x: c1.x * this._bezier1 + c2.x * this._bezier2 +
                        c3.x * this._bezier3 + c4.x * this._bezier4,
                    y: c1.y * this._bezier1 + c2.y * this._bezier2 +
                        c3.y * this._bezier3 + c4.y * this._bezier4
                };
            },

            _setDisabledAttr: function(value) {
                var argumentsCopy = [];

                if (typeof this._attribute === 'undefined' || this._attribute === null) {
                    this._attribute = '';
                }
                if (this.readonly || !this._mxObject || this._mxObject.isReadonlyAttr(this._attribute)) {
                    value = true;
                }

                return this.inherited(arguments, [ value ]);
            }
        });
    });
}());<commit_msg>Increase readability of the code<commit_after>/*jslint white: true nomen: true plusplus: true */
/*global mx, mxui, mendix, dojo, require, console, define, module, logger */
/**
	Signature
	========================

	@file      : Signature.js
	@version   : 2.0
	@author    : Maxim Oei, Richard Edens, Roeland Salij
	@date      : 22-08-2014
	@copyright : Mendix Technology BV
	@license   : Apache License, Version 2.0, January 2004

	Documentation
    ========================
	Complete any delivery service App with this Signature widget.
    This widget allows you to save a signature to an attribute.
*/
(function() {
    require([

        'mxui/widget/_WidgetBase', 'dijit/_Widget', 'dijit/_TemplatedMixin',
        'mxui/dom', 'dojo/dom', 'dojo/dom-construct', 'dojo/ready', 'dojo/query', 'dojo/dom-prop', 'dojo/dom-geometry', 'dojo/dom-class', 'dojo/dom-style', 'dojo/on', 'dojo/_base/lang', 'dojo/_base/declare', 'dojo/text'

    ], function(_WidgetBase, _Widget, _Templated, domMx,dom, domConstruct, domReady, domQuery, domProp, domGeom, domClass, domStyle, on, lang, declare, text) {

        return declare('Signature.widget.Signature', [ _WidgetBase, _Widget, _Templated ], {
            _wgtNode: null,
            _contextGuid: null,
            _contextObj: null,
            _handle: null,

            _smoothingpct: 0.9,

            _mxObject: null,
            _attribute: null,
            _path: null,

            _canvas: null,
            _reset: null,
            _context: null,

            _timer: null,

            _touchSupport: false,
            _bezierBuf: null,

            templatePath: dojo.moduleUrl('Signature', 'widget/templates/Signature.html'),

            postCreate: function() {
                console.log('Signature - postCreate');

                this._setupWidget();
                this._createUI();
                this._setupEvents();
            },

            startup: function() {
                this.set('disabled', this.readonly);

                var path = this.dataUrl.split('/');
                this._attribute = path[path.length - 1];
                this._path = path.splice(0, path.length - 1);
            },

            update: function(obj, callback) {
                if (obj) {
                    obj.fetch(this._path, dojo.hitch(this, function(obj) {
                        this._updateObject(obj, callback);
                    }));
                } else {
                    this._updateObject(null, callback);
                }
            },

            enable: function() {
                dojo.attr(this._reset, 'disabled', false);
                dojo.removeClass(this.domNode, 'signhereSignature_disabled');
            },

            disable: function() {
                dojo.attr(this._reset, 'disabled', true);
                dojo.addClass(this.domNode, 'signhereSignature_disabled');
            },

            _setupWidget: function() {
                var t = this._smoothingpct,
                    u = 1 - t;

                this._wgtNode = this.domNode;

                this._bezier1 = t * t * t;
                this._bezier2 = 3 * t * t * u;
                this._bezier3 = 3 * t * u * u;
                this._bezier4 = u * u * u;

                this._bezierBuf = [];

                this._touchSupport = window.hasOwnProperty('ontouchstart');
            },

            _createUI: function() {
                var $ = domConstruct.create,
                    sizeProperties = {
                        'width': this.width + 'px',
                        'height': this.height + 'px'
                    },
                    allProperties = lang.mixin(sizeProperties, {
                        'style': 'border: ' + this.gridborder + 'px solid ' + this.gridcolor
                    });

                this._canvas = $('canvas', allProperties);
                this._image  = $('img', allProperties);

                this._reset = $('button', {
                    'class': 'btn',
                    'style': {
                        'width': (this.width + 4) + 'px'
                    },
                    'innerHTML':  this.resetcaption
                });

                this.domNode.appendChild(this._canvas);
                this.domNode.appendChild(this._image);
                this.domNode.appendChild(this._reset);

                domStyle.set(this.domNode, sizeProperties);

                this._context = this._canvas.getContext('2d');
            },

            _updateObject: function(obj, callback) {
                this._mxObject = obj;

                this._resetCanvas();

                if (this._attribute && obj && obj.get(this._attribute)) {
                    this._showImage();
                } else {
                    this._hideImage();
                }

                this.set('disabled', obj ? false : true);

                mendix.lang.nullExec(callback);
            },

            _showImage: function() {
                this._image.src = this._mxObject.get(this.dataUrl);

                dojo.replaceClass(this.domNode, 'signature_set', 'signature_unset');
            },

            _hideImage: function() {
                this._image.src = '';

                domClass.replace(this.domNode, 'signature_unset', 'signature_set');
            },

            _drawGrid: function() {
                if (!this.showgrid) {
                    return;
                }

                var x = this.gridx,
                    y = this.gridy,
                    context = this._context,
                    width   = this._canvas.width,
                    height  = this._canvas.height;

                context.beginPath();

                for (x; x < width; x += this.gridx) {
                    context.moveTo(x, 0);
                    context.lineTo(x, this._canvas.height);
                }

                for (y; y < height; y += this.gridy) {
                    context.moveTo(0, y);
                    context.lineTo(this._canvas.width, y);
                }

                context.lineWidth   = 1;
                context.strokeStyle = this.gridcolor;
                context.stroke();
            },

            _setupEvents: function() {
                this.connect(this._canvas, (this._touchSupport ? 'touchstart' : 'mousedown'), '_eventMouseDown');
                this.connect(this._reset, 'click', dojo.hitch(this, this._eventResetClicked));

                // This prevents the 'dragging image' annoyance when someone tries to
                // draw on the image.
                this.connect(
                    this._image,
                    this._touchSupport ? 'touchstart' : 'mousedown',
                    function(e) {
                        dojo.stopEvent(e);
                        return false;
                    }
                );
            },

            _getCoords: function(e) {
                var pos   = dojo.position(this._canvas, true),
                    pageX = e.targetTouches ? e.targetTouches[0].pageX : e.pageX,
                    pageY = e.targetTouches ? e.targetTouches[0].pageY : e.pageY,
                    x     = Math.floor(pageX - pos.x),
                    y     = Math.floor(pageY - pos.y);

                return { x: x, y: y };
            },

            _beginCurve: function(e) {
                this._bezierBuf = [];
                this._handlers = [];

                this._stopTimeout();

                this._context.strokeStyle = this.pencolor;
                this._context.lineJoin    = 'round';
                this._context.lineWidth   = this.pensize;

                this._context.beginPath();

                this._handlers.push(this.connect(window, this._touchSupport ? 'touchmove' : 'mousemove', dojo.hitch(this, this._eventMouseMove)));
                this._handlers.push(this.connect(window, this._touchSupport ? 'touchend' : 'mouseup', dojo.hitch(this, this._eventMouseUp)));
            },

            _updateCurve: function(e) {
                console.log(this.id + '.updateCurve');

                var context = this._context,
                    buf = this._bezierBuf,
                    pos = this._getCoords(e),
                    bp = null;

                this._stopTimeout();

                if (this._movedTo) {
                    buf.push(pos);

                    if (buf.length === 4) {
                        bp = this._bezierPoint.apply(this, buf);

                        context.lineTo(bp.x, bp.y);
                        context.stroke();

                        buf.shift();
                        buf[0] = bp;
                    }
                } else {
                    context.moveTo(pos.x, pos.y);
                    this._movedTo = true;
                }
            },

            _endCurve: function() {
                var buf = this._bezierBuf,
                    i = 0,
                    pos = null,
                    j = 0,
                    handlers = null;

                this._stopTimeout();

                // Finish last points in Bezier buffer
                while(buf[i]) {
                    pos = buf[i];
                    this._context.lineTo(pos.x, pos.y);
                    i++;
                }
                this._context.stroke();

                this._bezierBuf = null;

                while(this._handlers[j]){
                    handlers = this._handlers[j];
                    this.disconnect(handlers);
                    j++;
                }

                this._timer = setTimeout(dojo.hitch(this, this._finalizeSignature), this.timeout);
            },

            _eventMouseDown: function(e) {
                console.log(this.id + '._eventMouseDown');

                dojo.stopEvent(e);

                if (!this.get('disabled')) {
                    this._beginCurve(e);
                }
            },

            _eventMouseMove: function(e) {
                console.log(this.id + '._eventMouseMove');

                dojo.stopEvent(e);

                this._updateCurve(e);
            },

            _eventMouseUp: function(e) {
                console.log(this.id + '._eventMouseUp');

                dojo.stopEvent(e);

                this._endCurve();
            },

            _eventResetClicked: function(e) {
                console.log(this.id + '._eventResetClicked');

                if (!this.get('disabled')) {
                    this._resetMxObject();
                    this._resetCanvas();

                    this._hideImage();
                }
            },

            _resetCanvas: function() {
                console.log(this.id + '.resetCanvas');

                this._context.clearRect(0, 0, this._canvas.width, this._canvas.height);

                this._bezierBuf = [];

                this._drawGrid();
            },

            _resetMxObject: function() {
                console.log(this.id + '.resetMxObject');

                this._mxObject.set(this.dataUrl, '');
            },

            _stopTimeout: function() {
                console.log(this.id + '._stopTimeout');

                if (this._timer) {
                    clearTimeout(this._timer);
                }
            },

            _finalizeSignature: function() {
                console.log(this.id + '.finalizeSignature');

                var mxobj = this._mxObject;
                if (mxobj) {
                    if (mxobj.has(this.dataUrl)) {
                        mxobj.set(this.dataUrl, this._canvas.toDataURL());
                    } else {
                        logger.error(this.id + '.finalizeSignature: no dataUrl attribute found.');
                    }
                }

                this._showImage();
            },

            _bezierPoint: function(c1, c2, c3, c4) {
                return {
                    x: c1.x * this._bezier1 + c2.x * this._bezier2 +
                        c3.x * this._bezier3 + c4.x * this._bezier4,
                    y: c1.y * this._bezier1 + c2.y * this._bezier2 +
                        c3.y * this._bezier3 + c4.y * this._bezier4
                };
            },

            _setDisabledAttr: function(value) {
                var argumentsCopy = [];

                if (typeof this._attribute === 'undefined' || this._attribute === null) {
                    this._attribute = '';
                }
                if (this.readonly || !this._mxObject || this._mxObject.isReadonlyAttr(this._attribute)) {
                    value = true;
                }

                return this.inherited(arguments, [ value ]);
            }
        });
    });
}());<|endoftext|>


<commit_before>/**
 * peter-piper.js
 * ==============
 *
 * Count the number of times a capital `P` or lowercase `p` shows up in the
 * Peter Piper tongue twister.
 *
 * Hint
 * ----
 * Read the 'References' section in the README, which contains links to some
 * JavaScript methods and language features that might be helpful.
 */

var peterpiper = '';
peterpiper += "Peter Piper picked a peck of pickled peppers.";
peterpiper += "A peck of pickled peppers Peter Piper picked.";
peterpiper += "If Peter Piper picked a peck of pickled peppers,";
peterpiper += "Where's the peck of pickled peppers Peter Piper picked?";

var counter = 0;

// TODO: Count the number of times an uppercase P or lowercase p character
//       occurs in the `peterpiper` string.

// var char = 'P';

// for (var i=0; i.length<1; i++){
//     if (char= "P") {
//         counter++;
//     }

//     else (char= "p"){

//     }
// }

for (var i=0; i.length<1; i++){
if(peterpiper.charAt(i) == 'P'){
    counter++;
}
if (peterpiper.charAt(i) == 'p'){
    counter++;
}
}

console.log("There are " + counter + " P's in Peter Piper.");

<commit_msg>DONE!<commit_after>/**
 * peter-piper.js
 * ==============
 *
 * Count the number of times a capital `P` or lowercase `p` shows up in the
 * Peter Piper tongue twister.
 *
 * Hint
 * ----
 * Read the 'References' section in the README, which contains links to some
 * JavaScript methods and language features that might be helpful.
 */

var peterpiper = '';
peterpiper += "Peter Piper picked a peck of pickled peppers.";
peterpiper += "A peck of pickled peppers Peter Piper picked.";
peterpiper += "If Peter Piper picked a peck of pickled peppers,";
peterpiper += "Where's the peck of pickled peppers Peter Piper picked?";

var counter = 0;

// TODO: Count the number of times an uppercase P or lowercase p character
//       occurs in the `peterpiper` string.

for (var i = 0; i < peterpiper.length; i++) {
    if (peterpiper.charAt(i) == 'P') {
        counter++;
    }
    if (peterpiper.charAt(i) == 'p') {
        counter++;
    }
}

console.log("There are " + counter + " P's in Peter Piper.");

<|endoftext|>


<commit_before>Meteor.publish('available-rounds', function() {
    if (this.userId) {
        var now = new Date();
        return Rounds.find({
            opens: {$lte: now},
            closes: {$gte: now}
        });
    }
});

Meteor.publish('available-appointments', function(roundId) {
    if (this.userId) {
        // if clock is over 18, don't allow reservations for tomorrow
        var earliest;
        if (moment().hour() >= 18) {
            earliest = moment().add('days', 2).startOf('day').toDate();
        } else {
            earliest = moment().add('days', 1).startOf('day').toDate();
        }
        return Appointments.find(
            {
                round: roundId,
                start: {$gt: earliest},
                $or: [
                    {student: null},
                    {student: this.userId}
                ]
            },
            {fields: {assistant: 0}}
        );
    }
});

Meteor.publish('my-appointments', function() {
    if (this.userId) {
        var now = new Date();
        return Appointments.find(
            {
                $or: [
                    {assistant: this.userId, student: {$ne: null}},
                    {student: this.userId}
                ]
            },
            {fields: {assistant: 0}}
        );
    }
});

// publish all events in db to admins
Meteor.publish('all-appointments', function() {
    if (this.userId) {
        var user = Meteor.users.findOne(this.userId);
        if (user.profile.admin) {
            return Appointments.find();
        }
    }
});

Meteor.publish('all-rounds', function() {
    if (this.userId) {
        var user = Meteor.users.findOne(this.userId);
        if (user.profile.admin) {
            return Rounds.find();
        }
    }
});

Meteor.publish('all-users', function() {
    if (this.userId) {
        var user = Meteor.users.findOne(this.userId);
        if (user.profile.admin) {
            return Meteor.users.find();
        }
    }
});
<commit_msg>Another try to fix published appointments<commit_after>Meteor.publish('available-rounds', function() {
    if (this.userId) {
        var now = new Date();
        return Rounds.find({
            opens: {$lte: now},
            closes: {$gte: now}
        });
    }
});

Meteor.publish('available-appointments', function(roundId) {
    if (this.userId) {
        // if clock is over 18, don't allow reservations for tomorrow
        var earliest;
        if (moment().hour() >= 18) {
            earliest = moment().add('days', 2).startOf('day').toDate();
        } else {
            earliest = moment().add('days', 1).startOf('day').toDate();
        }
        return Appointments.find(
            {
                round: roundId,
                start: {$gt: earliest},
                student: null
            },
            {fields: {assistant: 0}}
        );
    }
});

Meteor.publish('my-appointments', function() {
    if (this.userId) {
        var now = new Date();
        return Appointments.find(
            {
                $or: [
                    {assistant: this.userId, student: {$ne: null}},
                    {student: this.userId}
                ]
            },
            {fields: {assistant: 0}}
        );
    }
});

// publish all events in db to admins
Meteor.publish('all-appointments', function() {
    if (this.userId) {
        var user = Meteor.users.findOne(this.userId);
        if (user.profile.admin) {
            return Appointments.find();
        }
    }
});

Meteor.publish('all-rounds', function() {
    if (this.userId) {
        var user = Meteor.users.findOne(this.userId);
        if (user.profile.admin) {
            return Rounds.find();
        }
    }
});

Meteor.publish('all-users', function() {
    if (this.userId) {
        var user = Meteor.users.findOne(this.userId);
        if (user.profile.admin) {
            return Meteor.users.find();
        }
    }
});
<|endoftext|>


<commit_before>/*
 * Authored by  AlmogBaku
 *              almog.baku@gmail.com
 *              http://www.almogbaku.com/
 *
 * 18/01/15 00:23
 */

'use strict';

angular.module('app')
  .controller('connectionCtrl', function($scope, $linkedin, $state, $rootScope, $stateParams, hotkeys, $analytics) {
    if(!$rootScope.loggedIn){
      $state.go('home');
      return;
    }

    $scope.connection = $linkedin.getConnectionByIdx($stateParams.idx);
    $scope.last = $linkedin.getLastConnectionIdx();

    function flag(e, hotkey) {
      var flag = hotkey.combo[0];
      $scope.connection.flag(flag);
      $analytics.eventTrack('flag', { flag: flag });
      next();
    }
    function next() {
      if($scope.connection.idx===$scope.last) {
        $state.go("finish");
      } else {
        $state.go("connection", {idx: $scope.connection.idx+1 });
      }
    }

    hotkeys.bindTo($scope)
      .add({
        combo: ['n','3'],
        description: 'Need intro',
        callback: flag
      })
      .add({
        combo: ['0', 'x'],
        description: 'Not relevant',
        callback: flag
      })
      .add({
        combo: '1',
        description: 'Will help',
        callback: flag
      })
      .add({
        combo: '2',
        description: 'Will help a lot! (good-friend)',
        callback: flag
      })
      .add({
        combo: 'right',
        description: 'Next (skip)',
        callback: next
      })
      .add({
        combo: 'j',
        description: 'Jump back to the first skipped connection',
        callback: function() {
          var conn = $linkedin.getFirstNotFlagged();
          if(conn===false) {
            $state.go("finish");
          } else {
            $state.go("connection", {idx: conn.idx });
          }
        }
      })
      .add({
        combo: 'r',
        description: 'Skip to the results report',
        callback: function() {
          $state.go("report");
        }
      })
    ;

    //back
    if($scope.connection.idx>0) {
      hotkeys.bindTo($scope)
        .add({
          combo: 'left',
          description: 'back',
          callback: function() {
            if($scope.connection.idx>0) {
              $state.go("connection", {idx: $scope.connection.idx-1 });
            }
          }
        })
      ;
    }
  })
;<commit_msg>add analytics<commit_after>/*
 * Authored by  AlmogBaku
 *              almog.baku@gmail.com
 *              http://www.almogbaku.com/
 *
 * 18/01/15 00:23
 */

'use strict';

angular.module('app')
  .controller('connectionCtrl', function($scope, $linkedin, $state, $rootScope, $stateParams, hotkeys, $analytics) {
    if(!$rootScope.loggedIn){
      $state.go('home');
      return;
    }

    $analytics.pageTrack('/connection');

    $scope.connection = $linkedin.getConnectionByIdx($stateParams.idx);
    $scope.last = $linkedin.getLastConnectionIdx();

    function flag(e, hotkey) {
      var flag = hotkey.combo[0];
      $scope.connection.flag(flag);
      $analytics.eventTrack('flag', { flag: flag });
      next();
    }
    function next() {
      if($scope.connection.idx===$scope.last) {
        $state.go("finish");
      } else {
        $state.go("connection", {idx: $scope.connection.idx+1 });
      }
    }

    hotkeys.bindTo($scope)
      .add({
        combo: ['n','3'],
        description: 'Need intro',
        callback: flag
      })
      .add({
        combo: ['0', 'x'],
        description: 'Not relevant',
        callback: flag
      })
      .add({
        combo: '1',
        description: 'Will help',
        callback: flag
      })
      .add({
        combo: '2',
        description: 'Will help a lot! (good-friend)',
        callback: flag
      })
      .add({
        combo: 'right',
        description: 'Next (skip)',
        callback: next
      })
      .add({
        combo: 'j',
        description: 'Jump back to the first skipped connection',
        callback: function() {
          var conn = $linkedin.getFirstNotFlagged();
          if(conn===false) {
            $state.go("finish");
          } else {
            $state.go("connection", {idx: conn.idx });
          }
        }
      })
      .add({
        combo: 'r',
        description: 'Skip to the results report',
        callback: function() {
          $state.go("report");
        }
      })
    ;

    //back
    if($scope.connection.idx>0) {
      hotkeys.bindTo($scope)
        .add({
          combo: 'left',
          description: 'back',
          callback: function() {
            if($scope.connection.idx>0) {
              $state.go("connection", {idx: $scope.connection.idx-1 });
            }
          }
        })
      ;
    }
  })
;<|endoftext|>


<commit_before>// @flow

import {tmpDirs} from '../../test/helpers'
import CLI from '../cli'
import Plugins from '../plugins'

import path from 'path'
import fs from 'fs-extra'

jest.unmock('fs-extra')

let mockYarnExec
jest.mock('./yarn', () => {
  return class {
    exec = mockYarnExec
  }
})

jasmine.DEFAULT_TIMEOUT_INTERVAL = 30000

let tmpDir
beforeEach(async () => {
  tmpDir = await tmpDirs()
  mockYarnExec = jest.fn()
})

afterEach(() => {
  tmpDir.clean()
})

test('plugins should be reloaded if migrated', async () => {
  let dataDir = tmpDir.dataDir

  let src = path.join(__dirname, '..', '..', 'test', 'links', 'test-migrator')
  fs.mkdirsSync(path.join(dataDir, 'plugins'))

  let dst = path.join(dataDir, 'plugins', 'node_modules', 'test-migrator')
  fs.copySync(src, dst)

  let json = [{name: 'test-migrator'}]
  fs.writeJSONSync(path.join(dataDir, 'plugins', 'plugins.json'), json)

  let cli = new CLI({argv: ['cli', 'migrator'], mock: true, config: tmpDir.config})
  try {
    await cli.run()
  } catch (err) {
    if (err.code !== 0) throw err
  }

  expect(mockYarnExec).toBeCalledWith(['install', '--force'])
})

test('linked core plugins should be migrated', async () => {
  if (process.platform === 'win32') {
    return
  }

  let dataDir = tmpDir.dataDir

  let testDir = path.join(path.dirname(__filename), '..', '..', 'test')
  let src = path.normalize(path.join(testDir, 'links', 'test-migrator'))
  fs.mkdirsSync(path.join(dataDir, 'plugins'))

  let dst = path.join(dataDir, 'plugins', 'node_modules', 'test-migrator')
  fs.mkdirsSync(path.join(dataDir, 'plugins', 'node_modules'))
  fs.symlinkSync(src, dst)

  let json = [{name: 'test-migrator', tag: 'symlink'}]
  fs.writeJSONSync(path.join(dataDir, 'plugins', 'plugins.json'), json)

  let cli = new CLI({argv: ['cli', 'foo'], mock: true, config: tmpDir.config})
  try {
    await cli.run()
  } catch (err) {
    if (err.code !== 0) throw err
  }

  let plugins = new Plugins(tmpDir.output)
  await plugins.load()
  let MigratorLinked = await plugins.findCommand('migrator')
  expect(MigratorLinked).toBeDefined()
  expect(MigratorLinked.description).toBe('link')
})
<commit_msg>fix flow errorg<commit_after>// @flow

import {tmpDirs} from '../../test/helpers'
import CLI from '../cli'
import Plugins from '../plugins'

import path from 'path'
import fs from 'fs-extra'

jest.unmock('fs-extra')

let mockYarnExec
jest.mock('./yarn', () => {
  return class {
    exec = mockYarnExec
  }
})

jasmine.DEFAULT_TIMEOUT_INTERVAL = 30000

let tmpDir
beforeEach(async () => {
  tmpDir = await tmpDirs()
  mockYarnExec = jest.fn()
})

afterEach(() => {
  tmpDir.clean()
})

test('plugins should be reloaded if migrated', async () => {
  let dataDir = tmpDir.dataDir

  let src = path.join(__dirname, '..', '..', 'test', 'links', 'test-migrator')
  fs.mkdirsSync(path.join(dataDir, 'plugins'))

  let dst = path.join(dataDir, 'plugins', 'node_modules', 'test-migrator')
  fs.copySync(src, dst)

  let json = [{name: 'test-migrator'}]
  fs.writeJSONSync(path.join(dataDir, 'plugins', 'plugins.json'), json)

  let cli = new CLI({argv: ['cli', 'migrator'], mock: true, config: tmpDir.config})
  try {
    await cli.run()
  } catch (err) {
    if (err.code !== 0) throw err
  }

  expect(mockYarnExec).toBeCalledWith(['install', '--force'])
})

test('linked core plugins should be migrated', async () => {
  if (process.platform === 'win32') {
    return
  }

  let dataDir = tmpDir.dataDir

  let testDir = path.join(path.dirname(__filename), '..', '..', 'test')
  let src = path.normalize(path.join(testDir, 'links', 'test-migrator'))
  fs.mkdirsSync(path.join(dataDir, 'plugins'))

  let dst = path.join(dataDir, 'plugins', 'node_modules', 'test-migrator')
  fs.mkdirsSync(path.join(dataDir, 'plugins', 'node_modules'))
  fs.symlinkSync(src, dst)

  let json = [{name: 'test-migrator', tag: 'symlink'}]
  fs.writeJSONSync(path.join(dataDir, 'plugins', 'plugins.json'), json)

  let cli = new CLI({argv: ['cli', 'foo'], mock: true, config: tmpDir.config})
  try {
    await cli.run()
  } catch (err) {
    if (err.code !== 0) throw err
  }

  let plugins = new Plugins(tmpDir.output)
  await plugins.load()
  let MigratorLinked = await plugins.findCommand('migrator')
  expect(MigratorLinked).toHaveProperty('description', 'link')
})
<|endoftext|>


<commit_before>import xlsx from 'node-xlsx';

import { getTargetColumn, getLastSunday } from './utils/tools'

const expName = ["6/25", "7/2", "7/9", "7/16", "7/23", "7/30", "8/6", "8/13", "8/20", "8/27", "9/3", "9/10", "9/17", "9/24", "10/1", "10/8", "10/15", "10/22", "10/29", "11/5", "11/12", "11/19", "11/26", "12/3", "12/10", "12/17", "12/24", "12/31", "1/7", "1/14", "1/21", "1/28"]
const resumeExpValue = [5, 15, 30, 50, 70, 95, 120, 140, 160, 180, 195, 215, 235, 255, 270, 290, 310, 330, 345, 365, 385, 405, 420, 440, 460, 480, 495, 515, 535, 555, 570, 585];
const onsiteExpValue = [0, 2, 7, 14, 24, 34, 46, 58, 68, 78, 88, 95, 105, 115, 125, 132, 142, 152, 162, 169, 179, 189, 199, 206, 216, 226, 236, 243, 253, 263, 273, 280];
const reqExpValue = {
  isilon:   [0, 0, 0, 0, 1, 2, 3, 4, 6, 8, 9, 10, 11, 12, 13, 14, 16, 18, 22, 23, 24, 25, 26, 27, 29, 31, 33, 35, 37, 39, 41, 43],
  ecs:      [0, 0, 0, 0, 1, 2, 3, 4, 6, 8, 10, 13, 16, 19, 22, 25, 28, 31, 35, 36, 37, 38, 39, 40, 41, 42, 43, 43, 43, 44, 44, 45],
}
reqExpValue['overview'] = reqExpValue.isilon.map((num, i) => num + reqExpValue.ecs[i]);
// tmp hard code
const reqReal = {
  isilon: [0, 0, 0, 1],
  ecs: [0, 0, 0, 2],
  overview: [0, 0, 0, 3]
}
const interviewReal = [0, 0, 0];

const RESUME = 'CV Upload Date';
const ONSITE = 'TP/Onsite Interview Time';

const filePath = {
  isilon: require('path').resolve(__dirname, '../assets/Isilon Hiring Candidates Track Sheet.xlsx'),
  ecs: require('path').resolve(__dirname, '../assets/ECS Hiring Candidates Track Sheet.xlsx'),
  overview: require('path').resolve(__dirname, '../assets/Isilon Hiring Candidates Track Sheet.xlsx')
}

// return {name: string, resume: number, phone: number, onsite: number}[]
export const getTrend = (project) => {
  const rawData = xlsx.parse(filePath[project])[0].data;
  let resume = getTargetColumn(rawData, RESUME),
    onsite = getTargetColumn(rawData, ONSITE);
  return {
    resumeExpect: getCombined(expName, resumeExpValue),
    interviewExpect: getCombined(expName, onsiteExpValue),
    reqExpect: getCombined(expName, reqExpValue[project]),
    resumeReal: reduceByDate(getLastSunday(resume)),
    reqReal: getCombined(expName, reqReal[project]),
    interviewReal: getCombined(expName, interviewReal)
    //interviewReal: reduceByDate(getLastSunday(onsite)),
    //reqReal: []
  }
}

// @param dateArray: string[]
// return {name: string, value: number}[]
function reduceByDate(dateArray) {
  return dateArray
    .reduce((a, b) => {
      let exitIndex = a.findIndex(str => str && str.name === b);
      if (exitIndex >= 0) {
        a[exitIndex].value++;
        return a;
      }
      return [...a, {
        name: b,
        value: 1
      }];
    }, [])
    .reduce((a, b) => {
      return a.length ? [...a, {
        name: b.name,
        value: a[a.length - 1].value + b.value
      }] : [b];
    }, []);
}

function getCombined(dates, values) {
  return values.map((value, index) => {
    return {
      name: dates[index],
      value
    }
  });
}
<commit_msg>update trend<commit_after>import xlsx from 'node-xlsx';

import { getTargetColumn, getLastSunday } from './utils/tools'

const expName = ["6/25", "7/2", "7/9", "7/16", "7/23", "7/30", "8/6", "8/13", "8/20", "8/27", "9/3", "9/10", "9/17", "9/24", "10/1", "10/8", "10/15", "10/22", "10/29", "11/5", "11/12", "11/19", "11/26", "12/3", "12/10", "12/17", "12/24", "12/31", "1/7", "1/14", "1/21", "1/28"]
const resumeExpValue = [5, 15, 30, 50, 70, 95, 120, 140, 160, 180, 195, 215, 235, 255, 270, 290, 310, 330, 345, 365, 385, 405, 420, 440, 460, 480, 495, 515, 535, 555, 570, 585];
const onsiteExpValue = [0, 2, 7, 14, 24, 34, 46, 58, 68, 78, 88, 95, 105, 115, 125, 132, 142, 152, 162, 169, 179, 189, 199, 206, 216, 226, 236, 243, 253, 263, 273, 280];
const reqExpValue = {
  isilon:   [0, 0, 0, 0, 1, 2, 3, 4, 6, 8, 9, 10, 11, 12, 13, 14, 16, 18, 22, 23, 24, 25, 26, 27, 29, 31, 33, 35, 37, 39, 41, 43],
  ecs:      [0, 0, 0, 0, 1, 2, 3, 4, 6, 8, 10, 13, 16, 19, 22, 25, 28, 31, 35, 36, 37, 38, 39, 40, 41, 42, 43, 43, 43, 44, 44, 45],
}
reqExpValue['overview'] = reqExpValue.isilon.map((num, i) => num + reqExpValue.ecs[i]);
// tmp hard code
const reqReal = {
  isilon: [0, 0, 0, 1, 1, 1],
  ecs: [0, 0, 0, 2, 8, 14],
  overview: [0, 0, 0, 3, 9, 15]
}
const interviewReal = [0, 0, 0];

const RESUME = 'CV Upload Date';
const ONSITE = 'TP/Onsite Interview Time';

const filePath = {
  isilon: require('path').resolve(__dirname, '../assets/Isilon Hiring Candidates Track Sheet.xlsx'),
  ecs: require('path').resolve(__dirname, '../assets/ECS Hiring Candidates Track Sheet.xlsx'),
  overview: require('path').resolve(__dirname, '../assets/Isilon Hiring Candidates Track Sheet.xlsx')
}

// return {name: string, resume: number, phone: number, onsite: number}[]
export const getTrend = (project) => {
  const rawData = xlsx.parse(filePath[project])[0].data;
  let resume = getTargetColumn(rawData, RESUME),
    onsite = getTargetColumn(rawData, ONSITE);
  return {
    resumeExpect: getCombined(expName, resumeExpValue),
    interviewExpect: getCombined(expName, onsiteExpValue),
    reqExpect: getCombined(expName, reqExpValue[project]),
    resumeReal: reduceByDate(getLastSunday(resume)),
    reqReal: getCombined(expName, reqReal[project]),
    interviewReal: getCombined(expName, interviewReal)
    //interviewReal: reduceByDate(getLastSunday(onsite)),
    //reqReal: []
  }
}

// @param dateArray: string[]
// return {name: string, value: number}[]
function reduceByDate(dateArray) {
  return dateArray
    .reduce((a, b) => {
      let exitIndex = a.findIndex(str => str && str.name === b);
      if (exitIndex >= 0) {
        a[exitIndex].value++;
        return a;
      }
      return [...a, {
        name: b,
        value: 1
      }];
    }, [])
    .reduce((a, b) => {
      return a.length ? [...a, {
        name: b.name,
        value: a[a.length - 1].value + b.value
      }] : [b];
    }, []);
}

function getCombined(dates, values) {
  return values.map((value, index) => {
    return {
      name: dates[index],
      value
    }
  });
}
<|endoftext|>


<commit_before>const Rollbar = require('rollbar')
const { isProd } = require('../config')
const { rollbar: rollbarSecret } = require('../secret')

if (isProd) {
  global.rollbar = new Rollbar({
    accessToken: rollbarSecret.accessToken,
    captureUncaught: true,
    captureUnhandledRejections: true,
    checkIgnore: (isUncaught, args) => {
      // Ignore 404 errors
      const err = args[0]
      return !isUncaught && err && err.status === 404
    }
  })
}
<commit_msg>Update rollbar.js<commit_after>const Rollbar = require('rollbar')
const { isProd } = require('../config')
const { rollbar: rollbarSecret } = require('../secret')

if (isProd) {
  global.rollbar = new Rollbar({
    accessToken: rollbarSecret.accessToken,
    captureUncaught: true,
    captureUnhandledRejections: true,
    checkIgnore: (isUncaught, args) => {
      const err = args[0]

      // Never ignore uncaught errors
      if (isUncaught) return false

      // Ignore 'Bad Request' errors
      if (err.status === 400) return true

      // Ignore 'Forbidden' errors
      if (err.status === 403) return true

      // Ignore 'Not Found' errors
      if (err.status === 404) return true

      // Ignore 'Precondition Failed' errors
      if (err.status === 412) return true

      // Ignore 'Range Not Satisfiable' errors
      if (err.status === 416) return true

      return false
    }
  })
}
<|endoftext|>


<commit_before>
function __gotCurrentAcceleration(callbackID, x,y,z,timestamp){
	acceleration = {};
	acceleration.x = x;
	acceleration.y = y;
	acceleration.z = z;
	acceleration.timestamp = timestamp;
	___retrieveCallback(callbackID)(acceleration);
};

function bindAccelerometerToAndroid(){
	navigator.accelerometer = {};
	navigator.accelerometer.getCurrentAcceleration = function(onSuccess, onError){
		__androidAccelerometer.getCurrentAcceleration(
				___storeCallback(onSuccess),
				___storeCallback(onError)
		);
	};
	navigator.accelerometer.watchAcceleration = function(onSuccess, onError, options){
		setInterval(function(){
			navigator.accelerometer.getCurrentAcceleration(onSuccess, onError);
		}, options.frequency);
	};

	window.mWatch("ondevicemotion", function(id, oldval, newval){
		navigator.accelerometer.watchAcceleration(function(acceleration){
			var event = {};
			event.accelerationIncludingGravity = {};
			event.accelerationIncludingGravity.x = acceleration.x;
			event.accelerationIncludingGravity.y = acceleration.y;
			event.accelerationIncludingGravity.z = acceleration.z;
			newval(event);
		}, new function(){ }, {frequency: 50});
		return newval;
	});

};

if (!Object.prototype.mWatch) {
	Object.prototype.mWatch = function (prop, handler) {
		var oldval = this[prop], newval = oldval,
		getter = function () {
			return newval;
		},
		setter = function (val) {
			oldval = newval;
			return newval = handler.call(this, prop, oldval, val);
		};
		if (delete this[prop]) {
			if (Object.defineProperty) {
				Object.defineProperty(this, prop, {
					get: getter,
					set: setter,
					enumerable: false,
					configurable: true
				});
			} else if (Object.prototype.__defineGetter__ && Object.prototype.__defineSetter__) {
				Object.prototype.__defineGetter__.call(this, prop, getter);
				Object.prototype.__defineSetter__.call(this, prop, setter);
			};
		};
	};
};

bindAccelerometerToAndroid();
console.log("accelerometer loaded");<commit_msg>Finished first draft of Device plugin...hopefully<commit_after>
function __gotCurrentAcceleration(callbackID, x,y,z,timestamp){
	acceleration = {};
	acceleration.x = x;
	acceleration.y = y;
	acceleration.z = z;
	acceleration.timestamp = timestamp;
	___retrieveCallback(callbackID)(acceleration);
};

function __bindAccelerometerToAndroid(){
	navigator.accelerometer = {};
	navigator.accelerometer.getCurrentAcceleration = function(onSuccess, onError){
		__androidAccelerometer.getCurrentAcceleration(
				___storeCallback(onSuccess),
				___storeCallback(onError)
		);
	};
	navigator.accelerometer.watchAcceleration = function(onSuccess, onError, options){
		setInterval(function(){
			navigator.accelerometer.getCurrentAcceleration(onSuccess, onError);
		}, options.frequency);
	};

	window.mWatch("ondevicemotion", function(id, oldval, newval){
		navigator.accelerometer.watchAcceleration(function(acceleration){
			var event = {};
			event.accelerationIncludingGravity = {};
			event.accelerationIncludingGravity.x = acceleration.x;
			event.accelerationIncludingGravity.y = acceleration.y;
			event.accelerationIncludingGravity.z = acceleration.z;
			newval(event);
		}, new function(){ }, {frequency: 50});
		return newval;
	});

};

if (!Object.prototype.mWatch) {
	Object.prototype.mWatch = function (prop, handler) {
		var oldval = this[prop], newval = oldval,
		getter = function () {
			return newval;
		},
		setter = function (val) {
			oldval = newval;
			return newval = handler.call(this, prop, oldval, val);
		};
		if (delete this[prop]) {
			if (Object.defineProperty) {
				Object.defineProperty(this, prop, {
					get: getter,
					set: setter,
					enumerable: false,
					configurable: true
				});
			} else if (Object.prototype.__defineGetter__ && Object.prototype.__defineSetter__) {
				Object.prototype.__defineGetter__.call(this, prop, getter);
				Object.prototype.__defineSetter__.call(this, prop, setter);
			};
		};
	};
};

bindAccelerometerToAndroid();
console.log("accelerometer loaded");<|endoftext|>


<commit_before>class CareerPortalModalController {
    /* jshint -W072 */
    constructor($location, $window, $filter, $log, SharedData, SearchService, ApplyService, configuration, locale, LinkedInService, ShareService, MobileDetection, VerifyLI) {
        'ngInject';
        // NG Dependencies
        this.$location = $location;
        this.$window = $window;
        this.$filter = $filter;
        this.$log = $log;

        // Dependencies
        this.configuration = configuration;
        this.SharedData = SharedData;
        this.SearchService = SearchService;
        this.ShareService = ShareService;
        this.ApplyService = ApplyService;
        this.LinkedInService = LinkedInService;
        this.locale = locale;

        // Variables
        this.isLinkedInActive = VerifyLI.verified;
        this.isIOS = MobileDetection.browserData.os.ios;
        // Create a local variable to store user's email address for sendEmailLink
        this.email = '';
        // Boolean to indicate if the user has attempted to apply via LinkedIn
        this.hasAttemptedLIApply = false;
        // Resume object that contains the parsed LinkedIn data and the user's input
        this.linkedInData = {
            header: '',
            resume: '',
            footer: ''
        };

        // Load directive with modal closed by default
        this.closeModal();
    }

    /* jshint +W072 */

    applyWithLinkedIn() {
        this.hasAttemptedLIApply = true;
        this.LinkedInService.getUser()
            .then((linkedInUser) => {
                this.ApplyService.form.firstName = linkedInUser.firstName || '';
                this.ApplyService.form.lastName = linkedInUser.lastName || '';
                this.ApplyService.form.email = linkedInUser.emailAddress || '';
                this.ApplyService.form.phone = linkedInUser.phoneNumbers ? linkedInUser.phoneNumbers.values[0].phoneNumber : '';
                this.ApplyService.form.resumeInfo = this.formatResume(linkedInUser);
            });
    }

    closeModal(applyForm) {
        this.SharedData.modalState = 'closed';
        this.showForm = true;
        this.hasAttemptedLIApply = false;

        // Clear the errors if we have the form
        if (applyForm) {
            applyForm.$setPristine();
        }
    }

    validateResume(file) {
        if (!file || !file.name) {
            this.updateUploadClass(false);
            return false;
        }

        // First check the type
        var fileArray = file.name.split('.'),
            fileExtension = fileArray[fileArray.length - 1];

        if (this.configuration.acceptedResumeTypes.indexOf((fileExtension || '').toLowerCase()) === -1) {
            this.resumeUploadErrorMessage = (fileExtension || '').toUpperCase() + ' ' + this.$filter('i18n')('modal.resumeInvalidFormat');
            this.updateUploadClass(false);
            this.isSubmitting = false;
            return false;
        }

        // Now check the size
        if (file.size > this.configuration.maxUploadSize) {
            this.resumeUploadErrorMessage = this.$filter('i18n')('modal.resumeToBig') + ' (' + this.$filter('i18n')('modal.maxLabel') + ': ' + this.configuration.maxUploadSize / (1024 * 1024) + 'MB)';
            this.updateUploadClass(false);
            this.isSubmitting = false;
            return false;
        }

        this.resumeUploadErrorMessage = null;
        this.updateUploadClass(true);
        return true;
    }

    updateUploadClass(valid) {
        var $uploadContainer = document.querySelector('.upload-container');
        if ($uploadContainer) {
            $uploadContainer.classList.toggle('valid', valid);
        }
    }

    enableSendButton(isFormValid) {
        var resume = this.ApplyService.form.resumeInfo;

        if (isFormValid && (resume || this.linkedInData.resume)) {
            if (this.linkedInData.resume.length !== 0 || resume.type) {
                return false;
            }
        } else if (this.email) {
            return false;
        }
        return true;
    }

    getTooltipText() {
        var tooltip = '
';
        this.configuration.acceptedResumeTypes.forEach(function (type) {
            tooltip += '
' + type + '
';
        });
        tooltip += '
';
        return tooltip;
    }

    // TODO: offload to factory

    formatResume(userProfile) {
        var lineBreak = '\n',
            hardBreak = '\n\n\n',
            months = this.$filter('i18n')('modal.Months').split('_'),
            today = new Date(),
            friendlyDate = today.toLocaleDateString() + ' ' + this.$filter('i18n')('modal.at') + ' ' + today.toLocaleTimeString(),
            legal = this.$filter('i18n')('modal.profileReceived') + ' ' + friendlyDate + '. \n\n' + this.$filter('i18n')('modal.legal') + '\n\n';

        // First Name
        this.linkedInData.header = (userProfile.formattedName || '') + lineBreak;
        // Email Address
        this.linkedInData.header += (userProfile.emailAddress || '') + lineBreak;
        // Location
        if (userProfile.location && userProfile.location.name) {
            this.linkedInData.header += (userProfile.location.name || '') + ', ';
            if (userProfile.location.country) {
                this.linkedInData.header += (userProfile.location.country.code.toUpperCase() || '') + hardBreak;
            }
        }
        // Clear Instance of resume
        this.linkedInData.resume = '';
        // Education
        if (userProfile.educations && userProfile.educations.values) {
            var education = userProfile.educations.values;
            this.linkedInData.resume += this.$filter('i18n')('modal.education') + lineBreak;
            for (var i = 0; i < education.length; i++) {
                // Add Degree Type
                if (education[i].degree) {
                    this.linkedInData.resume += education[i].degree + ' ';
                }
                // Add Field of Study Type
                if (education[i].fieldOfStudy) {
                    this.linkedInData.resume += education[i].fieldOfStudy + ' ';
                }
                // Add line break
                if (education[i].degree || education[i].fieldOfStudy) {
                    this.linkedInData.resume += lineBreak;
                }
                // Add School
                if (education[i].schoolName) {
                    this.linkedInData.resume += education[i].schoolName + ' ';
                }
                // Add Start Date
                if (education[i].startDate) {
                    this.linkedInData.resume += education[i].startDate.year + ' - ';
                }
                // Add End Date
                if (education[i].endDate) {
                    this.linkedInData.resume += education[i].endDate.year + ' ';
                }
                // Add line break
                if ((education[i].schoolName || education[i].startDate || education[i].endDate) && education[i + 1]) {
                    this.linkedInData.resume += lineBreak;
                }
            }
            // Add line break
            this.linkedInData.resume += hardBreak;
        }

        // Work Experience Block
        this.linkedInData.resume += this.$filter('i18n')('modal.workExperience') + lineBreak;
        // Positions
        if (userProfile.positions) {
            var positions = userProfile.positions.values;
            // Iterate through each position
            if (positions && positions.length) {
                for (var ii = 0; ii < positions.length; ii++) {
                    // Add Employee section header
                    this.linkedInData.resume += (positions[ii].company.name || '') + ' ';
                    // Start Date
                    if (positions[ii].startDate) {
                        this.linkedInData.resume += months[positions[ii].startDate.month - 1] + ' ' + positions[ii].startDate.year + ' - ' || '';
                    }
                    // End Date or 'Present'
                    if (positions[ii].endDate) {
                        this.linkedInData.resume += months[positions[ii].endDate.month - 1] + ' ' + positions[ii].endDate.year || '';
                    } else {
                        if (positions[ii].isCurrent) { // jshint ignore:line
                            this.linkedInData.resume += this.$filter('i18n')('modal.present');
                        }
                    }
                    this.linkedInData.resume += lineBreak;
                    // Title
                    this.linkedInData.resume += positions[ii].title + lineBreak || '';
                    // Industry
                    this.linkedInData.resume += positions[ii].company.industry ? positions[ii].company.industry + lineBreak : '';
                    if (positions[ii].location && positions[ii].location.name) {
                        // Locale
                        this.linkedInData.resume += positions[ii].location.name + lineBreak || '';
                    }
                    // Summary
                    if (positions[ii].summary) {
                        this.linkedInData.resume += positions[ii].summary + lineBreak || '';
                    }
                    this.linkedInData.resume += hardBreak;
                }
            }
        }

        // Skills
        if (userProfile.skills && userProfile.skills.values) {
            this.linkedInData.resume +=  this.$filter('i18n')('modal.skillHeading') + lineBreak;
            var skills = userProfile.skills.values;
            for (var iii = 0; iii < skills.length; iii++) {
                var newSkill = skills[iii].skill;
                if (newSkill && newSkill.name) {
                    this.linkedInData.resume += newSkill.name;
                    if (skills[iii + 1]) {
                        this.linkedInData.resume += ', ';
                    }
                }
            }
            this.linkedInData.resume += hardBreak;
        }

        // LinkedIn Information
        this.linkedInData.footer = hardBreak + this.$filter('i18n')('modal.profileURL') + lineBreak;
        this.linkedInData.footer += userProfile.publicProfileUrl + lineBreak || '';
        this.linkedInData.footer += userProfile.siteStandardProfileRequest.url + lineBreak || '';
        // Legal
        this.linkedInData.footer += hardBreak + legal;
    }

    applySuccess() {
        // Reset LinkedIn Data
        this.linkedInData.header = '';
        this.linkedInData.resume = '';
        this.linkedInData.footer = '';
        // Reset LinkedIn Flag
        this.hasAttemptedLIApply = false;
        // Reset form data
        this.ApplyService.form.resumeInfo = null;
        // Hide Form
        this.showForm = false;
    }

    submit(applyForm) {
        var isFileValid = false,
            resumeInfo = this.ApplyService.form.resumeInfo,
            resumeText = this.linkedInData.header + this.linkedInData.resume + this.linkedInData.footer,
            controller;

        if (!this.hasAttemptedLIApply && this.email) {
            // Send email
            this.$window.open(this.ShareService.sendEmailLink(this.SearchService.currentDetailData, this.email), '_self');
            this.email = '';
            this.closeModal();
        } else if (this.hasAttemptedLIApply && resumeText) {
            // LinkedIn Apply
            applyForm.$submitted = true;
            this.ApplyService.form.resumeInfo = new Blob([resumeText], {type: 'text/plain'});
            isFileValid = true;
        } else if (!this.hasAttemptedLIApply && resumeInfo) {
            // Validate file & Apply
            applyForm.$submitted = true;
            isFileValid = this.validateResume(resumeInfo);
        } else {
            this.$log.error(this.$filter('i18n')('modal.LIError'));
        }

        if (applyForm.$valid && isFileValid) {
            controller = this;
            controller.isSubmitting = true;
            this.ApplyService.submit(this.SearchService.currentDetailData.id, function () {
                controller.applySuccess();
                controller.isSubmitting = false;
            }, function () {
                controller.isSubmitting = false;
            });
        }
    }
}

export default CareerPortalModalController;
<commit_msg>Added additional conditional logic for potentially undefined data.<commit_after>class CareerPortalModalController {
    /* jshint -W072 */
    constructor($location, $window, $filter, $log, SharedData, SearchService, ApplyService, configuration, locale, LinkedInService, ShareService, MobileDetection, VerifyLI) {
        'ngInject';
        // NG Dependencies
        this.$location = $location;
        this.$window = $window;
        this.$filter = $filter;
        this.$log = $log;

        // Dependencies
        this.configuration = configuration;
        this.SharedData = SharedData;
        this.SearchService = SearchService;
        this.ShareService = ShareService;
        this.ApplyService = ApplyService;
        this.LinkedInService = LinkedInService;
        this.locale = locale;

        // Variables
        this.isLinkedInActive = VerifyLI.verified;
        this.isIOS = MobileDetection.browserData.os.ios;
        // Create a local variable to store user's email address for sendEmailLink
        this.email = '';
        // Boolean to indicate if the user has attempted to apply via LinkedIn
        this.hasAttemptedLIApply = false;
        // Resume object that contains the parsed LinkedIn data and the user's input
        this.linkedInData = {
            header: '',
            resume: '',
            footer: ''
        };

        // Load directive with modal closed by default
        this.closeModal();
    }

    /* jshint +W072 */

    applyWithLinkedIn() {
        this.hasAttemptedLIApply = true;
        this.LinkedInService.getUser()
            .then((linkedInUser) => {
                this.ApplyService.form.firstName = linkedInUser.firstName || '';
                this.ApplyService.form.lastName = linkedInUser.lastName || '';
                this.ApplyService.form.email = linkedInUser.emailAddress || '';
                this.ApplyService.form.phone = linkedInUser.phoneNumbers ? linkedInUser.phoneNumbers.values[0].phoneNumber : '';
                this.ApplyService.form.resumeInfo = this.formatResume(linkedInUser);
            });
    }

    closeModal(applyForm) {
        this.SharedData.modalState = 'closed';
        this.showForm = true;
        this.hasAttemptedLIApply = false;

        // Clear the errors if we have the form
        if (applyForm) {
            applyForm.$setPristine();
        }
    }

    validateResume(file) {
        if (!file || !file.name) {
            this.updateUploadClass(false);
            return false;
        }

        // First check the type
        var fileArray = file.name.split('.'),
            fileExtension = fileArray[fileArray.length - 1];

        if (this.configuration.acceptedResumeTypes.indexOf((fileExtension || '').toLowerCase()) === -1) {
            this.resumeUploadErrorMessage = (fileExtension || '').toUpperCase() + ' ' + this.$filter('i18n')('modal.resumeInvalidFormat');
            this.updateUploadClass(false);
            this.isSubmitting = false;
            return false;
        }

        // Now check the size
        if (file.size > this.configuration.maxUploadSize) {
            this.resumeUploadErrorMessage = this.$filter('i18n')('modal.resumeToBig') + ' (' + this.$filter('i18n')('modal.maxLabel') + ': ' + this.configuration.maxUploadSize / (1024 * 1024) + 'MB)';
            this.updateUploadClass(false);
            this.isSubmitting = false;
            return false;
        }

        this.resumeUploadErrorMessage = null;
        this.updateUploadClass(true);
        return true;
    }

    updateUploadClass(valid) {
        var $uploadContainer = document.querySelector('.upload-container');
        if ($uploadContainer) {
            $uploadContainer.classList.toggle('valid', valid);
        }
    }

    enableSendButton(isFormValid) {
        var resume = this.ApplyService.form.resumeInfo;

        if (isFormValid && (resume || this.linkedInData.resume)) {
            if (this.linkedInData.resume.length !== 0 || resume.type) {
                return false;
            }
        } else if (this.email) {
            return false;
        }
        return true;
    }

    getTooltipText() {
        var tooltip = '
';
        this.configuration.acceptedResumeTypes.forEach(function (type) {
            tooltip += '
' + type + '
';
        });
        tooltip += '
';
        return tooltip;
    }

    // TODO: offload to factory

    formatResume(userProfile) {
        var lineBreak = '\n',
            hardBreak = '\n\n\n',
            months = this.$filter('i18n')('modal.Months').split('_'),
            today = new Date(),
            friendlyDate = today.toLocaleDateString() + ' ' + this.$filter('i18n')('modal.at') + ' ' + today.toLocaleTimeString(),
            legal = this.$filter('i18n')('modal.profileReceived') + ' ' + friendlyDate + '. \n\n' + this.$filter('i18n')('modal.legal') + '\n\n';

        // First Name
        this.linkedInData.header = (userProfile.formattedName || '') + lineBreak;
        // Email Address
        this.linkedInData.header += (userProfile.emailAddress || '') + lineBreak;
        // Location
        if (userProfile.location && userProfile.location.name) {
            this.linkedInData.header += (userProfile.location.name || '') + ', ';
            if (userProfile.location.country) {
                this.linkedInData.header += (userProfile.location.country.code.toUpperCase() || '') + hardBreak;
            }
        }
        // Clear Instance of resume
        this.linkedInData.resume = '';
        // Education
        if (userProfile.educations && userProfile.educations.values) {
            var education = userProfile.educations.values;
            this.linkedInData.resume += this.$filter('i18n')('modal.education') + lineBreak;
            for (var i = 0; i < education.length; i++) {
                // Add Degree Type
                if (education[i].degree) {
                    this.linkedInData.resume += education[i].degree + ' ';
                }
                // Add Field of Study Type
                if (education[i].fieldOfStudy) {
                    this.linkedInData.resume += education[i].fieldOfStudy + ' ';
                }
                // Add line break
                if (education[i].degree || education[i].fieldOfStudy) {
                    this.linkedInData.resume += lineBreak;
                }
                // Add School
                if (education[i].schoolName) {
                    this.linkedInData.resume += education[i].schoolName + ' ';
                }
                // Add Start Date
                if (education[i].startDate) {
                    this.linkedInData.resume += education[i].startDate.year + ' - ';
                }
                // Add End Date
                if (education[i].endDate) {
                    this.linkedInData.resume += education[i].endDate.year + ' ';
                }
                // Add line break
                if ((education[i].schoolName || education[i].startDate || education[i].endDate) && education[i + 1]) {
                    this.linkedInData.resume += lineBreak;
                }
            }
            // Add line break
            this.linkedInData.resume += hardBreak;
        }

        // Work Experience Block
        this.linkedInData.resume += this.$filter('i18n')('modal.workExperience') + lineBreak;
        // Positions
        if (userProfile.positions && userProfile.positions.values) {
            var positions = userProfile.positions.values;
            // Iterate through each position
            if (positions && positions.length) {
                for (var ii = 0; ii < positions.length; ii++) {
                    // Add Employee section header
                    this.linkedInData.resume += ((positions[ii].company || {}).name || '') + ' ';
                    // Start Date
                    if (positions[ii].startDate) {
                        this.linkedInData.resume += months[positions[ii].startDate.month - 1] + ' ' + positions[ii].startDate.year + ' - ' || '';
                    }
                    // End Date or 'Present'
                    if (positions[ii].endDate) {
                        this.linkedInData.resume += months[positions[ii].endDate.month - 1] + ' ' + positions[ii].endDate.year || '';
                    } else {
                        if (positions[ii].isCurrent) { // jshint ignore:line
                            this.linkedInData.resume += this.$filter('i18n')('modal.present');
                        }
                    }
                    this.linkedInData.resume += lineBreak;
                    // Title
                    this.linkedInData.resume += positions[ii].title + lineBreak || '';
                    // Industry
                    this.linkedInData.resume += positions[ii].company.industry ? positions[ii].company.industry + lineBreak : '';
                    if (positions[ii].location && positions[ii].location.name) {
                        // Locale
                        this.linkedInData.resume += positions[ii].location.name + lineBreak || '';
                    }
                    // Summary
                    if (positions[ii].summary) {
                        this.linkedInData.resume += positions[ii].summary + lineBreak || '';
                    }
                    this.linkedInData.resume += hardBreak;
                }
            }
        }

        // Skills
        if (userProfile.skills && userProfile.skills.values) {
            this.linkedInData.resume +=  this.$filter('i18n')('modal.skillHeading') + lineBreak;
            var skills = userProfile.skills.values;
            for (var iii = 0; iii < skills.length; iii++) {
                var newSkill = skills[iii].skill;
                if (newSkill && newSkill.name) {
                    this.linkedInData.resume += newSkill.name;
                    if (skills[iii + 1]) {
                        this.linkedInData.resume += ', ';
                    }
                }
            }
            this.linkedInData.resume += hardBreak;
        }

        // LinkedIn Information
        this.linkedInData.footer = hardBreak + this.$filter('i18n')('modal.profileURL') + lineBreak;
        this.linkedInData.footer += userProfile.publicProfileUrl + lineBreak || '';
        this.linkedInData.footer += userProfile.siteStandardProfileRequest.url + lineBreak || '';
        // Legal
        this.linkedInData.footer += hardBreak + legal;
    }

    applySuccess() {
        // Reset LinkedIn Data
        this.linkedInData.header = '';
        this.linkedInData.resume = '';
        this.linkedInData.footer = '';
        // Reset LinkedIn Flag
        this.hasAttemptedLIApply = false;
        // Reset form data
        this.ApplyService.form.resumeInfo = null;
        // Hide Form
        this.showForm = false;
    }

    submit(applyForm) {
        var isFileValid = false,
            resumeInfo = this.ApplyService.form.resumeInfo,
            resumeText = this.linkedInData.header + this.linkedInData.resume + this.linkedInData.footer,
            controller;

        if (!this.hasAttemptedLIApply && this.email) {
            // Send email
            this.$window.open(this.ShareService.sendEmailLink(this.SearchService.currentDetailData, this.email), '_self');
            this.email = '';
            this.closeModal();
        } else if (this.hasAttemptedLIApply && resumeText) {
            // LinkedIn Apply
            applyForm.$submitted = true;
            this.ApplyService.form.resumeInfo = new Blob([resumeText], {type: 'text/plain'});
            isFileValid = true;
        } else if (!this.hasAttemptedLIApply && resumeInfo) {
            // Validate file & Apply
            applyForm.$submitted = true;
            isFileValid = this.validateResume(resumeInfo);
        } else {
            this.$log.error(this.$filter('i18n')('modal.LIError'));
        }

        if (applyForm.$valid && isFileValid) {
            controller = this;
            controller.isSubmitting = true;
            this.ApplyService.submit(this.SearchService.currentDetailData.id, function () {
                controller.applySuccess();
                controller.isSubmitting = false;
            }, function () {
                controller.isSubmitting = false;
            });
        }
    }
}

export default CareerPortalModalController;
<|endoftext|>


<commit_before>/* ===============================================
 * ================ COMMON =======================
 * Some common functions for the basic JavaScript objects
 *
 * ===============================================
 */

String.prototype.trim = function()
{
    return this.replace(/^\s+|\s+$/, "");
};

// Define methods for the Array data structure.
Array.prototype.indexOf = function(item, start)
{
  var i;
	for (i = (start || 0); i < this.length; i++)
	{
		if (this[i] == item)
		{
			return i;
		}
	}
	return -1;
};

Array.prototype.remove = function(obj)
{
	var x = [];
	var i;
	for (i=0; i<this.length; i++)
	{
		if (this[i] != obj)
		{
			x.push(this[i]);
		}
	}
	return x;
};

Array.prototype.replace = function(obj1, obj2)
{
	var x = [];
	var len = this.length;
	var i;
	for (i=0; i<len; i++)
	{
		if (this[i] == obj1)
		{
			x.push(obj2);
		}
		else
		{
			x.push(this[i]);
		}
	}
	return x;
};

/* ===============================================
 * ============= GET ELEMENTS ====================
 * Methods to help retrieve elements from the DOM.
 *
 * ===============================================
 */

/*
 * Gets all the Elements by given Class Name.
 *
 * @param string searchClass - Name of the css class to look for.
 * @param object node - (optional) The node you want to start from. Defaults to 'document' if none is specified.
 * @param string tagName - (optional) Limit  results by adding a tagName. Defaults to '*' if none is specified.
 *
 * @returns array - Returns an array containing all the nodes given by the specified className.
 */
function getElementsByClass(searchClass, node, tagName)
{
	var	classElements =	[];
	if (node === null)
	{
    node = document;
  }
	if (tagName ===	null)
	{
    tagName	= '*';
  }

	var	els	= node.getElementsByTagName(tagName);
	var	elsLen = els.length;

	var i,j;
	for	(i = 0,	j =	0; i < elsLen; i++)
	{
		if (hasClass(els[i], searchClass))
		{
			classElements[j] = els[i];
			j++;
		}
	}
	return classElements;
}

/*
 * Get the element from the DOM Tree. If the given parameter (e) is a string,
 * it is assumed to be the element's ID, and that element will be retrieved, else
 * the given parameter is returned.
 *
 * @param string/element e - the element ID / element to be retrieved from the DOM tree.
 *
 * @returns element
 */
function getElement(e)
{
	if (typeof e ==	'string')
	{
		return document.getElementById(e);
	}
	else
	{
		return e;
  }
}

/* ===============================================
 * ================ STYLING ======================
 * Methods for manipulating an element's styles (CSS).
 *
 * ===============================================
 */

function getClasses(element)
{
	return element.className.trim().split(/\s+/);
}

function hasClass(element, className)
{
	return getClasses(element).indexOf(className) != -1;
}

function addClass(element, className)
{
    var classes = getClasses(element);

    if (classes.indexOf(className) == -1)
    {
        classes.push(className);
        element.className = classes.join(' ');
    }
}

function removeClass(element, className)
{
    var classes = getClasses(element);
    var index = classes.indexOf(className);

    if (index != -1)
    {
        classes.splice(index, 1);
        element.className = classes.join(' ');
    }
}

function showElement(element)
{
	element = getElement(element);

	if (element) // if we don't find the element, don't try to access it's properties.
	{
		element.style.display = "";
	}
}

function hideElement(element)
{
	element = getElement(element);

	if (element)
	{
		element.style.display = "none";
	}
}

/*-------------------------------------------------*/
/* Disables submit button during update panel post
/*-------------------------------------------------*/
function pageLoad(sender, args)
{
    var requestManager = Sys.WebForms.PageRequestManager.getInstance();
    requestManager.add_initializeRequest(initializeRequest);
    requestManager.add_endRequest(endRequest);
}

function initializeRequest(sender, args) {
    //Disable button to prevent double submit
    var button = $get(args._postBackElement.id);
    if (button)
    {
        button.disabled = true;
        button.oldValue = button.value;
        if (button.oldValue && button.oldValue !== '') {
            button.value = 'Posting...';
        }
        if (button.className == 'buttonSubmit')
        {
            button.className = 'button-disabled';
        }
    }
}

function endRequest(sender, args)
{
    //Re-enable button
    var button = $get(sender._postBackSettings.sourceElement.id);
    if (button)
    {
        button.disabled = false;
        button.value = button.oldValue;
        if (button.className == 'button-disabled')
        {
            button.className = 'buttonSubmit';
        }
    }
}
<commit_msg>Removing some unused methods from common.js<commit_after>/* ===============================================
 * ================ COMMON =======================
 * Some common functions for the basic JavaScript objects
 *
 * ===============================================
 */

String.prototype.trim = function()
{
    return this.replace(/^\s+|\s+$/, "");
};

// Define methods for the Array data structure.
Array.prototype.indexOf = function(item, start)
{
  var i;
	for (i = (start || 0); i < this.length; i++)
	{
		if (this[i] == item)
		{
			return i;
		}
	}
	return -1;
};

Array.prototype.remove = function(obj)
{
	var x = [];
	var i;
	for (i=0; i<this.length; i++)
	{
		if (this[i] != obj)
		{
			x.push(this[i]);
		}
	}
	return x;
};

Array.prototype.replace = function(obj1, obj2)
{
	var x = [];
	var len = this.length;
	var i;
	for (i=0; i<len; i++)
	{
		if (this[i] == obj1)
		{
			x.push(obj2);
		}
		else
		{
			x.push(this[i]);
		}
	}
	return x;
};

/*-------------------------------------------------*/
/* Disables submit button during update panel post
/*-------------------------------------------------*/
function pageLoad(sender, args)
{
    var requestManager = Sys.WebForms.PageRequestManager.getInstance();
    requestManager.add_initializeRequest(initializeRequest);
    requestManager.add_endRequest(endRequest);
}

function initializeRequest(sender, args) {
    //Disable button to prevent double submit
    var button = $get(args._postBackElement.id);
    if (button)
    {
        button.disabled = true;
        button.oldValue = button.value;
        if (button.oldValue && button.oldValue !== '') {
            button.value = 'Posting...';
        }
        if (button.className == 'buttonSubmit')
        {
            button.className = 'button-disabled';
        }
    }
}

function endRequest(sender, args)
{
    //Re-enable button
    var button = $get(sender._postBackSettings.sourceElement.id);
    if (button)
    {
        button.disabled = false;
        button.value = button.oldValue;
        if (button.className == 'button-disabled')
        {
            button.className = 'buttonSubmit';
        }
    }
}
<|endoftext|>


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

var findScrollParent = function (el) {
	var ref = el;
	while (ref) {
		switch (window.getComputedStyle(ref).overflow) {
			case "auto":
				return ref;
			case "scroll":
				return ref;
		}
		ref = ref.parentElement;
	}
	return window;
};

var ScrollPagination = window.ScrollPagination = React.createClass({
	displayName: "ScrollPagination",

	getDefaultProps: function () {
		return {
			hasPrevPage: false,
			hasNextPage: false,
			loadPrevPage: function () {},
			loadNextPage: function () {}
		};
	},

	componentWillMount: function () {
		this.__pages = {};
		this.__pageIds = [];
	},

	componentDidMount: function () {
		var scrollParent = this.__scrollParent = findScrollParent(this.getDOMNode());
		scrollParent.addEventListener("scroll", this.__handleScroll, false);
		scrollParent.addEventListener("resize", this.__handleResize, false);

		this.__updatePageIds();
		this.__updateDimensions();
	},

	componentDidUpdate: function () {
		this.__updatePageIds();
		this.__updateDimensions();

		this.__loadingNextPage = false;
		this.__loadingPrevPage = false;
		this.__unloadingPage = false;

		this.__evaluatePagesMutation();
	},

	componentWillUnmount: function () {
		var scrollParent = this.__scrollParent;
		scrollParent.removeEventListener("scroll", this.__handleScroll, false);
		scrollParent.removeEventListener("resize", this.__handleResize, false);
	},

	render: function () {
		var style = {};
		if (this.__paddingTop) {
			style.paddingTop = this.__paddingTop + "px";
		}
		return React.DOM.div({
			style: style,
			ref: "wrapper"
		}, this.props.children);
	},

	// called from Page component via parent component
	handlePageEvent: function (pageId, event) {
		var pages = this.__pages;
		switch (event.name) {
			case "mount":
				pages[pageId] = {
					id: pageId,
					height: event.height
				};
			break;

			case "update":
				pages[pageId] = {
					id: pageId,
					height: event.height
				};
			break;

			case "unmount":
			break;
		}
		this.__pages = pages;
	},

	__unloadPage: function (pageId) {
		if (this.__unloadingPage) {
			return;
		}
		this.__unloadingPage = true;
		this.props.unloadPage(pageId);
	},

	__loadPrevPage: function () {
		if (this.__loadingPrevPage || !this.props.hasPrevPage) {
			return;
		}
		this.__loadingPrevPage = true;
		this.props.loadPrevPage();
	},

	__loadNextPage: function () {
		if (this.__loadingNextPage || !this.props.hasNextPage) {
			return;
		}
		this.__loadingNextPage = true;
		this.props.loadNextPage();
	},

	__getScrollY: function () {
		var scrollParent = this.__scrollParent;
		if (scrollParent === window) {
			return window.scrollY;
		} else {
			return scrollParent.scrollTop;
		}
	},

	__setScrollY: function (scrollY) {
		var scrollParent = this.__scrollParent;
		if (scrollParent === window) {
			return window.scrollTo(window.scrollX, scrollY);
		} else {
			return scrollParent.scrollTop = scrollY;
		}
	},

	__updatePageIds: function () {
		var oldPageIds = this.__pageIds;
		var unloadedPageIdsTop = [];
		var newPageIdsTop = [];
		var pageIds = [];
		var findPages = function (children) {
			React.Children.forEach(children, function (child) {
				if (child.constructor.displayName === "ScrollPagination.Page") {
					pageIds.push(child.props.id);
				} else if (child.constructor.displayName === "ul") {
					findPages(child.props.children);
				}
			});
		};
		findPages(this.props.children);
		var i, len;
		if (oldPageIds.length > 0) {
			for (i = 0, len = oldPageIds.length; i < len; i++) {
				if (pageIds.indexOf(oldPageIds[i]) === -1) {
					unloadedPageIdsTop.push(oldPageIds[i]);
				} else {
					break;
				}
			}
			for (i = 0, len = pageIds.length; i < len; i++) {
				if (oldPageIds.indexOf(pageIds[i]) === -1) {
					newPageIdsTop.push(pageIds[i]);
				} else {
					break;
				}
			}
		}
		this.__adjustScrollPosition(unloadedPageIdsTop, newPageIdsTop);
		this.__pageIds = pageIds;
	},

	__adjustScrollPosition: function (unloadedPageIdsTop, newPageIdsTop) {
		var offset = 0;
		var pages = this.__pages;
		unloadedPageIdsTop.forEach(function (pageId) {
			var height = pages[pageId].height;
			offset += height;
			delete pages[pageId];
		});
		newPageIdsTop.forEach(function (pageId) {
			var height = pages[pageId].height;
			offset += height;
		});
		this.__setScrollY(this.__getScrollY() + offset);
	},

	__updateDimensions: function () {
		var el = this.refs.wrapper.getDOMNode();
		var scrollParent = this.__scrollParent;
		var viewportHeight = 0;
		if (scrollParent === window) {
			viewportHeight = window.innerHeight;
		} else {
			viewportHeight = parseInt(window.getComputedStyle(scrollParent).height, 10);
		}
		var contentHeight = el.offsetHeight;

		var offsetTop = 0;
		var ref = el;
		while (ref) {
			offsetTop += ref.offsetTop || 0;
			ref = ref.offsetParent;
			if (ref === scrollParent) {
				break;
			}
		}

		this.__dimentions = {
			viewportHeight: viewportHeight,
			contentHeight: contentHeight,
			offsetTop: offsetTop
		};
	},

	__evaluatePagesMutation: function (e) {
		if (this.__dimentions.contentHeight === 0) {
			return;
		}
		if (this.__loadingNextPage || this.__loadingPrevPage || this.__unloadingPage || !(this.props.hasNextPage || this.props.hasPrevPage)) {
			if (e) {
				e.preventDefault();
			}
			return;
		}

		var pages = this.__pages;
		var pageIds = this.__pageIds;
		var firstPage = pages[pageIds[0]];
		var secondPage = pages[pageIds[1]];
		var lastPage = pages[pageIds[pageIds.length-1]];
		var secondLastPage = pages[pageIds[pageIds.length-2]];

		if (pages.length < 4) {
			secondPage = null;
			secondLastPage = null;
		}

		var viewportHeight = this.__dimentions.viewportHeight;
		var contentHeight = this.__dimentions.contentHeight;
		var offsetTop = this.__dimentions.offsetTop;
		var scrollY = this.__getScrollY();

		var remainingScrollBottom = contentHeight - scrollY - viewportHeight + offsetTop;
		var remainingScrollTop = contentHeight - remainingScrollBottom - viewportHeight;

		if (lastPage && remainingScrollBottom < (lastPage.height / 3)) {
			if (secondPage && remainingScrollTop > (firstPage.height + secondPage.height)) {
				this.__unloadPage(firstPage.id);
			} else {
				this.__loadNextPage();
			}
		} else if (firstPage && remainingScrollTop < (firstPage.height / 3)) {
			if (secondLastPage && remainingScrollBottom > (lastPage.height + secondLastPage.height)) {
				this.__unloadPage(lastPage.id);
			} else {
				this.__loadPrevPage();
			}
		}
	},

	__handleScroll: function (e) {
		this.__evaluatePagesMutation(e);
	},

	__handleResize: function () {
		this.__updateDimensions();
		this.__evaluatePagesMutation();
	}
});

ScrollPagination.Page = React.createClass({
	displayName: "ScrollPagination.Page",

	getDefaultProps: function () {
		return {
			component: React.DOM.div
		};
	},

	componentDidMount: function () {
		this.__determineHeight();
	},

	componentDidUpdate: function () {
		if (this.__height === 0) {
			this.__determineHeight();
		}
	},

	render: function () {
		return this.props.component({ className: this.props.className }, this.props.children);
	},

	__determineHeight: function () {
		var height = this.__height = this.getDOMNode().offsetHeight;
		this.props.onPageEvent(this.props.id, {
			name: "mount",
			height: height
		});
	}
});

})();
<commit_msg>Update ScrollPagination component<commit_after>(function () {
"use strict";

var findScrollParent = function (el) {
	var ref = el;
	while (ref) {
		switch (window.getComputedStyle(ref).overflow) {
			case "auto":
				return ref;
			case "scroll":
				return ref;
		}
		ref = ref.parentElement;
	}
	return window;
};

var ScrollPagination = window.ScrollPagination = React.createClass({
	displayName: "ScrollPagination",

	getDefaultProps: function () {
		return {
			hasPrevPage: false,
			hasNextPage: false,
			loadPrevPage: function () {},
			loadNextPage: function () {}
		};
	},

	componentWillMount: function () {
		this.__pages = {};
		this.__pageIds = [];
	},

	componentDidMount: function () {
		var scrollParent = this.__scrollParent = findScrollParent(this.getDOMNode());
		scrollParent.addEventListener("scroll", this.__handleScroll, false);
		scrollParent.addEventListener("resize", this.__handleResize, false);

		this.__updatePageIds();
		this.__updateDimensions();
	},

	componentDidUpdate: function () {
		this.__updatePageIds();
		this.__updateDimensions();

		this.__loadingNextPage = false;
		this.__loadingPrevPage = false;
		this.__unloadingPage = false;

		this.__evaluatePagesMutation();
	},

	componentWillUnmount: function () {
		var scrollParent = this.__scrollParent;
		scrollParent.removeEventListener("scroll", this.__handleScroll, false);
		scrollParent.removeEventListener("resize", this.__handleResize, false);
	},

	render: function () {
		var style = {};
		if (this.__paddingTop) {
			style.paddingTop = this.__paddingTop + "px";
		}
		return React.DOM.div({
			style: style,
			ref: "wrapper"
		}, this.props.children);
	},

	// called from Page component via parent component
	handlePageEvent: function (pageId, event) {
		var pages = this.__pages;
		switch (event.name) {
			case "mount":
				pages[pageId] = {
					id: pageId,
					height: event.height
				};
			break;

			case "update":
				pages[pageId] = {
					id: pageId,
					height: event.height
				};
			break;

			case "unmount":
			break;
		}
		this.__pages = pages;
	},

	__unloadPage: function (pageId) {
		if (this.__unloadingPage) {
			return;
		}
		this.__unloadingPage = true;
		this.props.unloadPage(pageId);
	},

	__loadPrevPage: function () {
		if (this.__loadingPrevPage || !this.props.hasPrevPage) {
			return;
		}
		this.__loadingPrevPage = true;
		this.props.loadPrevPage();
	},

	__loadNextPage: function () {
		if (this.__loadingNextPage || !this.props.hasNextPage) {
			return;
		}
		this.__loadingNextPage = true;
		this.props.loadNextPage();
	},

	__getScrollY: function () {
		var scrollParent = this.__scrollParent;
		if (scrollParent === window) {
			return window.scrollY;
		} else {
			return scrollParent.scrollTop;
		}
	},

	__setScrollY: function (scrollY) {
		var scrollParent = this.__scrollParent;
		if (scrollParent === window) {
			return window.scrollTo(window.scrollX, scrollY);
		} else {
			return scrollParent.scrollTop = scrollY;
		}
	},

	__updatePageIds: function () {
		var oldPageIds = this.__pageIds;
		var unloadedPageIdsTop = [];
		var newPageIdsTop = [];
		var pageIds = [];
		var findPages = function (children) {
			React.Children.forEach(children, function (child) {
				if (child.constructor.displayName === "ScrollPagination.Page") {
					pageIds.push(child.props.id);
				} else if (child.constructor.displayName === "ul") {
					findPages(child.props.children);
				}
			});
		};
		findPages(this.props.children);
		var i, len;
		if (oldPageIds.length > 0) {
			for (i = 0, len = oldPageIds.length; i < len; i++) {
				if (pageIds.indexOf(oldPageIds[i]) === -1) {
					unloadedPageIdsTop.push(oldPageIds[i]);
				} else {
					break;
				}
			}
			for (i = 0, len = pageIds.length; i < len; i++) {
				if (oldPageIds.indexOf(pageIds[i]) === -1) {
					newPageIdsTop.push(pageIds[i]);
				} else {
					break;
				}
			}
		}
		this.__adjustScrollPosition(unloadedPageIdsTop, newPageIdsTop);
		this.__pageIds = pageIds;
	},

	__adjustScrollPosition: function (unloadedPageIdsTop, newPageIdsTop) {
		var offset = 0;
		var pages = this.__pages;
		unloadedPageIdsTop.forEach(function (pageId) {
			var height = pages[pageId].height;
			offset += height;
			delete pages[pageId];
		});
		newPageIdsTop.forEach(function (pageId) {
			var height = pages[pageId].height;
			offset += height;
		});
		this.__setScrollY(this.__getScrollY() + offset);
	},

	__updateDimensions: function () {
		var el = this.refs.wrapper.getDOMNode();
		var scrollParent = this.__scrollParent;
		var viewportHeight = 0;
		if (scrollParent === window) {
			viewportHeight = window.innerHeight;
		} else {
			viewportHeight = parseInt(window.getComputedStyle(scrollParent).height, 10);
		}
		var contentHeight = el.offsetHeight;

		var offsetTop = 0;
		var ref = el;
		while (ref) {
			offsetTop += ref.offsetTop || 0;
			ref = ref.offsetParent;
			if (ref === scrollParent) {
				break;
			}
		}

		this.__dimentions = {
			viewportHeight: viewportHeight,
			contentHeight: contentHeight,
			offsetTop: offsetTop
		};
	},

	__evaluatePagesMutation: function (e) {
		if (this.__dimentions.contentHeight === 0) {
			return;
		}
		if (this.__loadingNextPage || this.__loadingPrevPage || this.__unloadingPage || !(this.props.hasNextPage || this.props.hasPrevPage)) {
			if (e) {
				e.preventDefault();
			}
			return;
		}

		var pages = this.__pages;
		var pageIds = this.__pageIds;
		var firstPage = pages[pageIds[0]];
		var secondPage = pages[pageIds[1]];
		var lastPage = pages[pageIds[pageIds.length-1]];
		var secondLastPage = pages[pageIds[pageIds.length-2]];

		if (pages.length < 4) {
			secondPage = null;
			secondLastPage = null;
		}

		var viewportHeight = this.__dimentions.viewportHeight;
		var contentHeight = this.__dimentions.contentHeight;
		var offsetTop = this.__dimentions.offsetTop;
		var scrollY = this.__getScrollY();

		var remainingScrollBottom = contentHeight - scrollY - viewportHeight + offsetTop;
		var remainingScrollTop = contentHeight - remainingScrollBottom - viewportHeight;

		if (lastPage && remainingScrollBottom < (lastPage.height / 3)) {
			if (secondPage && remainingScrollTop > (firstPage.height + secondPage.height)) {
				this.__unloadPage(firstPage.id);
			} else {
				this.__loadNextPage();
			}
		} else if (firstPage && remainingScrollTop < (firstPage.height / 3)) {
			if (secondLastPage && remainingScrollBottom > (lastPage.height + secondLastPage.height)) {
				this.__unloadPage(lastPage.id);
			} else {
				this.__loadPrevPage();
			}
		}
	},

	__handleScroll: function (e) {
		this.__evaluatePagesMutation(e);
	},

	__handleResize: function () {
		this.__updateDimensions();
		this.__evaluatePagesMutation();
	}
});

ScrollPagination.Page = React.createClass({
	displayName: "ScrollPagination.Page",

	getDefaultProps: function () {
		return {
			component: React.DOM.div
		};
	},

	componentDidMount: function () {
		this.__determineHeight();
	},

	componentDidUpdate: function () {
		if (this.__height === 0) {
			this.__determineHeight();
		}
	},

	render: function () {
		var props = {};
		for (var k in this.props) {
			if (k !== "component" && k !== "onPageEvent" && k !== "id" && this.props.hasOwnProperty(k)) {
				props[k] = this.props[k];
			}
		}
		return this.props.component(props, this.props.children);
	},

	__determineHeight: function () {
		var height = this.__height = this.getDOMNode().offsetHeight;
		this.props.onPageEvent(this.props.id, {
			name: "mount",
			height: height
		});
	}
});

})();
<|endoftext|>