<commit_before>/* Author: Praekelt */

$("#id_start_time").timePicker({step:10, startTime:"00:00", endTime:"23:50", show24Hours: true,separator: ':',});
$('#id_message').keyup(function(){
	    	$('#charcount').text($('#id_message').val().length);
			if($('#id_message').val().length>140){$('#valid-twitter').hide()}else{$('#valid-twitter').show()}
			if($('#id_message').val().length>160){$('#valid-sms').hide()}else{$('#valid-sms').show()}
			$('span.preview-message').text($('#id_message').val());

});

$('.typeahead').typeahead();

$(function() { $( "#id_start_date" ).datepicker({ minDate: 0, dateFormat: 'yy-mm-dd' }); });
$(function() { $( "#dob" ).datepicker({ minDate: 0, dateFormat: 'yy-mm-dd' }); });

$('#surveyUSSD').click(function() {
	if($('#surveyUSSD').attr('checked')) { $('#surveyUSSDNum').show(); } else { $('#surveyUSSDNum').hide(); }
});

$('#convtype').change(function() {
	var newAction = $('#convtype').val();
	$('#newConversationType').attr('action', newAction);
});

/* show or hide the tag pool options depending on the delivery class chosen */
$('.delivery-class-radio').change(function() {
    delivery_classes = $('.delivery-class-radio[name=delivery_class]');
    delivery_classes.each(function(index, element) {
        var deliveryClass = $(element);
        var tagPoolDiv = $('#' + deliveryClass.val() + '_tag_pool_selection');
        var selectField = $('#' + deliveryClass.val() + '_tag_pool_selection select');
        if($(deliveryClass).attr('checked')) {
            tagPoolDiv.show();
            selectField.removeAttr('disabled');
        } else {
            tagPoolDiv.hide();
            selectField.attr('disabled', 'disabled');
        }
    });

})<commit_msg>ensure JS is only executed after DOM has loaded<commit_after>/* Author: Praekelt */
$(document).ready(function(){
    $("#id_start_time").timePicker({
        step: 10,
        startTime: "00:00",
        endTime: "23:50",
        show24Hours: true,
        separator: ':'
    });

    $('#id_message').keyup(function(){
        $('#charcount').text($('#id_message').val().length);
        if($('#id_message').val().length>140){
            $('#valid-twitter').hide();
        } else {
            $('#valid-twitter').show();
        }
        if($('#id_message').val().length>160){
            $('#valid-sms').hide();
        } else {
            $('#valid-sms').show();
        }
        $('span.preview-message').text($('#id_message').val());

    });

    $('.typeahead').typeahead();

    $(function() { $( "#id_start_date" ).datepicker({ minDate: 0, dateFormat: 'yy-mm-dd' }); });
    $(function() { $( "#dob" ).datepicker({ minDate: 0, dateFormat: 'yy-mm-dd' }); });

    $('#surveyUSSD').click(function() {
        if($('#surveyUSSD').attr('checked')) { $('#surveyUSSDNum').show(); } else { $('#surveyUSSDNum').hide(); }
    });

    $('#convtype').change(function() {
        var newAction = $('#convtype').val();
        $('#newConversationType').attr('action', newAction);
    });

    /* show or hide the tag pool options depending on the delivery class chosen */
    $('.delivery-class-radio').change(function() {
        delivery_classes = $('.delivery-class-radio[name=delivery_class]');
        delivery_classes.each(function(index, element) {
            var deliveryClass = $(element);
            var tagPoolDiv = $('#' + deliveryClass.val() + '_tag_pool_selection');
            var selectField = $('#' + deliveryClass.val() + '_tag_pool_selection select');
            if($(deliveryClass).attr('checked')) {
                tagPoolDiv.show();
                selectField.removeAttr('disabled');
            } else {
                tagPoolDiv.hide();
                selectField.attr('disabled', 'disabled');
            }
        });
    });
});
<|endoftext|>


<commit_before>import * as helpers from 'apps/authoring/authoring/helpers';

AuthoringEmbeddedDirective.$inject = ['api', 'notify', 'gettext', '$filter', 'config'];
export function AuthoringEmbeddedDirective(api, notify, gettext, $filter, config) {
    return {
        templateUrl: 'scripts/apps/authoring/views/authoring.html',
        scope: {
            item: '=',
            action: '='
        },
        link: function(scope) {
            if (scope.action === 'kill') {
                // kill template is applied on the item.
                // task is required to get the desk name.
                var fields = _.union(_.keys(helpers.CONTENT_FIELDS_DEFAULTS), ['_id', 'versioncreated', 'task']);
                var item = {
                    template_name: 'kill', item: _.pick(scope.item, fields)
                };

                api.save('content_templates_apply', {}, item, {}).then((result) => {
                    item = _.pick(result, _.keys(helpers.CONTENT_FIELDS_DEFAULTS));
                    scope.origItem = angular.extend({}, scope.item);
                    _.each(item, (value, key) => {
                        scope.origItem[key] = value;
                    });
                }, (err) => {
                    notify.error(gettext('Failed to apply kill template to the item.'));
                });
            } else {
                if (scope.action === 'correct') {
                    scope.item.ednote = gettext('In the story "') + scope.item.slugline + gettext('" sent at: ') +
                    $filter('formatLocalDateTimeString')(scope.item.versioncreated, config.view.dateformat + ' ' +
                        config.view.timeformat) +
                    gettext('\r\n\r\nThis is a corrected repeat.');
                    scope.item.flags.marked_for_sms = false;
                    scope.item.sms_message = '';
                }
                scope.origItem = scope.item;
            }
        }
    };
}
<commit_msg>[AUTHORING] Use backend settings to override editor note<commit_after>import * as helpers from 'apps/authoring/authoring/helpers';

AuthoringEmbeddedDirective.$inject = ['api', 'notify', 'gettext', '$filter', 'config', 'deployConfig', '$interpolate'];
export function AuthoringEmbeddedDirective(api, notify, gettext, $filter, config, deployConfig, $interpolate) {
    return {
        templateUrl: 'scripts/apps/authoring/views/authoring.html',
        scope: {
            item: '=',
            action: '='
        },
        link: function(scope) {
            function overrideEdnote(template) {
                /* Override Editor note with given template or default one
                 *
                 * @param {string} template - template to use (set in backend)
                 */
                let date = $filter('formatLocalDateTimeString')(scope.item.versioncreated, config.view.dateformat +
                    ' ' + config.view.timeformat);

                if (template == null) {
                    // no template specified in backend, we use default one
                    let slugline = scope.item.slugline ? '"' + scope.item.slugline + '" ' : '';

                    scope.item.ednote = $interpolate(gettext('In the story {{ slugline }} sent at: {{ date }}\r\n' +
                        '\r\nThis is corrected repeat.'))({slugline, date});
                } else {
                    // we use template from backend
                    scope.item.ednote = template
                        .replace('{date}', date)
                        .replace('{slugline}', scope.item.slugline || '');
                }
            }
            if (scope.action === 'kill') {
                // kill template is applied on the item.
                // task is required to get the desk name.
                var fields = _.union(_.keys(helpers.CONTENT_FIELDS_DEFAULTS), ['_id', 'versioncreated', 'task']);
                var item = {
                    template_name: 'kill', item: _.pick(scope.item, fields)
                };

                api.save('content_templates_apply', {}, item, {}).then((result) => {
                    item = _.pick(result, _.keys(helpers.CONTENT_FIELDS_DEFAULTS));
                    scope.origItem = angular.extend({}, scope.item);
                    _.each(item, (value, key) => {
                        scope.origItem[key] = value;
                    });
                }, (err) => {
                    notify.error(gettext('Failed to apply kill template to the item.'));
                });
            } else if (scope.action === 'correct') {
                deployConfig.all({
                    override: 'override_ednote_for_corrections',
                    template: 'override_ednote_template'
                }).then((config) => {
                    if (config.override) {
                        overrideEdnote(config.template);
                    }
                    scope.origItem = scope.item;
                });
                scope.item.flags.marked_for_sms = false;
                scope.item.sms_message = '';
            } else {
                scope.origItem = scope.item;
            }
        }
    };
}
<|endoftext|>


<commit_before>Package.describe({
  name: 'bennyz:errors',
  version: '0.0.1',
  // Brief, one-line summary of the package.
  summary: '',
  // URL to the Git repository containing the source code for this package.
  git: '',
  // By default, Meteor will default to using README.md for documentation.
  // To avoid submitting documentation, set this field to null.
  documentation: 'README.md'
});

Package.onUse(function(api) {
  api.versionsFrom('1.1.0.2');
  api.addFiles('errors.js');
});

Package.onTest(function(api) {
  api.use('tinytest');
  api.use('bennyz:errors');
  api.addFiles('errors-tests.js');
});
<commit_msg>Modify package.js for errors package<commit_after>Package.describe({
  name: 'bennyz:errors',
  version: '0.0.1',
  summary: 'Handle errors nicely',
});

Package.onUse(function(api) {
  api.versionsFrom('1.1.0.2');
  api.use(['minimongo', 'mongo-livedata', 'templating'], 'client');
  api.addFiles(['errors.js, errors_list.html', 'errors_list.js'], 'client');

  if (api.export) [
    api.export('Errors');
  }
});

Package.onTest(function(api) {
  api.use('tinytest');
  api.use('bennyz:errors');
  api.addFiles('errors-tests.js');
});
<|endoftext|>


<commit_before><commit_msg>More reasonable default<commit_after><|endoftext|>


<commit_before>// All other packages automatically depend on this one

Package.describe({
  summary: "Core Meteor environment",
  version: '1.8.5'
});

Package.registerBuildPlugin({
  name: "basicFileTypes",
  sources: ['plugin/basic-file-types.js']
});

Npm.depends({
  "meteor-deque": "2.1.0"
});

Package.onUse(function (api) {
  api.use('isobuild:compiler-plugin@1.0.0');

  api.export('Meteor');

  api.addFiles('global.js', ['client', 'server']);
  api.export('global');

  api.addFiles('client_environment.js', 'client');
  api.addFiles('server_environment.js', 'server');
  // Defined by client_environment.js and server_environment.js.
  api.export("meteorEnv");

  api.addFiles('cordova_environment.js', 'web.cordova');
  api.addFiles('define-package.js', ['client', 'server']);
  api.addFiles('helpers.js', ['client', 'server']);
  api.addFiles('setimmediate.js', ['client', 'server']);
  api.addFiles('timers.js', ['client', 'server']);
  api.addFiles('errors.js', ['client', 'server']);
  api.addFiles('fiber_helpers.js', 'server');
  api.addFiles('fiber_stubs_client.js', 'client');
  api.addFiles('startup_client.js', ['client']);
  api.addFiles('startup_server.js', ['server']);
  api.addFiles('debug.js', ['client', 'server']);
  api.addFiles('string_utils.js', ['client', 'server']);
  api.addFiles('test_environment.js', ['client', 'server']);

  // dynamic variables, bindEnvironment
  // XXX move into a separate package?
  api.addFiles('dynamics_browser.js', 'client');
  api.addFiles('dynamics_nodejs.js', 'server');

  // note server before common. usually it is the other way around, but
  // in this case server must load first.
  api.addFiles('url_server.js', 'server');
  api.addFiles('url_common.js', ['client', 'server']);

  // People expect process.exit() to not swallow console output.
  // On Windows, it sometimes does, so we fix it for all apps and packages
  api.addFiles('flush-buffers-on-exit-in-windows.js', 'server');
});

Package.onTest(function (api) {
  api.use(['underscore', 'tinytest', 'test-helpers']);

  api.addFiles('browser_environment_test.js', 'web.browser');
  api.addFiles('client_environment_test.js', 'client');
  api.addFiles('cordova_environment_test.js', 'web.cordova');
  api.addFiles('server_environment_test.js', 'server');

  api.addFiles('helpers_test.js', ['client', 'server']);
  api.addFiles('dynamics_test.js', ['client', 'server']);

  api.addFiles('fiber_helpers_test.js', ['server']);
  api.addFiles('wrapasync_test.js', ['server']);

  api.addFiles('url_tests.js', ['client', 'server']);

  api.addFiles('timers_tests.js', ['client', 'server']);

  api.addFiles('debug_test.js', 'client');

  api.addFiles('bare_test_setup.js', 'client', {bare: true});
  api.addFiles('bare_tests.js', 'client');
});
<commit_msg>Bump meteor package version to 1.8.6 to publish with Meteor 1.6.0.1.<commit_after>// All other packages automatically depend on this one

Package.describe({
  summary: "Core Meteor environment",
  version: '1.8.6'
});

Package.registerBuildPlugin({
  name: "basicFileTypes",
  sources: ['plugin/basic-file-types.js']
});

Npm.depends({
  "meteor-deque": "2.1.0"
});

Package.onUse(function (api) {
  api.use('isobuild:compiler-plugin@1.0.0');

  api.export('Meteor');

  api.addFiles('global.js', ['client', 'server']);
  api.export('global');

  api.addFiles('client_environment.js', 'client');
  api.addFiles('server_environment.js', 'server');
  // Defined by client_environment.js and server_environment.js.
  api.export("meteorEnv");

  api.addFiles('cordova_environment.js', 'web.cordova');
  api.addFiles('define-package.js', ['client', 'server']);
  api.addFiles('helpers.js', ['client', 'server']);
  api.addFiles('setimmediate.js', ['client', 'server']);
  api.addFiles('timers.js', ['client', 'server']);
  api.addFiles('errors.js', ['client', 'server']);
  api.addFiles('fiber_helpers.js', 'server');
  api.addFiles('fiber_stubs_client.js', 'client');
  api.addFiles('startup_client.js', ['client']);
  api.addFiles('startup_server.js', ['server']);
  api.addFiles('debug.js', ['client', 'server']);
  api.addFiles('string_utils.js', ['client', 'server']);
  api.addFiles('test_environment.js', ['client', 'server']);

  // dynamic variables, bindEnvironment
  // XXX move into a separate package?
  api.addFiles('dynamics_browser.js', 'client');
  api.addFiles('dynamics_nodejs.js', 'server');

  // note server before common. usually it is the other way around, but
  // in this case server must load first.
  api.addFiles('url_server.js', 'server');
  api.addFiles('url_common.js', ['client', 'server']);

  // People expect process.exit() to not swallow console output.
  // On Windows, it sometimes does, so we fix it for all apps and packages
  api.addFiles('flush-buffers-on-exit-in-windows.js', 'server');
});

Package.onTest(function (api) {
  api.use(['underscore', 'tinytest', 'test-helpers']);

  api.addFiles('browser_environment_test.js', 'web.browser');
  api.addFiles('client_environment_test.js', 'client');
  api.addFiles('cordova_environment_test.js', 'web.cordova');
  api.addFiles('server_environment_test.js', 'server');

  api.addFiles('helpers_test.js', ['client', 'server']);
  api.addFiles('dynamics_test.js', ['client', 'server']);

  api.addFiles('fiber_helpers_test.js', ['server']);
  api.addFiles('wrapasync_test.js', ['server']);

  api.addFiles('url_tests.js', ['client', 'server']);

  api.addFiles('timers_tests.js', ['client', 'server']);

  api.addFiles('debug_test.js', 'client');

  api.addFiles('bare_test_setup.js', 'client', {bare: true});
  api.addFiles('bare_tests.js', 'client');
});
<|endoftext|>


<commit_before>function Wavebox(args) {
    if (arguments.length) {
        this.getready(args);
    }
}

extend(Wavebox, Element);

Wavebox.prototype.getready = function (args) {

    // Call the constructor from the superclass.
    Wavebox.superclass.getready.call(this, args);

    this.values = {"waveboxposition" : 0,
                   "startsample" : 0,
                   "endsample" : null,
                   "waveboxsignal" : undefined
               };
    this.defaultSlot = "waveboxposition";

    this.setWidth(args.width);
    this.setHeight(args.height);

};

// This methods returns true if the point given belongs to this element.
Wavebox.prototype.isInROI = function (x, y) {
    if ((x > this.ROILeft) && (y > this.ROITop)) {
        if ((x < (this.ROILeft + this.ROIWidth)) && (y < (this.ROITop + this.ROIHeight))) {
            return true;
        }
    }
    return false;
};

Wavebox.prototype.setValue = function (slot, value) {

    // Won't call the parent: this element has a custom way to set values.

    if (this.values[slot] === undefined) {
        throw new Error("Slot " + slot + " not present or value undefined");
    }

    if (this.values[slot] === value) {
        //Nothing changed, don't redraw.
        return;
    }

    // Check some boundaries.

    if ((slot === "startsample") || (slot === "endsample")) {
        if (value < 0) {
            throw new Error("Error: Trying to set ", slot, " less than 0: ", value);
        }
        if (this.values["waveboxsignal"] !== undefined) {
            if (value > this.values["waveboxsignal"].length) {
                throw new Error("Error: Trying to set ", slot, " bigger than signal length: ", value, " > ", this.values["waveboxsignal"].length);
            }
        }
    }

    if (slot === "startsample") {
        if (value > this.values["endsample"]) {
                throw new Error("Error: Trying to set startsample > endsample: ", value, " > ", this.values["endsample"]);
            }
    }

    if (slot === "endsample") {
        if (value < this.values["startample"]) {
                throw new Error("Error: Trying to set endsample < startsample: ", value, " < ", this.values["startsample"]);
            }
    }

    this.values[slot] = value;
    // console.log ("set value for slot ", slot);

    // When we change the signal, we know we must reset the whole thing.
    if (slot === "waveboxsignal") {
        //Take the whole waveform
        // console.log ("inside!");
        this.values["endsample"] = this.values["waveboxsignal"].length;
        this.values["startsample"] = 0;
    }
};

Wavebox.prototype.refresh = function () {
    if (this.drawClass !== undefined) {
        // Draw, if our draw class is already set.

        // Call the superclass.
        Wavebox.superclass.refresh.call(this, this.drawClass.drawPath);
        // Draw, if our draw class is already set.
        if (this.isVisible === true) {

            var oldpoint = 0;
            this.drawClass.drawPath.beginDraw();

            for (var i = 0; i < this.width; i += 1) {
                var point = this.calculateSampleCoord(i);
                if (point !== oldpoint) {
                    //console.log ("Drawing a point, x is ", point.x, " y is ", point.y);
                    //this.drawClass.drawImage.draw(this.imagesArray[imageNum], this.xOrigin, this.yOrigin);
                    this.drawClass.drawPath.draw(point.x, point.y);
                }
                oldpoint = point;
            }
            this.drawClass.drawPath.endDraw();

        }
    }
};

//Non-interface functions

Wavebox.prototype.sampleindexToY = function (samplenum) {
    //Check boundaries
    if ((samplenum >= this.values.endsample) || (this.values.waveboxsignal[samplenum] === undefined) || (this.values.waveboxsignal[samplenum] === null)) {
        throw new Error("Error: problem with sample index: ", samplenum, " or sample value: ", this.values.waveboxsignal[samplenum]);
    }

    //We got a sample number, and we want to know where it should be drawn.
    //Sample values go from -1 to 1.
    //NewValue = (((OldValue - OldMin) * (NewMax - NewMin)) / (OldMax - OldMin)) + NewMin
    var range01 = (this.values.waveboxsignal[samplenum] + 1) / 2;
    //console.log ("signal that was ", this.values.waveboxsignal[samplenum], " is now transformed in ", range01);
    var temp = ((1 - range01) *  this.height);
    //console.log ("Adding to origin ", temp);
    var y = this.yOrigin + temp;
    return parseInt (y, 10);

}

Wavebox.prototype.sampleXToIndex = function (xcoord) {

    var factor = ((this.values.endsample - this.values.startsample) / this.width);
    var x = xcoord * factor;
    var ret = parseInt (x, 10);
    //if (( x % 100) == 0 ) {
        //console.log ("xcoord is ", xcoord , " of ", this.width , " factor is ", factor, " and corresponding sample number is ", ret , " finishing at ", this.values.endsample);
    //}
    return ret;

}

Wavebox.prototype.calculateSampleCoord = function (xcoord) {
    // this returns the absolute x,y coordinates from the sample in x position, relative to the x-origin of the box
    var ret = {};
    ret.x = xcoord + this.xOrigin;
    ret.y = this.sampleindexToY(this.sampleXToIndex(xcoord));
    return ret;
}

Wavebox.prototype.setGraphicWrapper = function (wrapper) {

    // Call the superclass.
    Wavebox.superclass.setGraphicWrapper.call(this, wrapper);

    // Get the wrapper primitive functions
    this.drawClass = wrapper.initObject ([{objName: "drawPath",
                                           objParms: this.objParms}]);

};<commit_msg>Fixed a Wavebox bug.<commit_after>function Wavebox(args) {
    if (arguments.length) {
        this.getready(args);
    }
}

extend(Wavebox, Element);

Wavebox.prototype.getready = function (args) {

    // Call the constructor from the superclass.
    Wavebox.superclass.getready.call(this, args);

    this.values = {"waveboxposition" : 0,
                   "startsample" : 0,
                   "endsample" : null,
                   "waveboxsignal" : []
               };
    this.defaultSlot = "waveboxposition";

    this.setWidth(args.width);
    this.setHeight(args.height);

};

// This methods returns true if the point given belongs to this element.
Wavebox.prototype.isInROI = function (x, y) {
    if ((x > this.ROILeft) && (y > this.ROITop)) {
        if ((x < (this.ROILeft + this.ROIWidth)) && (y < (this.ROITop + this.ROIHeight))) {
            return true;
        }
    }
    return false;
};

Wavebox.prototype.setValue = function (slot, value) {

    // Won't call the parent: this element has a custom way to set values.

    if (this.values[slot] === undefined) {
        throw new Error("Slot " + slot + " not present or value undefined");
    }

    if (this.values[slot] === value) {
        //Nothing changed, don't redraw.
        return;
    }

    // Check some boundaries.

    if ((slot === "startsample") || (slot === "endsample")) {
        if (value < 0) {
            throw new Error("Error: Trying to set ", slot, " less than 0: ", value);
        }
        if (this.values["waveboxsignal"] !== undefined) {
            if (value > this.values["waveboxsignal"].length) {
                throw new Error("Error: Trying to set ", slot, " bigger than signal length: ", value, " > ", this.values["waveboxsignal"].length);
            }
        }
    }

    if (slot === "startsample") {
        if (value > this.values["endsample"]) {
                throw new Error("Error: Trying to set startsample > endsample: ", value, " > ", this.values["endsample"]);
            }
    }

    if (slot === "endsample") {
        if (value < this.values["startample"]) {
                throw new Error("Error: Trying to set endsample < startsample: ", value, " < ", this.values["startsample"]);
            }
    }

    this.values[slot] = value;
    // console.log ("set value for slot ", slot);

    // When we change the signal, we know we must reset the whole thing.
    if (slot === "waveboxsignal") {
        //Take the whole waveform
        // console.log ("inside!");
        this.values["endsample"] = this.values["waveboxsignal"].length;
        this.values["startsample"] = 0;
    }
};

Wavebox.prototype.refresh = function () {
    if (this.drawClass !== undefined) {
        // Draw, if our draw class is already set.

        // Call the superclass.
        Wavebox.superclass.refresh.call(this, this.drawClass.drawPath);
        // Draw, if our draw class is already set.
        if (this.isVisible === true) {

            var oldpoint = 0;
            this.drawClass.drawPath.beginDraw();

            for (var i = 0; i < this.width; i += 1) {
                var point = this.calculateSampleCoord(i);
                if (point !== oldpoint) {
                    //console.log ("Drawing a point, x is ", point.x, " y is ", point.y);
                    //this.drawClass.drawImage.draw(this.imagesArray[imageNum], this.xOrigin, this.yOrigin);
                    this.drawClass.drawPath.draw(point.x, point.y);
                }
                oldpoint = point;
            }
            this.drawClass.drawPath.endDraw();

        }
    }
};

//Non-interface functions

Wavebox.prototype.sampleindexToY = function (samplenum) {
    //Check boundaries
    if ((samplenum >= this.values.endsample) || (this.values.waveboxsignal[samplenum] === undefined) || (this.values.waveboxsignal[samplenum] === null)) {
        throw new Error("Error: problem with sample index: ", samplenum, " or sample value: ", this.values.waveboxsignal[samplenum]);
    }

    //We got a sample number, and we want to know where it should be drawn.
    //Sample values go from -1 to 1.
    //NewValue = (((OldValue - OldMin) * (NewMax - NewMin)) / (OldMax - OldMin)) + NewMin
    var range01 = (this.values.waveboxsignal[samplenum] + 1) / 2;
    //console.log ("signal that was ", this.values.waveboxsignal[samplenum], " is now transformed in ", range01);
    var temp = ((1 - range01) *  this.height);
    //console.log ("Adding to origin ", temp);
    var y = this.yOrigin + temp;
    return parseInt (y, 10);

}

Wavebox.prototype.sampleXToIndex = function (xcoord) {

    var factor = ((this.values.endsample - this.values.startsample) / this.width);
    var x = xcoord * factor;
    var ret = parseInt (x, 10);
    //if (( x % 100) == 0 ) {
        //console.log ("xcoord is ", xcoord , " of ", this.width , " factor is ", factor, " and corresponding sample number is ", ret , " finishing at ", this.values.endsample);
    //}
    return ret;

}

Wavebox.prototype.calculateSampleCoord = function (xcoord) {
    // this returns the absolute x,y coordinates from the sample in x position, relative to the x-origin of the box
    var ret = {};
    ret.x = xcoord + this.xOrigin;
    ret.y = this.sampleindexToY(this.sampleXToIndex(xcoord));
    return ret;
}

Wavebox.prototype.setGraphicWrapper = function (wrapper) {

    // Call the superclass.
    Wavebox.superclass.setGraphicWrapper.call(this, wrapper);

    // Get the wrapper primitive functions
    this.drawClass = wrapper.initObject ([{objName: "drawPath",
                                           objParms: this.objParms}]);

};<|endoftext|>


<commit_before>define(["sugar-web/graphics/palette",
        "sugar-web/env"], function (palette, env) {

    var activitypalette = {};

    activitypalette.ActivityPalette = function (activityButton,
        datastoreObject) {

        palette.Palette.call(this, activityButton);

        var activityTitle;
        var descriptionLabel;
        var descriptionBox;

        this.getPalette().id = "activity-palette";

        var titleContainer = document.createElement('div');
        titleContainer.className = "row";
        activityTitle = document.createElement('input');
        activityTitle.type = "text";
        activityTitle.id = "title";
        activityTitle.className = "expand";
        titleContainer.appendChild(activityTitle);

        var descLabelContainer = document.createElement('div');
        descLabelContainer.className = "row small";
        descriptionLabel = document.createElement('label');
        descriptionLabel.innerHTML = "Description:";
        descLabelContainer.appendChild(descriptionLabel);

        var descriptionContainer = document.createElement('div');
        descriptionContainer.className = "row expand";
        descriptionBox = document.createElement('textarea');
        descriptionBox.rows = "8";
        descriptionBox.id = "description";
        descriptionBox.className = "expand";
        descriptionContainer.appendChild(descriptionBox);

        this.setContent([titleContainer, descLabelContainer,
                         descriptionContainer]);

        this.titleElem = document.getElementById("title");
        this.descriptionElem = document.getElementById("description");

        this.titleElem.onblur = function () {
            datastoreObject.setMetadata({
                "title": this.value
            });
            datastoreObject.save(function () {});
        };

        this.descriptionElem.onblur = function () {
            datastoreObject.setMetadata({
                "description": this.value
            });
            datastoreObject.save(function () {});
        };
    };

    // Fill the text inputs with the received metadata.
    var setTitleDescription = function (metadata) {
        var that = this;
        if (metadata.title === undefined) {
            env.getEnvironment(function (error, environment) {
                that.titleElem.value = environment.activityName;
            });
        } else {
            this.titleElem.value = metadata.title;
        }

        if (metadata.description !== undefined) {
            this.descriptionElem.value = metadata.description;
        }
    };

    activitypalette.ActivityPalette.prototype =
        Object.create(palette.Palette.prototype, {
        setTitleDescription: {
            value: setTitleDescription,
            enumerable: true,
            configurable: true,
            writable: true
        }
    });

    return activitypalette;
});
<commit_msg>ActivityPalette: write HTML directly<commit_after>define(["sugar-web/graphics/palette",
        "sugar-web/env"], function (palette, env) {

    var activitypalette = {};

    activitypalette.ActivityPalette = function (activityButton,
        datastoreObject) {

        palette.Palette.call(this, activityButton);

        var activityTitle;
        var descriptionLabel;
        var descriptionBox;

        this.getPalette().id = "activity-palette";

        this.template =
            '
' +
            '<input type="text" id="title" class="expand">' +
            '
' +
            '
' +
            'Description:' +
            '
' +
            '
' +
            '<textarea rows="8" id="description" class="expand"></textarea>' +
            '
';

        var containerElem = document.createElement('div');
        containerElem.innerHTML = this.template;
        this.setContent([containerElem]);

        this.titleElem = containerElem.querySelector('#title');
        this.descriptionElem = containerElem.querySelector('#description');

        this.titleElem.onblur = function () {
            datastoreObject.setMetadata({
                "title": this.value
            });
            datastoreObject.save(function () {});
        };

        this.descriptionElem.onblur = function () {
            datastoreObject.setMetadata({
                "description": this.value
            });
            datastoreObject.save(function () {});
        };
    };

    // Fill the text inputs with the received metadata.
    var setTitleDescription = function (metadata) {
        var that = this;
        if (metadata.title === undefined) {
            env.getEnvironment(function (error, environment) {
                that.titleElem.value = environment.activityName;
            });
        } else {
            this.titleElem.value = metadata.title;
        }

        if (metadata.description !== undefined) {
            this.descriptionElem.value = metadata.description;
        }
    };

    activitypalette.ActivityPalette.prototype =
        Object.create(palette.Palette.prototype, {
        setTitleDescription: {
            value: setTitleDescription,
            enumerable: true,
            configurable: true,
            writable: true
        }
    });

    return activitypalette;
});
<|endoftext|>


<commit_before>var extend = require('jquery-extend');
var request = require('request');

module.exports = function (grunt) {

    function downloadOnePokemon(requestParams, cb) {
        var outFile = requestParams.outFile();
        grunt.log.ok('Downloading to ' + outFile);

        request.post({
            url: requestParams.url,
            method: 'POST',
            headers: requestParams.headers,
            form: requestParams.params
        }, function (err, res, body) {
            if (!err) {
                grunt.file.write(outFile, body);
                var json = JSON.parse(body);
                cb(true, json.nextPokemonId);
            } else {
                grunt.fail.warn('Error retrieving data from Global Link: ' + err);
                cb(false, '1-0');
            }
        });
    }

    function downloadAllPokemon(rawDir, requestParams, cb) {
        requestParams.params = requestParams.initialParams;
        requestParams.outFile = function () {
            return rawDir + '/' + requestParams.params.pokemonId + '.json'
        };

        function keepGoing (res, nextId) {
            if (nextId === '1-0') {
                cb(res);
            } else {
                requestParams.params.pokemonId = nextId;
                downloadOnePokemon(requestParams, keepGoing);
            }
        }

        downloadOnePokemon(requestParams, keepGoing);
    }

    function getFormeName(info) {
        if (info.name === 'Rotom') {
            switch (info.typeName2) {
                case 'Ghost':
                    return 'Rotom';
                case 'Grass':
                    return 'Rotom-C';
                case 'Ice':
                    return 'Rotom-F';
                case 'Fire':
                    return 'Rotom-H';
                case 'Flying':
                    return 'Rotom-S';
                case 'Water':
                    return 'Rotom-W';
            }
        } else if (info.name === 'Landorus' ||
                   info.name === 'Tornadus' ||
                   info.name === 'Thundurus') {
            if (info.formNo === '1') {
                return info.name + '-T';
            }
        } else if (info.name === 'Pumpkaboo' ||
                   info.name === 'Gourgeist') {
            switch (info.formNo) {
                case '0':
                    return info.name + '-Average';
                case '1':
                    return info.name + '-Small';
                case '2':
                    return info.name + '-Large';
                case '3':
                    return info.name + '-Super';

            }
        }
        return info.name;
    }

    function individualSet(data) {
        var rv = {};
        // We need the "info" for the name (and possibly types), and "trend" for the rest of the data
        if (data && data.rankingPokemonInfo && data.rankingPokemonTrend) {
            try {
                // Note: This assumes all info arrays are properly ranked.  If that ever changes, this'll
                // need to actually sort the arrays (or at least look for ranking === 1)
                var trend   = data.rankingPokemonTrend;
                var nature  = trend.seikakuInfo && trend.seikakuInfo[0].name;
                var ability = trend.tokuseiInfo && trend.tokuseiInfo[0].name;
                var item    = trend.itemInfo && trend.itemInfo[0].name;
                var moves   = trend.wazaInfo && trend.wazaInfo.slice(0,4).map(function (a) { return a.name; });
                var name    = getFormeName(data.rankingPokemonInfo);

                rv[name] = {
                    "Common Battle Spot": {
                        level:   50,
                        evs:     {},
                        nature:  grunt.LevenWork.closestNature(nature),
                        ability: grunt.LevenWork.closestAbility(ability),
                        item:    grunt.LevenWork.closestItem(item),
                        moves:   moves.map(function (a) { return grunt.LevenWork.closestMove(a); })
                    }
                };
            } catch (e) {
                grunt.fail.warn('Error extracting set info for ' + data.rankingPokemonInfo.name + ': ' + e);
            }
        }
        return rv;
    }

    function generateGlobalLinkDex(inDir, out) {
        var sets = {};
        grunt.log.write('Processing sets');
        grunt.file.recurse(inDir, function (abspath) {
            sets = extend(sets, individualSet(grunt.file.readJSON(abspath)));
            grunt.log.write('.');
        });
        grunt.log.ok();

        var outText = 'var SETDEX_GLOBALLINK=' + JSON.stringify(sets, null, 2) +';';
        var trueOutf = process.cwd() + '/' + out;
        grunt.log.ok('Writing output to ' + trueOutf);
        grunt.file.write(trueOutf, outText);

    }

    grunt.registerTask('globalLinkDownload', 'Download the Global Link data', function () {
        var done = this.async();
        downloadAllPokemon(
            grunt.config([this.name, 'rawDir']) + '/' + grunt.template.today('yyyy-mm-dd'),
            grunt.config([this.name, 'request']),
            function (res) {
                done(res);
            }
        );
    });

    grunt.registerTask('globalLink', 'Generate Global Link dex data', function () {
        generateGlobalLinkDex(
            grunt.config([this.name, 'rawDir']),
            grunt.config([this.name, 'genFile'])
        );
    });
};<commit_msg>Stripped the dex-gen stuff out of globalLinkDownload<commit_after>var extend = require('jquery-extend');
var request = require('request');

module.exports = function (grunt) {

    function downloadOnePokemon(requestParams, cb) {
        var outFile = requestParams.outFile();
        grunt.log.ok('Downloading to ' + outFile);

        request.post({
            url: requestParams.url,
            method: 'POST',
            headers: requestParams.headers,
            form: requestParams.params
        }, function (err, res, body) {
            if (!err) {
                grunt.file.write(outFile, body);
                var json = JSON.parse(body);
                cb(true, json.nextPokemonId);
            } else {
                grunt.fail.warn('Error retrieving data from Global Link: ' + err);
                cb(false, '1-0');
            }
        });
    }

    function downloadAllPokemon(rawDir, requestParams, cb) {
        requestParams.params = requestParams.initialParams;
        requestParams.outFile = function () {
            return rawDir + '/' + requestParams.params.pokemonId + '.json'
        };

        function keepGoing (res, nextId) {
            if (nextId === '1-0') {
                cb(res);
            } else {
                requestParams.params.pokemonId = nextId;
                downloadOnePokemon(requestParams, keepGoing);
            }
        }

        downloadOnePokemon(requestParams, keepGoing);
    }

    grunt.registerTask('globalLinkDownload', 'Download the Global Link data', function () {
        var done = this.async();
        downloadAllPokemon(
            grunt.config([this.name, 'rawDir']) + '/' + grunt.template.today('yyyy-mm-dd'),
            grunt.config([this.name, 'request']),
            function (res) {
                done(res);
            }
        );
    });

};<|endoftext|>


<commit_before>"use strict";

module.exports = {
  options: {
    cleancss: "<%= prod %>",
    sourceMap: "<%= !prod %>"
  },
  all: {
    files: [{
      expand: true,
      cwd: "src/less",
      src: ["*.less"],
      dest: "<%= buildDir %>/css",
      ext: ".css"
    }]
  }
};<commit_msg>Compress CSS in production mode build<commit_after>"use strict";

module.exports = {
  options: {
    compress: "<%= !prod %>",
    cleancss: "<%= prod %>",
    sourceMap: "<%= !prod %>"
  },
  all: {
    files: [{
      expand: true,
      cwd: "src/less",
      src: ["*.less"],
      dest: "<%= buildDir %>/css",
      ext: ".css"
    }]
  }
};<|endoftext|>


<commit_before>/*
 * NTwitBot - retrieve.test.js
 * Copyright (C) 2016-2017 Jordan Sne
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

const Retrieve  = require('../../lib/retrieve.js');
const Twitter   = require('../../lib/twitter.js');
const Util      = require('../../lib/util.js');
const tweetBuilder = require('../builders/tweetbuilder.js');

const utils = new Util();
const retriever = new Retrieve(new Twitter({}, utils), utils);

describe('Retrieve', () => {

    describe('Mention Retrievals', () => {
        const getMentionsSpy = jest.spyOn(retriever.twitterHandler, 'getMentions');

        afterEach(() => {
            getMentionsSpy.mockReset();
        });

        it('should retrieve all mentions of the user', () => {
            getMentionsSpy.mockImplementation(() => Promise.resolve({}));

            return retriever.retrieveMentions(0).then((mentions) => {
                expect(mentions).toBeDefined();
                expect(getMentionsSpy).toHaveBeenCalledWith({ count: 200 });
            });
        });

        it('should retrieve all mentions since a specified ID of the user', () => {
            getMentionsSpy.mockImplementation(() => Promise.resolve({}));

            return retriever.retrieveMentions('5001').then((mentions) => {
                expect(mentions).toBeDefined();
                expect(getMentionsSpy).toHaveBeenCalledWith({ since_id: '5001' });
            });
        });
    });

    describe('Tweet Retrievals', () => {
        describe('Existing Users', () => {
            let retrieveForExistingSpy, getTweetsSpy;

            beforeEach(() => {
                retrieveForExistingSpy = jest.spyOn(retriever, 'retrieveForExisting');
                getTweetsSpy = jest.spyOn(retriever.twitterHandler, 'getTweets');
            });

            afterEach(() => {
                retrieveForExistingSpy.mockRestore();
                getTweetsSpy.mockRestore();
            });

            it('should specify the correct parameters for a retrieval', () => {
                const users = { '001': '5001', '002': '5002' };
                retrieveForExistingSpy.mockImplementation(() => Promise.resolve({}));

                return retriever.retrieveTweets(users).then((tweets) => {
                    expect(tweets).toEqual([ {}, {} ]);
                    expect(retrieveForExistingSpy).toHaveBeenCalledTimes(2);
                    expect(retrieveForExistingSpy).toHaveBeenCalledWith({
                        user_id: '001',
                        since_id: '5001',
                        count: 200,
                        trim_user: true
                    });
                    expect(retrieveForExistingSpy).toHaveBeenCalledWith({
                        user_id: '002',
                        since_id: '5002',
                        count: 200,
                        trim_user: true
                    });
                });
            });

            describe('when receivable tweets < 200', () => {
                it('should properly make Twitter API requests', () => {
                    const users = { '001': '5001' };
                    const mockTweets = tweetBuilder.generateRandomTweets(5);
                    getTweetsSpy
                        .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(0, 5)))
                        .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(4, 5)));

                    return retriever.retrieveTweets(users).then(() => {
                        expect(getTweetsSpy).toHaveBeenCalledTimes(2);
                        expect(getTweetsSpy).toHaveBeenCalledWith({
                            user_id: '001',
                            since_id: '5001',
                            trim_user: true,
                            count: 200
                        });
                        expect(getTweetsSpy).toHaveBeenCalledWith({
                            user_id: '001',
                            since_id: '5001',
                            trim_user: true,
                            count: 200,
                            max_id: mockTweets[4].id_str
                        });
                    });
                });

                it('should return the correct tweets', () => {
                    const users = { '001': '5001' };
                    const mockTweets = tweetBuilder.generateRandomTweets(5);
                    getTweetsSpy
                        .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(0, 5)))
                        .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(4, 5)));

                    return retriever.retrieveTweets(users).then((tweets) => {
                        expect(tweets).toEqual([ mockTweets ]);
                    });
                });
            });

            describe('when receivable tweets > 200', () => {
                it('should properly make Twitter API requests', () => {
                    const users = { '001': '5001' };
                    const mockTweets = tweetBuilder.generateRandomTweets(220);
                    getTweetsSpy
                        .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(0, 200)))
                        .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(199, 210)))
                        .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(209, 210)));

                    return retriever.retrieveTweets(users).then(() => {
                        expect(getTweetsSpy).toHaveBeenCalledTimes(3);
                        expect(getTweetsSpy).toHaveBeenCalledWith({
                            user_id: '001',
                            since_id: '5001',
                            trim_user: true,
                            count: 200
                        });
                        expect(getTweetsSpy).toHaveBeenCalledWith({
                            user_id: '001',
                            since_id: '5001',
                            trim_user: true,
                            count: 200,
                            max_id: mockTweets[199].id_str
                        });
                        expect(getTweetsSpy).toHaveBeenCalledWith({
                            user_id: '001',
                            since_id: '5001',
                            trim_user: true,
                            count: 200,
                            max_id: mockTweets[209].id_str
                        });
                    });
                });

                it('should return the correct tweets', () => {
                    const users = { '001': '5001' };
                    const mockTweets = tweetBuilder.generateRandomTweets(210);
                    getTweetsSpy
                        .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(0, 200)))
                        .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(199, 210)))
                        .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(209, 210)));

                    return retriever.retrieveTweets(users).then((tweets) => {
                        expect(tweets).toEqual([ mockTweets ]);
                    });
                });
            });
        });

        describe('New Users', () => {
            let retrieveForNewSpy, getTweetsSpy;

            beforeEach(() => {
                retrieveForNewSpy = jest.spyOn(retriever, 'retrieveForNew');
                getTweetsSpy = jest.spyOn(retriever.twitterHandler, 'getTweets');
            });

            afterEach(() => {
                retrieveForNewSpy.mockRestore();
                getTweetsSpy.mockRestore();
            });

            it('should specify the correct parameters for a retrieval', () => {
                const users = { '001': 0, '002': 0 };
                retrieveForNewSpy.mockImplementation(() => Promise.resolve({}));

                return retriever.retrieveTweets(users).then((tweets) => {
                    expect(tweets).toEqual([ {}, {} ]);
                    expect(retrieveForNewSpy).toHaveBeenCalledTimes(2);
                    expect(retrieveForNewSpy).toHaveBeenCalledWith({
                        user_id: '001',
                        trim_user: true
                    });
                    expect(retrieveForNewSpy).toHaveBeenCalledWith({
                        user_id: '002',
                        trim_user: true
                    });
                });
            });

            describe('when receivable tweets < 200', () => {
                describe('when tracked tweets > receivable tweets', () => {
                    it('should properly make Twitter API requests', () => {
                        const users = { '001': 0 };
                        const mockTweets = tweetBuilder.generateRandomTweets(5);
                        retriever.TWEETS_TO_TRACK = 500;
                        getTweetsSpy
                            .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(0, 5)))
                            .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(4, 5)));

                        return retriever.retrieveTweets(users).then(() => {
                            expect(getTweetsSpy).toHaveBeenCalledTimes(2);
                            expect(getTweetsSpy).toHaveBeenCalledWith({
                                user_id: '001',
                                trim_user: true,
                                count: 200
                            });
                            expect(getTweetsSpy).toHaveBeenCalledWith({
                                user_id: '001',
                                trim_user: true,
                                count: 200,
                                max_id: mockTweets[4].id_str
                            });
                        });
                    });

                    it('should return the correct tweets', () => {
                        const users = { '001': 0 };
                        const mockTweets = tweetBuilder.generateRandomTweets(5);
                        retriever.TWEETS_TO_TRACK = 500;
                        getTweetsSpy
                            .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(0, 5)))
                            .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(4, 5)));

                        return retriever.retrieveTweets(users).then((tweets) => {
                            expect(tweets).toEqual([ mockTweets ]);
                        });
                    });
                });
            });

            describe('when receivable tweets > 200', () => {
                describe('when tracked tweets > receivable tweets', () => {
                    it('should properly make Twitter API requests', () => {
                        const users = { '001': 0 };
                        const mockTweets = tweetBuilder.generateRandomTweets(210);
                        retriever.TWEETS_TO_TRACK = 500;
                        getTweetsSpy
                            .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(0, 200)))
                            .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(199, 210)))
                            .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(209, 210)));

                        return retriever.retrieveTweets(users).then(() => {
                            expect(getTweetsSpy).toHaveBeenCalledTimes(3);
                            expect(getTweetsSpy).toHaveBeenCalledWith({
                                user_id: '001',
                                trim_user: true,
                                count: 200
                            });
                            expect(getTweetsSpy).toHaveBeenCalledWith({
                                user_id: '001',
                                trim_user: true,
                                count: 200,
                                max_id: mockTweets[199].id_str
                            });
                            expect(getTweetsSpy).toHaveBeenCalledWith({
                                user_id: '001',
                                trim_user: true,
                                count: 200,
                                max_id: mockTweets[209].id_str
                            });
                        });
                    });

                    it('should return the correct tweets', () => {
                        const users = { '001': 0 };
                        const mockTweets = tweetBuilder.generateRandomTweets(210);
                        retriever.TWEETS_TO_TRACK = 500;
                        getTweetsSpy
                            .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(0, 200)))
                            .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(199, 210)))
                            .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(209, 210)));

                        return retriever.retrieveTweets(users).then((tweets) => {
                            expect(tweets).toEqual([ mockTweets ]);
                        });
                    });
                });
            });
        });
    });
});
<commit_msg>Add tests for tracked tweets < receivable tweets<commit_after>/*
 * NTwitBot - retrieve.test.js
 * Copyright (C) 2016-2017 Jordan Sne
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

const Retrieve  = require('../../lib/retrieve.js');
const Twitter   = require('../../lib/twitter.js');
const Util      = require('../../lib/util.js');
const tweetBuilder = require('../builders/tweetbuilder.js');

const utils = new Util();
const retriever = new Retrieve(new Twitter({}, utils), utils);

describe('Retrieve', () => {

    describe('Mention Retrievals', () => {
        const getMentionsSpy = jest.spyOn(retriever.twitterHandler, 'getMentions');

        afterEach(() => {
            getMentionsSpy.mockReset();
        });

        it('should retrieve all mentions of the user', () => {
            getMentionsSpy.mockImplementation(() => Promise.resolve({}));

            return retriever.retrieveMentions(0).then((mentions) => {
                expect(mentions).toBeDefined();
                expect(getMentionsSpy).toHaveBeenCalledWith({ count: 200 });
            });
        });

        it('should retrieve all mentions since a specified ID of the user', () => {
            getMentionsSpy.mockImplementation(() => Promise.resolve({}));

            return retriever.retrieveMentions('5001').then((mentions) => {
                expect(mentions).toBeDefined();
                expect(getMentionsSpy).toHaveBeenCalledWith({ since_id: '5001' });
            });
        });
    });

    describe('Tweet Retrievals', () => {
        describe('Existing Users', () => {
            let retrieveForExistingSpy, getTweetsSpy;

            beforeEach(() => {
                retrieveForExistingSpy = jest.spyOn(retriever, 'retrieveForExisting');
                getTweetsSpy = jest.spyOn(retriever.twitterHandler, 'getTweets');
            });

            afterEach(() => {
                retrieveForExistingSpy.mockRestore();
                getTweetsSpy.mockRestore();
            });

            it('should specify the correct parameters for a retrieval', () => {
                const users = { '001': '5001', '002': '5002' };
                retrieveForExistingSpy.mockImplementation(() => Promise.resolve({}));

                return retriever.retrieveTweets(users).then((tweets) => {
                    expect(tweets).toEqual([ {}, {} ]);
                    expect(retrieveForExistingSpy).toHaveBeenCalledTimes(2);
                    expect(retrieveForExistingSpy).toHaveBeenCalledWith({
                        user_id: '001',
                        since_id: '5001',
                        count: 200,
                        trim_user: true
                    });
                    expect(retrieveForExistingSpy).toHaveBeenCalledWith({
                        user_id: '002',
                        since_id: '5002',
                        count: 200,
                        trim_user: true
                    });
                });
            });

            describe('when receivable tweets < 200', () => {
                it('should properly make Twitter API requests', () => {
                    const users = { '001': '5001' };
                    const mockTweets = tweetBuilder.generateRandomTweets(5);
                    getTweetsSpy
                        .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(0, 5)))
                        .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(4, 5)));

                    return retriever.retrieveTweets(users).then(() => {
                        expect(getTweetsSpy).toHaveBeenCalledTimes(2);
                        expect(getTweetsSpy).toHaveBeenCalledWith({
                            user_id: '001',
                            since_id: '5001',
                            trim_user: true,
                            count: 200
                        });
                        expect(getTweetsSpy).toHaveBeenCalledWith({
                            user_id: '001',
                            since_id: '5001',
                            trim_user: true,
                            count: 200,
                            max_id: mockTweets[4].id_str
                        });
                    });
                });

                it('should return the correct tweets', () => {
                    const users = { '001': '5001' };
                    const mockTweets = tweetBuilder.generateRandomTweets(5);
                    getTweetsSpy
                        .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(0, 5)))
                        .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(4, 5)));

                    return retriever.retrieveTweets(users).then((tweets) => {
                        expect(tweets).toEqual([ mockTweets ]);
                    });
                });
            });

            describe('when receivable tweets > 200', () => {
                it('should properly make Twitter API requests', () => {
                    const users = { '001': '5001' };
                    const mockTweets = tweetBuilder.generateRandomTweets(220);
                    getTweetsSpy
                        .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(0, 200)))
                        .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(199, 210)))
                        .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(209, 210)));

                    return retriever.retrieveTweets(users).then(() => {
                        expect(getTweetsSpy).toHaveBeenCalledTimes(3);
                        expect(getTweetsSpy).toHaveBeenCalledWith({
                            user_id: '001',
                            since_id: '5001',
                            trim_user: true,
                            count: 200
                        });
                        expect(getTweetsSpy).toHaveBeenCalledWith({
                            user_id: '001',
                            since_id: '5001',
                            trim_user: true,
                            count: 200,
                            max_id: mockTweets[199].id_str
                        });
                        expect(getTweetsSpy).toHaveBeenCalledWith({
                            user_id: '001',
                            since_id: '5001',
                            trim_user: true,
                            count: 200,
                            max_id: mockTweets[209].id_str
                        });
                    });
                });

                it('should return the correct tweets', () => {
                    const users = { '001': '5001' };
                    const mockTweets = tweetBuilder.generateRandomTweets(210);
                    getTweetsSpy
                        .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(0, 200)))
                        .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(199, 210)))
                        .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(209, 210)));

                    return retriever.retrieveTweets(users).then((tweets) => {
                        expect(tweets).toEqual([ mockTweets ]);
                    });
                });
            });
        });

        describe('New Users', () => {
            let retrieveForNewSpy, getTweetsSpy;

            beforeEach(() => {
                retrieveForNewSpy = jest.spyOn(retriever, 'retrieveForNew');
                getTweetsSpy = jest.spyOn(retriever.twitterHandler, 'getTweets');
            });

            afterEach(() => {
                retrieveForNewSpy.mockRestore();
                getTweetsSpy.mockRestore();
            });

            it('should specify the correct parameters for a retrieval', () => {
                const users = { '001': 0, '002': 0 };
                retrieveForNewSpy.mockImplementation(() => Promise.resolve({}));

                return retriever.retrieveTweets(users).then((tweets) => {
                    expect(tweets).toEqual([ {}, {} ]);
                    expect(retrieveForNewSpy).toHaveBeenCalledTimes(2);
                    expect(retrieveForNewSpy).toHaveBeenCalledWith({
                        user_id: '001',
                        trim_user: true
                    });
                    expect(retrieveForNewSpy).toHaveBeenCalledWith({
                        user_id: '002',
                        trim_user: true
                    });
                });
            });

            describe('when receivable tweets < 200', () => {
                describe('when tracked tweets > receivable tweets', () => {
                    it('should properly make Twitter API requests', () => {
                        const users = { '001': 0 };
                        const mockTweets = tweetBuilder.generateRandomTweets(5);
                        retriever.TWEETS_TO_TRACK = 500;
                        getTweetsSpy
                            .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(0, 5)))
                            .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(4, 5)));

                        return retriever.retrieveTweets(users).then(() => {
                            expect(getTweetsSpy).toHaveBeenCalledTimes(2);
                            expect(getTweetsSpy).toHaveBeenCalledWith({
                                user_id: '001',
                                trim_user: true,
                                count: 200
                            });
                            expect(getTweetsSpy).toHaveBeenCalledWith({
                                user_id: '001',
                                trim_user: true,
                                count: 200,
                                max_id: mockTweets[4].id_str
                            });
                        });
                    });

                    it('should return the correct tweets', () => {
                        const users = { '001': 0 };
                        const mockTweets = tweetBuilder.generateRandomTweets(5);
                        retriever.TWEETS_TO_TRACK = 500;
                        getTweetsSpy
                            .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(0, 5)))
                            .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(4, 5)));

                        return retriever.retrieveTweets(users).then((tweets) => {
                            expect(tweets).toEqual([ mockTweets ]);
                        });
                    });
                });

                describe('when tracked tweets < receivable tweets', () => {
                    it('should properly make Twitter API requests', () => {
                        const users = { '001': 0 };
                        const mockTweets = tweetBuilder.generateRandomTweets(10);
                        retriever.TWEETS_TO_TRACK = 5;
                        getTweetsSpy
                            .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(0, 10)));

                        return retriever.retrieveTweets(users).then(() => {
                            expect(getTweetsSpy).toHaveBeenCalledTimes(1);
                            expect(getTweetsSpy).toHaveBeenCalledWith({
                                user_id: '001',
                                trim_user: true,
                                count: 200
                            });
                        });
                    });

                    it('should return the correct tweets', () => {
                        const users = { '001': 0 };
                        const mockTweets = tweetBuilder.generateRandomTweets(10);
                        retriever.TWEETS_TO_TRACK = 5;
                        getTweetsSpy
                            .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(0, 10)));

                        return retriever.retrieveTweets(users).then((tweets) => {
                            expect(tweets).toEqual([ mockTweets.slice(0, 5) ]);
                        });
                    });
                });
            });

            describe('when receivable tweets > 200', () => {
                describe('when tracked tweets > receivable tweets', () => {
                    it('should properly make Twitter API requests', () => {
                        const users = { '001': 0 };
                        const mockTweets = tweetBuilder.generateRandomTweets(210);
                        retriever.TWEETS_TO_TRACK = 500;
                        getTweetsSpy
                            .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(0, 200)))
                            .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(199, 210)))
                            .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(209, 210)));

                        return retriever.retrieveTweets(users).then(() => {
                            expect(getTweetsSpy).toHaveBeenCalledTimes(3);
                            expect(getTweetsSpy).toHaveBeenCalledWith({
                                user_id: '001',
                                trim_user: true,
                                count: 200
                            });
                            expect(getTweetsSpy).toHaveBeenCalledWith({
                                user_id: '001',
                                trim_user: true,
                                count: 200,
                                max_id: mockTweets[199].id_str
                            });
                            expect(getTweetsSpy).toHaveBeenCalledWith({
                                user_id: '001',
                                trim_user: true,
                                count: 200,
                                max_id: mockTweets[209].id_str
                            });
                        });
                    });

                    it('should return the correct tweets', () => {
                        const users = { '001': 0 };
                        const mockTweets = tweetBuilder.generateRandomTweets(210);
                        retriever.TWEETS_TO_TRACK = 500;
                        getTweetsSpy
                            .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(0, 200)))
                            .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(199, 210)))
                            .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(209, 210)));

                        return retriever.retrieveTweets(users).then((tweets) => {
                            expect(tweets).toEqual([ mockTweets ]);
                        });
                    });
                });

                describe('when tracked tweets < receivable tweets', () => {
                    it('should properly make Twitter API requests', () => {
                        const users = { '001': 0 };
                        const mockTweets = tweetBuilder.generateRandomTweets(220);
                        retriever.TWEETS_TO_TRACK = 210;
                        getTweetsSpy
                            .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(0, 200)))
                            .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(199, 220)));

                        return retriever.retrieveTweets(users).then(() => {
                            expect(getTweetsSpy).toHaveBeenCalledTimes(2);
                            expect(getTweetsSpy).toHaveBeenCalledWith({
                                user_id: '001',
                                trim_user: true,
                                count: 200
                            });
                            expect(getTweetsSpy).toHaveBeenCalledWith({
                                user_id: '001',
                                trim_user: true,
                                count: 200,
                                max_id: mockTweets[199].id_str
                            });
                        });
                    });

                    it('should return the correct tweets', () => {
                        const users = { '001': 0 };
                        const mockTweets = tweetBuilder.generateRandomTweets(220);
                        retriever.TWEETS_TO_TRACK = 210;
                        getTweetsSpy
                            .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(0, 200)))
                            .mockImplementationOnce(() => Promise.resolve(mockTweets.slice(199, 220)));

                        return retriever.retrieveTweets(users).then((tweets) => {
                            expect(tweets).toEqual([ mockTweets.slice(0, 210)] );
                        });
                    });
                });
            });
        });
    });
});
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import OutsideClickHandler from 'react-outside-click-handler';
import styled from 'styled-components';
import { position, top, right, bottom, left } from 'styled-system';

import { preset } from 'react/styles/functions';

import compactObject from 'react/util/compactObject';

const Background = styled.div`
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: ${x => x.theme.z.modal};
  pointer-events: none;
`;

const Wrapper = styled.div`
  ${preset(position, { position: 'absolute' })}
  ${top}
  ${right}
  ${bottom}
  ${left}
  pointer-events: all;
`;

export default class Overlay extends Component {
  static propTypes = {
    children: PropTypes.node.isRequired,
    onClose: PropTypes.func.isRequired,
    targetEl: PropTypes.func.isRequired,
    anchorY: PropTypes.oneOf(['top', 'bottom']),
    anchorX: PropTypes.oneOf(['left', 'right']),
    alignToY: PropTypes.oneOf(['top', 'bottom']),
    alignToX: PropTypes.oneOf(['left', 'right']),
    offsetX: PropTypes.number,
    offsetY: PropTypes.number,
  }

  static defaultProps = {
    anchorY: 'top',
    anchorX: 'left',
    alignToY: 'bottom',
    alignToX: 'left',
    offsetX: 0,
    offsetY: 0,
  }

  constructor(props) {
    super(props);

    this.el = document.createElement('div');
  }

  state = {
    top: null,
    right: null,
    bottom: null,
    left: null,
  }

  componentDidMount() {
    document.body.appendChild(this.el);

    this.alignToEl(this.props.targetEl());
  }

  componentWillUnmount() {
    this.el.parentNode.removeChild(this.el);
  }

  alignToEl = (el) => {
    const {
      anchorY, anchorX, alignToY, alignToX, offsetY, offsetX,
    } = this.props;

    const { [alignToY]: y, [alignToX]: x } = el.getBoundingClientRect();

    const positions = {
      top: y,
      bottom: window.innerHeight - y,
      left: x,
      right: window.innerWidth - x,
    };

    const theState = {
      [anchorY]: positions[anchorY] + offsetY,
      [anchorX]: positions[anchorX] + offsetX,
    };

    this.setState(theState);
  }

  render() {
    const { children, onClose, ...rest } = this.props;

    return ReactDOM.createPortal(
      (
        <Background>
          <Wrapper {...compactObject(this.state)} {...rest}>
            <OutsideClickHandler onOutsideClick={onClose}>
              {children}
            </OutsideClickHandler>
          </Wrapper>
        </Background>
      ), this.el,
    );
  }
}
<commit_msg>Allows for matching width of targetEl; updates position on scroll/resize events<commit_after>import React, { PureComponent } from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import OutsideClickHandler from 'react-outside-click-handler';
import styled from 'styled-components';
import { position, top, right, bottom, left, width } from 'styled-system';
import { debounce } from 'underscore';

import { preset } from 'react/styles/functions';

import compactObject from 'react/util/compactObject';

const Background = styled.div`
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: ${x => x.theme.z.modal};
  pointer-events: none;
`;

const Wrapper = styled.div`
  ${preset(position, { position: 'absolute' })}
  ${top}
  ${right}
  ${bottom}
  ${left}
  ${width}
  pointer-events: all;
`;

export default class Overlay extends PureComponent {
  static propTypes = {
    children: PropTypes.node.isRequired,
    onClose: PropTypes.func.isRequired,
    targetEl: PropTypes.func.isRequired,
    anchorY: PropTypes.oneOf(['top', 'bottom']),
    anchorX: PropTypes.oneOf(['left', 'right']),
    alignToY: PropTypes.oneOf(['top', 'bottom']),
    alignToX: PropTypes.oneOf(['left', 'right']),
    offsetX: PropTypes.number,
    offsetY: PropTypes.number,
    fullWidth: PropTypes.bool,
  }

  static defaultProps = {
    anchorY: 'top',
    anchorX: 'left',
    alignToY: 'bottom',
    alignToX: 'left',
    offsetX: 0,
    offsetY: 0,
    fullWidth: false,
  }

  constructor(props) {
    super(props);

    this.el = document.createElement('div');
  }

  state = {
    top: null,
    right: null,
    bottom: null,
    left: null,
  }

  componentDidMount() {
    document.body.appendChild(this.el);

    this.positionOverlay = () => this.alignToEl(this.props.targetEl());
    this.debouncedPositionOverlay = debounce(this.positionOverlay, 250);

    window.addEventListener('resize', this.debouncedPositionOverlay);
    document.body.addEventListener('mousewheel', this.debouncedPositionOverlay);

    this.positionOverlay();
  }

  componentWillUnmount() {
    this.el.parentNode.removeChild(this.el);
    window.removeEventListener('resize', this.debouncedPositionOverlay);
    document.body.removeEventListener('mousewheel', this.debouncedPositionOverlay);
  }

  alignToEl = (el) => {
    const {
      anchorY, anchorX, alignToY, alignToX, offsetY, offsetX, fullWidth,
    } = this.props;

    const { [alignToY]: y, [alignToX]: x, width: elWidth } = el.getBoundingClientRect();

    const positions = {
      top: y,
      bottom: window.innerHeight - y,
      left: x,
      right: window.innerWidth - x,
    };

    const theState = {
      [anchorY]: positions[anchorY] + offsetY,
      [anchorX]: positions[anchorX] + offsetX,
    };

    if (fullWidth) {
      theState.width = elWidth;
    }

    this.setState(theState);
  }

  render() {
    const { children, onClose, ...rest } = this.props;

    return ReactDOM.createPortal(
      (
        <Background>
          <Wrapper {...compactObject(this.state)} {...rest}>
            <OutsideClickHandler onOutsideClick={onClose}>
              {children}
            </OutsideClickHandler>
          </Wrapper>
        </Background>
      ), this.el,
    );
  }
}
<|endoftext|>