<commit_before>/**
 * Bindings to Kanso events
 */

var duality_events = require('duality/events'),
    dutils = require('duality/utils'),
    querystring = require('querystring'),
    templates = require('duality/templates'),
    session = require('session'),
    cookies = require('cookies'),
    users = require('users'),
    moment = require('moment'),
    settings = require('settings/root'),
    _ = require('underscore'),
    shows = require('./shows'),
    data_records = require('./data_records'),
    appinfo = require('lib/appinfo'),
    //    objectpath = require('views/lib/objectpath'),
    utils = require('kujua-utils'),
    sms_utils = require('./utils'),
    url = require('url'),
    app_settings = {};

var initDropdown = function() {
    if ($('.dropdown-toggle').dropdown) {
        $('.dropdown-toggle').dropdown();
    }
};

// wrap code spans with overflow auto. typically called after docsLoaded event
// is triggered.
var wrapCodeBlocks = function() {
    $('#docs-body code').each(function(idx, el) {
        var limit = 860,
            _el = $(this),
            width = _el.width();
        if (_el.hasClass('shorten')) {
            _el.wrap($('
').addClass('scroll-short'));
        } else if (width > limit) {
            _el.wrap($('
').addClass('scroll'));
        }
    });
};

exports.addHelpers = function() {
    // add helpers
    templates.addHelpers({
        translate: function(chunk, context, bodies, params) {
            var value = this.tap(params.value, chunk, context);

            return chunk.write($.kansotranslate(value));
        },
        formatDate: function(chunk, context, bodies, params) {
            var timestamp = Number(this.tap(params.timestamp, chunk, context)),
                format = this.tap(params.format, chunk, context);

            if (_.isNaN(timestamp)) {
                timestamp = this.tap(params.timestamp, chunk, context);
            }

            // todo use data_format setting if format is not passed in
            format = format || 'DD, MMM YYYY, HH:mm:ss ZZ';

            return chunk.write(moment(timestamp).format(format));
        },
        formName: function(chunk, context, bodies, params) {
            var form = this.tap(params.form, chunk, context);

            return chunk.write(sms_utils.getFormTitle(form));
        },
        contact: function(chunk, context, bodies, params) {
            var entities = this.tapObject(params.entities, chunk, context),
                from = this.tap(params.from, chunk, context),
                to = this.tap(params.to, chunk, context),
                contact,
                clinic;

            if (entities) {

                contact = objectpath.get(
                    entities,
                    app_settings.contact_display_short
                );

                if (!contact) {
                    contact = entities.clinic && entities.clinic.name;
                }
            }

            if (!contact) {
                contact = from;
            }
            if (!contact) {
                contact = to;
            }
            if (!contact) {
                contact = '';
            }

            return chunk.write(contact);
        },
        tasksByState: function(chunk, context, bodies, params) {
            var array = this.tapArray(params.array, chunk, context),
                state = this.tap(params.state, chunk, context),
                matches;

            matches = _.filter(array, function(item) {
                return item.state === state;
            });

            return bodies.block(chunk, context.push(matches));
        },
        ifHasState: function(chunk, context, bodies, params) {
            var array = this.tapArray(params.array, chunk, context),
                state = this.tap(params.state, chunk, context),
                body = bodies.block,
                skip = bodies['else'],
                cond;

            cond = _.find(array, function(item) {
                return item && item.state === state;
            });

            if (cond) {
                return chunk.render(bodies.block, context);
            } else if (skip) {
                return chunk.render(bodies['else'], context);
            } else {
                return chunk;
            }
        },
        countByState: function(chunk, context, bodies, params) {
            var array1 = this.tapArray(params.array1, chunk, context),
                state = this.tap(params.state, chunk, context),
                matches,
                array = [];

            if (params.array2) {
                array1 = array1.concat(
                    this.tapArray(params.array2, chunk, context)
                );
            }

            matches = _.filter(array1, function(item) {
                return item && item.state === state;
            });

            return chunk.write(matches.length);
        },
        isAdmin: function(chunk, context, bodies, params) {
            var body = bodies.block,
                skip = bodies['else'];

            if (data_records.isAdmin) {
                return chunk.render(bodies.block, context);
            } else if (skip) {
                return chunk.render(skip, context);
            } else {
                return chunk;
            }
        },
        hasPermission: function(chunk, context, bodies, params) {
            var body = bodies.block,
                skip = bodies['else'],
                permission = this.tap(params.permission, chunk, context);

            if (utils.hasPerm(data_records.userCtx, permission)) {
                return chunk.render(bodies.block, context);
            } else if (skip) {
                return chunk.render(skip, context);
            } else {
                return chunk;
            }
        },
        idx: function(chunk, context, bodies) {
            if (bodies.block) {
                return bodies.block(chunk, context.push(context.stack.index));
            } else {
                return chunk;
            }
        },
        if : function(chunk, context, bodies, params) {
            var body = bodies.block,
                skip = bodies['else'];

            if (params && params.cond) {
                var cond = params.cond;

                cond = this.tap(cond, chunk, context);
                // eval expressions with given dust references
                if (eval(cond)) {
                    if (body) {
                        return chunk.render(bodies.block, context);
                    } else {
                        _console.log("Missing body block in the if helper!");
                        return chunk;
                    }
                }
                if (skip) {
                    return chunk.render(bodies['else'], context);
                }
            }
            // no condition
            else {
                _console.log("No condition given in the if helper!");
            }
            return chunk;
        }
    });

};

/**
 * The init method fires when the app is initially loaded from a page rendered
 * by CouchDB.  These should only be executed once when the app loads.
 */
duality_events.on('init', function() {

    try {
        app_settings = appinfo.getAppInfo.call(this);
    } catch (e) {
        shows.render500('Failed to retrieve settings.');
        console.error('Failed to retrieve settings.');
        throw e;
    }

    exports.addHelpers();

    // render top nav labels
    $('#topnav .nav .patients a').append(' ' + $.kansotranslate('Patients'));
    $('#topnav .nav .visits a').append(' ' + $.kansotranslate('Visits'));
    $('#topnav .nav .reports a').append(' ' + $.kansotranslate('Reports'));
    $('#topnav .nav .reports_calculated a').append(' ' + $.kansotranslate('Reports Calculated'));
    //    $('#topnav .nav .sms-forms-data a').append(' ' + $.kansotranslate('Export'));
    $('#topnav .nav .facilities a').append(' ' + $.kansotranslate('Facilities'));
    $('#topnav .nav .help a').append(' ' + $.kansotranslate('Help'));

    // Set version on all pages
    $('.version').text(settings.version);

    // Dynamic year for footer copyright
    $("#year").text(new Date().getFullYear());

    // patch dropdown to fire an event
    $.fn.dropdown.Constructor.prototype.toggle = _.wrap($.fn.dropdown.Constructor.prototype.toggle, function(fn, e) {
        fn.call(this, e);
        $(this).trigger('toggle');
    });

    // hack to bind to dynamic elements
    $(document).on('mouseenter', initDropdown);

    // add handler to docsPageLoader event for #supportedforms + p elements
    $(document).on('docsPageLoaded', wrapCodeBlocks);

    $(document).on('click', '.spreadsheet-help .icon-question-sign', function(ev) {
        var el = $(ev.target);
        el.siblings('ul').toggle();
    });

    // our version of bootstrap does not clear error on textareas
    $(document).on('focus', 'textarea', function(ev) {
        $(ev.target).closest('.control-group').removeClass('error');
    });

    $(document).on('click', '.controls .edit-mode .btn', data_records.handleUpdateDropdown);
    $(document).on('click', '.add-message button, .add-message a', data_records.handleSendMessage);

});

/**
 * The sessionChange event fires when the app is first loaded and the user's
 * session information becomes available. It is also fired whenever a change
 * to the user's session is detected, for example after logging in or out.
 */

// stores a reference to the modal dialog
var m;

session.on('change', function(userCtx) {

    try {
        app_settings = appinfo.getAppInfo.call(this);
    } catch (e) {
        shows.render500('Failed to retrieve settings.');
        console.error('Failed to retrieve settings.');
        throw e;
    }
    exports.addHelpers();

    var isAdmin = utils.isUserAdmin(userCtx);

    _.extend(data_records, {
        isAdmin: isAdmin,
        userCtx: userCtx
    });

    if (!$('#session_menu').length) {
        $('#topnav .pull-right').append(
            '

'
        );
    }
    var el;
    if (userCtx.name) {
        el = $(
            '
' +
            '' +
            ' ' + userCtx.name + ' ' +
            '' +
            '' +
            '
' +
            '
Logout
' +
            '
' +
            '
'
        );
        $('.dropdown-toggle', el).click(data_records.handleUpdateDropdown);
        $('.logout', el).click(function(ev) {
            ev.preventDefault();
            session.logout(function(err, resp) {
                location.href = dutils.getBaseURL();
            });
            return false;
        });
    } else {
        el = $(
            '
' +
            'Login' +
            '
'
        );

        if (m) {
            // clear previous modal dialog
            m.modal('hide');
            m.data('modal', null);
            m.remove();
        }
        m = $(templates.render("login_modal.html", {
            userCtx: userCtx
        }, {}));

        var submitHandler = function(ev) {
            ev.preventDefault();

            var username = $('#id_username', m).val();
            var password = $('#id_password', m).val();

            $('.alert', m).remove();
            $('.help-inline', m).remove();
            $('.control-group', m).removeClass('error');
            $('.controls', m).show(); // sometimes these get hidden

            var username_cg = $('#id_username').parents('.control-group');
            var password_cg = $('#id_password').parents('.control-group');
            var errors = false;

            if (!username) {
                username_cg.addClass('error');
                $('#id_username').attr("placeholder", "Username Required");
								$('#id_username').parent().addClass("has-error");
                errors = true;
            }
            if (!password) {
                password_cg.addClass('error');
                $('#id_password').attr("placeholder", "Password Required");
								$('#id_password').parent().addClass("has-error");
                errors = true;
            }
            if (errors) {
                return false;
            }

            session.login(username, password, function(err) {
                if (err) {
                    var msg = err.toString();
                    $('form', m).after(
                        '
' + msg + '
'
                    );
                } else {
                    m.modal('hide');
                    location.href = dutils.getBaseURL();
                }
            });
            return false;
        };

        // this is broken for some reason, I suspect the bootstrap-modal
        // plugin is doing preventDefault on events inside the modal
        $('form', m).submit(submitHandler);

        // fake form submit event
        $('input', m).keyup(function(ev) {
            if (ev.keyCode === 13) {
                return submitHandler.apply(this, arguments);
            }
        });

        $('.btn-primary', m).click(submitHandler);
        $('.btn-close', m).click(function() {
            m.modal('hide');
        });
        $('.btn-cancel', m).click(function() {
            m.modal('hide');
        });

        $('.login', el).click(function(ev) {
            ev.preventDefault();
            m.modal('show');
            $('#id_username').focus();
            return false;
        });
    }
    // $('#session_menu').replaceWith(el);

    if (utils.isDbAdmin(userCtx)) {
        $('.dropdown-menu', el).append(
            '
Manage Users
'
        );
    }
    $('#session_menu').replaceWith(el);

    // hide the nav items from non-admin users
    if (_.difference(['district_admin', 'national_admin', '_admin'], userCtx.roles).length === 3) {
        $('.navbar .nav li').hide();
        $('.navbar .nav .docs').show();
    } else {
        $('.navbar .nav li').show();
    }
    $('#topnav .navbar-right').append(el);
});

/**
 * The updateFailure event fires when an update function returns a document as
 * the first part of an array, but the client-side request to update the
 * document fails.
 */

duality_events.on('updateFailure', function(err, info, req, res, doc) {
    alert(err.message || err.toString());
});<commit_msg>Fixed login modal getting the focus<commit_after>/**
 * Bindings to Kanso events
 */

var duality_events = require('duality/events'),
    dutils = require('duality/utils'),
    querystring = require('querystring'),
    templates = require('duality/templates'),
    session = require('session'),
    cookies = require('cookies'),
    users = require('users'),
    moment = require('moment'),
    settings = require('settings/root'),
    _ = require('underscore'),
    shows = require('./shows'),
    data_records = require('./data_records'),
    appinfo = require('lib/appinfo'),
    //    objectpath = require('views/lib/objectpath'),
    utils = require('kujua-utils'),
    sms_utils = require('./utils'),
    url = require('url'),
    app_settings = {};

/*var initDropdown = function() {
    if ($('.dropdown-toggle').dropdown) {
        $('.dropdown-toggle').dropdown();
    }
};*/

// wrap code spans with overflow auto. typically called after docsLoaded event
// is triggered.
var wrapCodeBlocks = function() {
    $('#docs-body code').each(function(idx, el) {
        var limit = 860,
            _el = $(this),
            width = _el.width();
        if (_el.hasClass('shorten')) {
            _el.wrap($('
').addClass('scroll-short'));
        } else if (width > limit) {
            _el.wrap($('
').addClass('scroll'));
        }
    });
};

exports.addHelpers = function() {
    // add helpers
    templates.addHelpers({
        translate: function(chunk, context, bodies, params) {
            var value = this.tap(params.value, chunk, context);

            return chunk.write($.kansotranslate(value));
        },
        formatDate: function(chunk, context, bodies, params) {
            var timestamp = Number(this.tap(params.timestamp, chunk, context)),
                format = this.tap(params.format, chunk, context);

            if (_.isNaN(timestamp)) {
                timestamp = this.tap(params.timestamp, chunk, context);
            }

            // todo use data_format setting if format is not passed in
            format = format || 'DD, MMM YYYY, HH:mm:ss ZZ';

            return chunk.write(moment(timestamp).format(format));
        },
        formName: function(chunk, context, bodies, params) {
            var form = this.tap(params.form, chunk, context);

            return chunk.write(sms_utils.getFormTitle(form));
        },
        contact: function(chunk, context, bodies, params) {
            var entities = this.tapObject(params.entities, chunk, context),
                from = this.tap(params.from, chunk, context),
                to = this.tap(params.to, chunk, context),
                contact,
                clinic;

            if (entities) {

                contact = objectpath.get(
                    entities,
                    app_settings.contact_display_short
                );

                if (!contact) {
                    contact = entities.clinic && entities.clinic.name;
                }
            }

            if (!contact) {
                contact = from;
            }
            if (!contact) {
                contact = to;
            }
            if (!contact) {
                contact = '';
            }

            return chunk.write(contact);
        },
        tasksByState: function(chunk, context, bodies, params) {
            var array = this.tapArray(params.array, chunk, context),
                state = this.tap(params.state, chunk, context),
                matches;

            matches = _.filter(array, function(item) {
                return item.state === state;
            });

            return bodies.block(chunk, context.push(matches));
        },
        ifHasState: function(chunk, context, bodies, params) {
            var array = this.tapArray(params.array, chunk, context),
                state = this.tap(params.state, chunk, context),
                body = bodies.block,
                skip = bodies['else'],
                cond;

            cond = _.find(array, function(item) {
                return item && item.state === state;
            });

            if (cond) {
                return chunk.render(bodies.block, context);
            } else if (skip) {
                return chunk.render(bodies['else'], context);
            } else {
                return chunk;
            }
        },
        countByState: function(chunk, context, bodies, params) {
            var array1 = this.tapArray(params.array1, chunk, context),
                state = this.tap(params.state, chunk, context),
                matches,
                array = [];

            if (params.array2) {
                array1 = array1.concat(
                    this.tapArray(params.array2, chunk, context)
                );
            }

            matches = _.filter(array1, function(item) {
                return item && item.state === state;
            });

            return chunk.write(matches.length);
        },
        isAdmin: function(chunk, context, bodies, params) {
            var body = bodies.block,
                skip = bodies['else'];

            if (data_records.isAdmin) {
                return chunk.render(bodies.block, context);
            } else if (skip) {
                return chunk.render(skip, context);
            } else {
                return chunk;
            }
        },
        hasPermission: function(chunk, context, bodies, params) {
            var body = bodies.block,
                skip = bodies['else'],
                permission = this.tap(params.permission, chunk, context);

            if (utils.hasPerm(data_records.userCtx, permission)) {
                return chunk.render(bodies.block, context);
            } else if (skip) {
                return chunk.render(skip, context);
            } else {
                return chunk;
            }
        },
        idx: function(chunk, context, bodies) {
            if (bodies.block) {
                return bodies.block(chunk, context.push(context.stack.index));
            } else {
                return chunk;
            }
        },
        if : function(chunk, context, bodies, params) {
            var body = bodies.block,
                skip = bodies['else'];

            if (params && params.cond) {
                var cond = params.cond;

                cond = this.tap(cond, chunk, context);
                // eval expressions with given dust references
                if (eval(cond)) {
                    if (body) {
                        return chunk.render(bodies.block, context);
                    } else {
                        _console.log("Missing body block in the if helper!");
                        return chunk;
                    }
                }
                if (skip) {
                    return chunk.render(bodies['else'], context);
                }
            }
            // no condition
            else {
                _console.log("No condition given in the if helper!");
            }
            return chunk;
        }
    });

};

/**
 * The init method fires when the app is initially loaded from a page rendered
 * by CouchDB.  These should only be executed once when the app loads.
 */
duality_events.on('init', function() {

    try {
        app_settings = appinfo.getAppInfo.call(this);
    } catch (e) {
        shows.render500('Failed to retrieve settings.');
        console.error('Failed to retrieve settings.');
        throw e;
    }

    exports.addHelpers();

    // render top nav labels
    $('#topnav .nav .patients a').append(' ' + $.kansotranslate('Patients'));
    $('#topnav .nav .visits a').append(' ' + $.kansotranslate('Visits'));
    $('#topnav .nav .reports a').append(' ' + $.kansotranslate('Reports'));
    $('#topnav .nav .reports_calculated a').append(' ' + $.kansotranslate('Reports Calculated'));
    //    $('#topnav .nav .sms-forms-data a').append(' ' + $.kansotranslate('Export'));
    $('#topnav .nav .facilities a').append(' ' + $.kansotranslate('Facilities'));
    $('#topnav .nav .help a').append(' ' + $.kansotranslate('Help'));

    // Set version on all pages
    $('.version').text(settings.version);

    // Dynamic year for footer copyright
    $("#year").text(new Date().getFullYear());

    // add handler to docsPageLoader event for #supportedforms + p elements
    $(document).on('docsPageLoaded', wrapCodeBlocks);

    $(document).on('click', '.spreadsheet-help .icon-question-sign', function(ev) {
        var el = $(ev.target);
        el.siblings('ul').toggle();
    });

    // our version of bootstrap does not clear error on textareas
    $(document).on('focus', 'textarea', function(ev) {
        $(ev.target).closest('.control-group').removeClass('error');
    });

    $(document).on('click', '.controls .edit-mode .btn', data_records.handleUpdateDropdown);
    $(document).on('click', '.add-message button, .add-message a', data_records.handleSendMessage);

});

/**
 * The sessionChange event fires when the app is first loaded and the user's
 * session information becomes available. It is also fired whenever a change
 * to the user's session is detected, for example after logging in or out.
 */

// stores a reference to the modal dialog
var m;

session.on('change', function(userCtx) {

    try {
        app_settings = appinfo.getAppInfo.call(this);
    } catch (e) {
        shows.render500('Failed to retrieve settings.');
        console.error('Failed to retrieve settings.');
        throw e;
    }
    exports.addHelpers();

    var isAdmin = utils.isUserAdmin(userCtx);

    _.extend(data_records, {
        isAdmin: isAdmin,
        userCtx: userCtx
    });

    if (!$('#session_menu').length) {
        $('#topnav .pull-right').append(
            '

'
        );
    }
    var el;
    if (userCtx.name) {
        el = $(
            '
' +
            '' +
            ' ' + userCtx.name + ' ' +
            '' +
            '' +
            '
' +
            '
Logout
' +
            '
' +
            '
'
        );
        //$('.dropdown-toggle', el).click(data_records.handleUpdateDropdown);
        $('.logout', el).click(function(ev) {
            ev.preventDefault();
            session.logout(function(err, resp) {
                location.href = dutils.getBaseURL();
            });
            return false;
        });
    } else {
        el = $(
            '
' +
            'Login' +
            '
'
        );

        if (m) {
            // clear previous modal dialog
            m.modal('hide');
            m.data('modal', null);
            m.remove();
        }
        m = $(templates.render("login_modal.html", {
            userCtx: userCtx
        }, {}));

        var submitHandler = function(ev) {
            ev.preventDefault();

            var username = $('#id_username', m).val();
            var password = $('#id_password', m).val();

            $('.alert', m).remove();
            $('.help-inline', m).remove();
            $('.control-group', m).removeClass('error');
            $('.controls', m).show(); // sometimes these get hidden

            var username_cg = $('#id_username').parents('.control-group');
            var password_cg = $('#id_password').parents('.control-group');
            var errors = false;

            if (!username) {
                username_cg.addClass('error');
                $('#id_username').attr("placeholder", "Username Required");
								$('#id_username').parent().addClass("has-error");
                errors = true;
            }
            if (!password) {
                password_cg.addClass('error');
                $('#id_password').attr("placeholder", "Password Required");
								$('#id_password').parent().addClass("has-error");
                errors = true;
            }
            if (errors) {
                return false;
            }

            session.login(username, password, function(err) {
                if (err) {
                    var msg = err.toString();
                    $('form', m).after(
                        '
' + msg + '
'
                    );
                } else {
                    m.modal('hide');
                    location.href = dutils.getBaseURL();
                }
            });
            return false;
        };

        $('form', m).submit(submitHandler);

        // fake form submit event
        $('input', m).keyup(function(ev) {
            if (ev.keyCode === 13) {
                return submitHandler.apply(this, arguments);
            }
        });

        $('.btn-primary', m).click(submitHandler);
        $('.btn-close', m).click(function() {
            m.modal('hide');
        });
        $('.btn-cancel', m).click(function() {
            m.modal('hide');
        });

        $('.login', el).click(function(ev) {
            ev.preventDefault();
            m.modal('show');
            return false;
        });

				m.on('shown.bs.modal', function() {
					$('#id_username').focus();
				})
    }
    // $('#session_menu').replaceWith(el);

    if (utils.isDbAdmin(userCtx)) {
        $('.dropdown-menu', el).append(
            '
Manage Users
'
        );
    }
    $('#session_menu').replaceWith(el);

    // hide the nav items from non-admin users
    if (_.difference(['district_admin', 'national_admin', '_admin'], userCtx.roles).length === 3) {
        $('.navbar .nav li').hide();
        $('.navbar .nav .docs').show();
    } else {
        $('.navbar .nav li').show();
    }
    $('#topnav .navbar-right').append(el);
});

/**
 * The updateFailure event fires when an update function returns a document as
 * the first part of an array, but the client-side request to update the
 * document fails.
 */

duality_events.on('updateFailure', function(err, info, req, res, doc) {
    alert(err.message || err.toString());
});<|endoftext|>


<commit_before>function filterF(i, el) {
  var pattern = /(From|To|Sent|Subject|Cc|Date):/i;
  return el.textContent.match(pattern);
}

// convert From...To... blocks into one-liners
var matches = $(document).find("*").filter(filterF).get().reverse();

while (matches.length > 0) {
  var parent = $(matches[0]).parent();
  var localMatches = parent.find("*").filter(filterF);

  // insert breakpoint after the last element of localMatches
  $("

").insertAfter(localMatches[localMatches.length-1]);
  var breakpoint = $("#breakpoint");
  // save all text content of the block
  var textContent = $(localMatches[0]).text();
  $(localMatches[0]).nextUntil(breakpoint).each(function(i, el) {
    textContent += $(el).text();
    $(el).remove();
  });
  $(localMatches[0]).remove();

  console.log(textContent);
  // extract relevant info from the text
  var from = textContent.match(/From:(.*)\n/i)[1].trim();
  var date = textContent.match(/Date:(.*)\n/i)[1].trim();
  var output = "
On " + date + ", " + from + " wrote:\n
";

  $(output).insertAfter(breakpoint);
  breakpoint.remove();

  break;

  matches = $(document).find("*").filter(filterF).get().reverse();
}

// remove blockquotes but preserve contents
$($("blockquote").get().reverse()).each(function(i, el) {
  var contents = $(el).contents();
  contents.insertAfter($(el));
  $(el).remove();
});
<commit_msg>Refactor and clean up<commit_after>function fromToBlocksIntoOneLiners(topSearchElement) {
  var filterF = function(i, el) {
    var pattern = /(From|To|Sent|Subject|Cc|Date):/i;
    return el.textContent.match(pattern);
  };

  var matches = topSearchElement.find("*").filter(filterF).get().reverse();

  while (matches.length > 0) {
    var parent = $(matches[0]).parent();
    var localMatches = parent.find("*").filter(filterF);

    // insert breakpoint after the last element of localMatches
    var first = $(localMatches[0]);
    var last = $(localMatches[localMatches.length-1]);
    $("

").insertAfter(last);
    var breakpoint = $("#breakpoint");

    // preserve all text content of the block
    var textContent = first.text();
    first.nextUntil(breakpoint).each(function(i, el) {
      textContent += $(el).text();
      $(el).remove();
    });
    first.remove();

    console.log(textContent);
    // extract relevant info from the text
    var from = textContent.match(/From:(.*)\n/i)[1].trim();
    var date = textContent.match(/Date:(.*)\n/i)[1].trim();
    var output = "
On " + date + ", " + from + " wrote:\n
";

    $(output).insertAfter(breakpoint);
    breakpoint.remove();

    // update matches array
    matches = topSearchElement.find("*").filter(filterF).get().reverse();
  }
}

function removeBlockquotes(blockquoteElement) {
  $(blockquoteElement.get().reverse()).each(function(i, el) {
    var contents = $(el).contents();
    contents.insertAfter($(el));
    $(el).remove();
  });
}

// convert From...To... blocks into one-liners
fromToBlocksIntoOneLiners($("blockquote"));

// remove blockquotes but preserve contents
removeBlockquotes($("blockquote"));
<|endoftext|>


<commit_before>var api = require("./api");
var util = require("./util");
var time = require("./time");

var eq = require("./evqueue");
var CONST = require("./constants");

var _ = require("underscore");
var async = require("async");

/*
 * built-in event emitter for own events.
 */
var EventEmitter = require("events").EventEmitter,
	emitter = new EventEmitter();

var push_providers = {

	web:{
			module:require("./localpush"),
		  	is_batch:false
		}

};

/*
 * Add a push provider.
 */
exports.add_push_provider = function( provider_name, provider, is_batch ){

	is_batch = is_batch || false;

	push_providers[provider_name] = {
										module:provider,
										is_batch: is_batch
									};
}

/*
 * default function for handling events.
 */
function default_ev_handler(msg, rcpts){

	if( !(rcpts = rcpts || util.clone(msg.ev_ctx.config.rcpts) || util.clone(msg.ev_ctx.doc.rcpts)) )//rcpts parameter takes precedence over document rcpts
		return;

	if(msg.ev_ctx.user)
		rcpts = _.reject( rcpts,function(rcpt){ return rcpt.push_id == msg.ev_ctx.user.push_id});

	var ev_msg = {ev_type: msg.ev_type, ev_tstamp: msg.ev_tstamp, ev_data: msg.ev_ctx.payload};
	if(msg.ev_tag)
		ev_msg.ev_tag = msg.ev_tag;

	async.series(
		[
			function(next){//save event into journal

				eq.save(ev_msg,function(err){

					next(err);
				});
			},
			function(next){//process push for non-batch push providers

				if(rcpts && rcpts.length > 0){
					_.each( rcpts, function(rcpt){

						if( !push_providers[rcpt.push_type].is_batch ){
							if(rcpt.ev_types){
								if( _.contains(rcpt.ev_types,ev_msg.ev_type) )
									push_providers[rcpt.push_type].module.push( rcpt.push_id, ev_msg );

							}else
								push_providers[rcpt.push_type].module.push( rcpt.push_id, ev_msg );
						}
					});
				}
				next();

			},
			function(next){ //process push for batch push providers

				_.each(push_providers,function(push_provider, provider_type){

						if( push_provider.is_batch ){

							var push_ids =	 _.chain(rcpts)
											  .filter(function(rcpt){//filter provider type

													return rcpt.push_type == provider_type;
											 }).filter(function(rcpt){//filter event type

											 		if(!rcpt.ev_types)
											 			return true;
											 		else
											 			return _.contains(rcpt.ev_types,ev_msg.ev_type);
											 }).map(function(rcpt){//get rid of structure and get push_id only

													return rcpt.push_id;
											 }).value();
							if(!_.isEmpty(push_ids))
								push_provider.module.push( push_ids, ev_msg);
						}

				});

				next();
			}
		],function( err ){

		}
	);
}

/*
 * handler for ev_api_register event type
 */
api.on("ev_api_register", function( msg, rcpts ){

	default_ev_handler( msg, rcpts );

});

/*
 * handler for av_api_create event type
 */
api.on("ev_api_create", function( msg, rcpts ){

	default_ev_handler( msg, rcpts );

});

/*
 * handler for ev_api_dispose event type.
 */
api.on("ev_api_dispose", function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for ev_api_join event type.
 */
api.on("ev_api_join", function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for ev_api_unjoin event type
 */
api.on("ev_api_unjoin", function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for ev_api_rem event type.
 */
api.on("ev_api_remove", function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for the ev_api_set event type.
 */
api.on("ev_api_set",function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for the ev_api_push event type.
 */
api.on("ev_api_push",function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for the ev_api_pop event type.
 */
api.on("ev_api_pop",function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for the ev_api_shift event type.
 */
api.on("ev_api_shift",function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for ev_api_search event type
 */
api.on("ev_api_search",function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for ev_api_signal event type
 */
api.on("ev_api_signal",function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * Register listeners to the evmngr events.
 *
 */
exports.on = function( ev_type, ret_handler ){

	emitter.on(ev_type, function( params, rcpts ){

		ret_handler( {
						ev_type:ev_type,
						ev_tstamp:time.now(),
						ev_data:params
					 }, rcpts );
	});
}

/*
 * emit an event as it was generated inside the evmanager.
 */
var emit = exports.emit =  function( ev_type, params, rcpts ){

	emitter.emit(ev_type, params, rcpts );
}

/*
 * Make evmngr listen for api events.
 */
exports.api = {listen : function( ev_type ){

		api.on(ev_type,function( msg, rcpts ){

			default_ev_handler( msg, rcpts );

		});
	}
}

exports.remote = {};

/*
 *
 * Remote procedure to subscribe to the event queue. The socket remains open
 * after this call to send events to the subscribed client.
 */
exports.remote.subscribe = function( http_resp, params ){

	//TODO:select push provider to complete subscription.

	push_providers.web.module.subscribe(http_resp, params);

}

<commit_msg>added gcm push provider to module.<commit_after>var api = require("./api");
var util = require("./util");
var time = require("./time");

var eq = require("./evqueue");
var CONST = require("./constants");

var _ = require("underscore");
var async = require("async");

/*
 * built-in event emitter for own events.
 */
var EventEmitter = require("events").EventEmitter,
	emitter = new EventEmitter();

var push_providers = exports.push_providers =  {

	web:{
		module:require("./localpush"),
	  	is_batch:false
	},
	gcm:{
		module:require("./gcmpush"),
		is_batch:true
	}

};

/*
 * Add a push provider.
 */
exports.add_push_provider = function( provider_name, provider, is_batch ){

	is_batch = is_batch || false;

	push_providers[provider_name] = {
										module:provider,
										is_batch: is_batch
									};
}

/*
 * default function for handling events.
 */
function default_ev_handler(msg, rcpts){

	if( !(rcpts = rcpts || util.clone(msg.ev_ctx.config.rcpts) || util.clone(msg.ev_ctx.doc.rcpts)) )//rcpts parameter takes precedence over document rcpts
		return;

	if(msg.ev_ctx.user)
		rcpts = _.reject( rcpts,function(rcpt){ return rcpt.push_id == msg.ev_ctx.user.push_id});

	var ev_msg = {ev_type: msg.ev_type, ev_tstamp: msg.ev_tstamp, ev_data: msg.ev_ctx.payload};
	if(msg.ev_tag)
		ev_msg.ev_tag = msg.ev_tag;

	async.series(
		[
			function(next){//save event into journal

				eq.save(ev_msg,function(err){

					next(err);
				});
			},
			function(next){//process push for non-batch push providers

				if(rcpts && rcpts.length > 0){
					_.each( rcpts, function(rcpt){

						if( !push_providers[rcpt.push_type].is_batch ){
							if(rcpt.ev_types){
								if( _.contains(rcpt.ev_types,ev_msg.ev_type) )
									push_providers[rcpt.push_type].module.push( rcpt.push_id, ev_msg );

							}else
								push_providers[rcpt.push_type].module.push( rcpt.push_id, ev_msg );
						}
					});
				}
				next();

			},
			function(next){ //process push for batch push providers

				_.each(push_providers,function(push_provider, provider_type){

						if( push_provider.is_batch ){

							var push_ids =	 _.chain(rcpts)
											  .filter(function(rcpt){//filter provider type

													return rcpt.push_type == provider_type;
											 }).filter(function(rcpt){//filter event type

											 		if(!rcpt.ev_types)
											 			return true;
											 		else
											 			return _.contains(rcpt.ev_types,ev_msg.ev_type);
											 }).map(function(rcpt){//get rid of structure and get push_id only

													return rcpt.push_id;
											 }).value();
							if(!_.isEmpty(push_ids))
								push_provider.module.push( push_ids, ev_msg);
						}

				});

				next();
			}
		],function( err ){

		}
	);
}

/*
 * handler for ev_api_register event type
 */
api.on("ev_api_register", function( msg, rcpts ){

	default_ev_handler( msg, rcpts );

});

/*
 * handler for av_api_create event type
 */
api.on("ev_api_create", function( msg, rcpts ){

	default_ev_handler( msg, rcpts );

});

/*
 * handler for ev_api_dispose event type.
 */
api.on("ev_api_dispose", function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for ev_api_join event type.
 */
api.on("ev_api_join", function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for ev_api_unjoin event type
 */
api.on("ev_api_unjoin", function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for ev_api_rem event type.
 */
api.on("ev_api_remove", function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for the ev_api_set event type.
 */
api.on("ev_api_set",function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for the ev_api_push event type.
 */
api.on("ev_api_push",function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for the ev_api_pop event type.
 */
api.on("ev_api_pop",function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for the ev_api_shift event type.
 */
api.on("ev_api_shift",function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for ev_api_search event type
 */
api.on("ev_api_search",function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * handler for ev_api_signal event type
 */
api.on("ev_api_signal",function( msg, rcpts ){

	default_ev_handler( msg, rcpts );
});

/*
 * Register listeners to the evmngr events.
 *
 */
exports.on = function( ev_type, ret_handler ){

	emitter.on(ev_type, function( params, rcpts ){

		ret_handler( {
						ev_type:ev_type,
						ev_tstamp:time.now(),
						ev_data:params
					 }, rcpts );
	});
}

/*
 * emit an event as it was generated inside the evmanager.
 */
var emit = exports.emit =  function( ev_type, params, rcpts ){

	emitter.emit(ev_type, params, rcpts );
}

/*
 * Make evmngr listen for api events.
 */
exports.api = {listen : function( ev_type ){

		api.on(ev_type,function( msg, rcpts ){

			default_ev_handler( msg, rcpts );

		});
	}
}

exports.remote = {};

/*
 *
 * Remote procedure to subscribe to the event queue. The socket remains open
 * after this call to send events to the subscribed client.
 */
exports.remote.subscribe = function( http_resp, params ){

	//TODO:select push provider to complete subscription.

	push_providers.web.module.subscribe(http_resp, params);

}

<|endoftext|>


<commit_before>var stylus = require('stylus'),
    source = '';

process.stdin.resume();
process.stdin.setEncoding('utf8');

process.stdin.on('data', function(chunk) {
  source += chunk;
});

process.stdin.on('end', function() {
  var style = stylus(source, {filename: process.argv[2]});
  style.render(function(err, css) {
    if (err) {
      throw err;
    }
    process.stdout.write(css);
  })
});
<commit_msg>Using nib in compiler script.<commit_after>var stylus = require('stylus'),
    nib = require('nib'),
    source = '';

process.stdin.resume();
process.stdin.setEncoding('utf8');

process.stdin.on('data', function(chunk) {
  source += chunk;
});

process.stdin.on('end', function() {
  var style = stylus(source, {filename: process.argv[2]}).use(nib());
  style.render(function(err, css) {
    if (err) {
      throw err;
    }
    process.stdout.write(css);
  })
});
<|endoftext|>


<commit_before>const decompress = require('decompress')
const request = require('request')
const ProgressBar = require('progress')
const tmpdir = require('os-tmpdir')
const mkdirp = require('mkdirp')
const path = require('path')
const fs = require('fs')
const checksum = require('checksum')
const rimraf = require('rimraf')

const decompressUnzip = require('decompress-unzip')
const decompressTargz = require('decompress-targz')
const targz = require('tar.gz')
const tar = require('tar')
const zlib = require('zlib')

const config = {
  outputPath: path.join(__dirname, '..', 'git'),
  version: '2.11.0',
  source: '',
  checksum: '',
  upstreamVersion: '',
  fileName: ''
}

config.fileName = `git-kitchen-sink-${process.platform}-v${config.version}-2.zip`

// TODO: swap these out for official release URLs when we make the repository public

if (process.platform === 'darwin') {
  config.source = `https://www.dropbox.com/s/pd1q8gqttvhgm59/${config.fileName}?dl=1`
  config.checksum = '0c2e0535f86de75c58cf0c815cd3e1e7a172d32537fcfdc4f452745613586a4f'
} else if (process.platform === 'win32') {
  config.source = `https://www.dropbox.com/s/wjbs9p8959nt8w4/${config.fileName}?dl=1`
  config.checksum = '45158f9172889ff3020562788473d235cca1ca3281d955111b0b44fec71013e8'
} else if (process.platform === 'linux') {
  // switching this to Ubuntu to ensure it's clear what we're installing here
  config.fileName = `git-kitchen-sink-ubuntu-v${config.version}-2.zip`
  config.source = `https://www.dropbox.com/s/cm69onplkfixwfy/${config.fileName}?dl=1`
  config.checksum = '8723719b1dfb461715b39f88f048dfc1444b617fa1673dde0c17bdf6e70605ae'
}
const fullUrl = config.source

function handleError (url, error) {
  if (!error) {
    return
  }

  const message = error.message || error
  console.error(`Downloading ${url} failed: ${message}`)
  process.exit(1)
}

function extract (source, callback) {
  if (path.extname(source) === '.zip') {
    const result = decompress(source, config.outputPath)
    result
      .then(() => {
        callback(null)
      })
      .catch(err => {
        callback(err)
      })

  } else {
    const extractor = tar.Extract({path: config.outputPath})
      .on('error', function (error) { callback(error) })
      .on('end', function () { callback() })

    fs.createReadStream(source)
      .on('error', function (error) { callback(error) })
      .pipe(zlib.Gunzip())
      .pipe(extractor)
  }
}

const dir = tmpdir()
const temporaryFile = path.join(dir, config.fileName)

const verifyFile = function (file, callback) {
  checksum.file(file, { algorithm: 'sha256' }, (_, hash) => {
    callback(hash === config.checksum)
  })
}

const unpackFile = function (file) {
  extract(file, function (error) {
    if (error) {
      return handleError(fullUrl, error)
    }
  })
}

const downloadCallback = function (error, response, body) {
  if (error) {
    return handleError(fullUrl, error)
  }

  if (response.statusCode !== 200) {
    return handleError(fullUrl, Error(`Non-200 response (${response.statusCode})`))
  }

  fs.createWriteStream(temporaryFile).write(body, function (error) {
    if (error) {
      return handleError(fullUrl, error)
    }

    verifyFile(temporaryFile, valid => {
      if (valid) {
        unpackFile(temporaryFile)
      } else {
        process.exit(1)
      }
    })
  })
}

const downloadAndUnpack = () => {
  console.log(`Downloading Git from: ${fullUrl}`)

  const req = request.get(fullUrl, { encoding: null }, downloadCallback)

  req.on('response', function (res) {
    const len = parseInt(res.headers['content-length'], 10)

    console.log()
    const bar = new ProgressBar('Downloading Git [:bar] :percent :etas', {
      complete: '=',
      incomplete: ' ',
      width: 50,
      total: len
    })

    res.on('data', function (chunk) {
      bar.tick(chunk.length)
    })

    res.on('end', function () {
      console.log('\n')
    })
  })
}

mkdirp(config.outputPath, function (error) {
  if (error) {
    return handleError(fullUrl, error)
  }

  if (fs.existsSync(config.outputPath)) {
    try {
      rimraf.sync(config.outputPath)
    } catch (err) {
      console.error(err)
      return
    }
  }

  if (fs.existsSync(temporaryFile)) {
    verifyFile(temporaryFile, valid => {
      if (valid) {
        unpackFile(temporaryFile)
      } else {
        rimraf.sync(temporaryFile)
        downloadAndUnpack()
      }
    })
    return
  }

  downloadAndUnpack()
})
<commit_msg>fixed error with verifying checksums<commit_after>const decompress = require('decompress')
const request = require('request')
const ProgressBar = require('progress')
const tmpdir = require('os-tmpdir')
const mkdirp = require('mkdirp')
const path = require('path')
const fs = require('fs')
const checksum = require('checksum')
const rimraf = require('rimraf')

const decompressUnzip = require('decompress-unzip')
const decompressTargz = require('decompress-targz')
const targz = require('tar.gz')
const tar = require('tar')
const zlib = require('zlib')

const config = {
  outputPath: path.join(__dirname, '..', 'git'),
  version: '2.11.0',
  source: '',
  checksum: '',
  upstreamVersion: '',
  fileName: ''
}

config.fileName = `git-kitchen-sink-${process.platform}-v${config.version}-2.zip`

// TODO: swap these out for official release URLs when we make the repository public

if (process.platform === 'darwin') {
  config.source = `https://www.dropbox.com/s/pd1q8gqttvhgm59/${config.fileName}?dl=1`
  config.checksum = '0c2e0535f86de75c58cf0c815cd3e1e7a172d32537fcfdc4f452745613586a4f'
} else if (process.platform === 'win32') {
  config.source = `https://www.dropbox.com/s/wjbs9p8959nt8w4/${config.fileName}?dl=1`
  config.checksum = '8723719b1dfb461715b39f88f048dfc1444b617fa1673dde0c17bdf6e70605ae'
} else if (process.platform === 'linux') {
  // switching this to Ubuntu to ensure it's clear what we're installing here
  config.fileName = `git-kitchen-sink-ubuntu-v${config.version}-2.zip`
  config.source = `https://www.dropbox.com/s/cm69onplkfixwfy/${config.fileName}?dl=1`
  config.checksum = '45158f9172889ff3020562788473d235cca1ca3281d955111b0b44fec71013e8'
}
const fullUrl = config.source

function handleError (url, error) {
  if (!error) {
    return
  }

  const message = error.message || error
  console.error(`Downloading ${url} failed: ${message}`)
  process.exit(1)
}

function extract (source, callback) {
  if (path.extname(source) === '.zip') {
    const result = decompress(source, config.outputPath)
    result
      .then(() => {
        callback(null)
      })
      .catch(err => {
        callback(err)
      })

  } else {
    const extractor = tar.Extract({path: config.outputPath})
      .on('error', function (error) { callback(error) })
      .on('end', function () { callback() })

    fs.createReadStream(source)
      .on('error', function (error) { callback(error) })
      .pipe(zlib.Gunzip())
      .pipe(extractor)
  }
}

const dir = tmpdir()
const temporaryFile = path.join(dir, config.fileName)

const verifyFile = function (file, callback) {
  checksum.file(file, { algorithm: 'sha256' }, (_, hash) => {
    const isValid = hash === config.checksum
    if (!isValid) {
      console.log(`DEBUG: expected checksums to be equal: ${hash} === ${config.checksum}`)
    }
    callback(hash === config.checksum)
  })
}

const unpackFile = function (file) {
  extract(file, function (error) {
    if (error) {
      return handleError(fullUrl, error)
    }
  })
}

const downloadCallback = function (error, response, body) {
  if (error) {
    return handleError(fullUrl, error)
  }

  if (response.statusCode !== 200) {
    return handleError(fullUrl, Error(`Non-200 response (${response.statusCode})`))
  }

  fs.createWriteStream(temporaryFile).write(body, function (error) {
    if (error) {
      return handleError(fullUrl, error)
    }

    verifyFile(temporaryFile, valid => {
      if (valid) {
        unpackFile(temporaryFile)
      } else {
        process.exit(1)
      }
    })
  })
}

const downloadAndUnpack = () => {
  console.log(`Downloading Git from: ${fullUrl}`)

  const req = request.get(fullUrl, { encoding: null }, downloadCallback)

  req.on('response', function (res) {
    const len = parseInt(res.headers['content-length'], 10)

    console.log()
    const bar = new ProgressBar('Downloading Git [:bar] :percent :etas', {
      complete: '=',
      incomplete: ' ',
      width: 50,
      total: len
    })

    res.on('data', function (chunk) {
      bar.tick(chunk.length)
    })

    res.on('end', function () {
      console.log('\n')
    })
  })
}

mkdirp(config.outputPath, function (error) {
  if (error) {
    return handleError(fullUrl, error)
  }

  if (fs.existsSync(config.outputPath)) {
    try {
      rimraf.sync(config.outputPath)
    } catch (err) {
      console.error(err)
      return
    }
  }

  if (fs.existsSync(temporaryFile)) {
    verifyFile(temporaryFile, valid => {
      if (valid) {
        unpackFile(temporaryFile)
      } else {
        rimraf.sync(temporaryFile)
        downloadAndUnpack()
      }
    })
    return
  }

  downloadAndUnpack()
})
<|endoftext|>


<commit_before>//  Phaser.Physics.Matter

module.exports = {

    Factory: require('./Factory'),
    Image: require('./MatterImage'),
    Matter: require('./CustomMain'),
    MatterPhysics: require('./MatterPhysics'),
    Sprite: require('./MatterSprite'),
    World: require('./World')

};
<commit_msg>Expose Phaser.Physics.Matter.TileBody<commit_after>//  Phaser.Physics.Matter

module.exports = {

    Factory: require('./Factory'),
    Image: require('./MatterImage'),
    Matter: require('./CustomMain'),
    MatterPhysics: require('./MatterPhysics'),
    Sprite: require('./MatterSprite'),
    TileBody: require('./MatterTileBody'),
    World: require('./World')

};
<|endoftext|>


<commit_before>/**
 * @author Mat Groves http://matgroves.com/ @Doormat23
 */

/**
 * The json file loader is used to load in JSON data and parse it
 * When loaded this class will dispatch a 'loaded' event
 * If loading fails this class will dispatch an 'error' event
 *
 * @class JsonLoader
 * @uses EventTarget
 * @constructor
 * @param url {String} The url of the JSON file
 * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
 */
PIXI.JsonLoader = function (url, crossorigin) {

    /**
     * The url of the bitmap font data
     *
     * @property url
     * @type String
     */
    this.url = url;

    /**
     * Whether the requests should be treated as cross origin
     *
     * @property crossorigin
     * @type Boolean
     */
    this.crossorigin = crossorigin;

    /**
     * [read-only] The base url of the bitmap font data
     *
     * @property baseUrl
     * @type String
     * @readOnly
     */
    this.baseUrl = url.replace(/[^\/]*$/, '');

    /**
     * [read-only] Whether the data has loaded yet
     *
     * @property loaded
     * @type Boolean
     * @readOnly
     */
    this.loaded = false;

};

// constructor
PIXI.JsonLoader.prototype.constructor = PIXI.JsonLoader;

PIXI.EventTarget.mixin(PIXI.JsonLoader.prototype);

/**
 * Loads the JSON data
 *
 * @method load
 */
PIXI.JsonLoader.prototype.load = function () {

    if(window.XDomainRequest && this.crossorigin)
    {
        this.ajaxRequest = new window.XDomainRequest();

        // XDomainRequest has a few quirks. Occasionally it will abort requests
        // A way to avoid this is to make sure ALL callbacks are set even if not used
        // More info here: http://stackoverflow.com/questions/15786966/xdomainrequest-aborts-post-on-ie-9
        this.ajaxRequest.timeout = 3000;

        this.ajaxRequest.onerror = this.onError.bind(this);

        this.ajaxRequest.ontimeout = this.onError.bind(this);

        this.ajaxRequest.onprogress = function() {};

    }
    else if (window.XMLHttpRequest)
    {
        this.ajaxRequest = new window.XMLHttpRequest();
    }
    else
    {
        this.ajaxRequest = new window.ActiveXObject('Microsoft.XMLHTTP');
    }

    this.ajaxRequest.onload = this.onJSONLoaded.bind(this);

    this.ajaxRequest.open('GET',this.url,true);

    this.ajaxRequest.send();
};

/**
 * Invoked when the JSON file is loaded.
 *
 * @method onJSONLoaded
 * @private
 */
PIXI.JsonLoader.prototype.onJSONLoaded = function () {

    if(!this.ajaxRequest.responseText )
    {
        this.onError();
        return;
    }

    this.json = JSON.parse(this.ajaxRequest.responseText);

    if(this.json.frames)
    {
        // sprite sheet
        var textureUrl = this.baseUrl + this.json.meta.image;
        var image = new PIXI.ImageLoader(textureUrl, this.crossorigin);
        var frameData = this.json.frames;

        this.texture = image.texture.baseTexture;
        image.addEventListener('loaded', this.onLoaded.bind(this));

        for (var i in frameData)
        {
            var rect = frameData[i].frame;

            if (rect)
            {
                var textureSize = new PIXI.Rectangle(rect.x, rect.y, rect.w, rect.h);
                var crop = textureSize.clone();
                var trim = null;

                //  Check to see if the sprite is trimmed
                if (frameData[i].trimmed)
                {
                    var actualSize = frameData[i].sourceSize;
                    var realSize = frameData[i].spriteSourceSize;
                    trim = new PIXI.Rectangle(realSize.x, realSize.y, actualSize.w, actualSize.h);
                }
                PIXI.TextureCache[i] = new PIXI.Texture(this.texture, textureSize, crop, trim);
            }
        }

        image.load();

    }
    else if(this.json.bones)
    {
        // spine animation
        var spineJsonParser = new spine.SkeletonJson();
        var skeletonData = spineJsonParser.readSkeletonData(this.json);
        PIXI.AnimCache[this.url] = skeletonData;
        this.onLoaded();
    }
    else
    {
        this.onLoaded();
    }
};

/**
 * Invoked when the json file has loaded.
 *
 * @method onLoaded
 * @private
 */
PIXI.JsonLoader.prototype.onLoaded = function () {
    this.loaded = true;
    this.dispatchEvent({
        type: 'loaded',
        content: this
    });
};

/**
 * Invoked if an error occurs.
 *
 * @method onError
 * @private
 */
PIXI.JsonLoader.prototype.onError = function () {

    this.dispatchEvent({
        type: 'error',
        content: this
    });
};
<commit_msg>-[LOADER] Json loader now loads spine files as per the new implementation.<commit_after>/**
 * @author Mat Groves http://matgroves.com/ @Doormat23
 */

/**
 * The json file loader is used to load in JSON data and parse it
 * When loaded this class will dispatch a 'loaded' event
 * If loading fails this class will dispatch an 'error' event
 *
 * @class JsonLoader
 * @uses EventTarget
 * @constructor
 * @param url {String} The url of the JSON file
 * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
 */
PIXI.JsonLoader = function (url, crossorigin) {
    /**
     * The url of the bitmap font data
     *
     * @property url
     * @type String
     */
    this.url = url;

    /**
     * Whether the requests should be treated as cross origin
     *
     * @property crossorigin
     * @type Boolean
     */
    this.crossorigin = crossorigin;

    /**
     * [read-only] The base url of the bitmap font data
     *
     * @property baseUrl
     * @type String
     * @readOnly
     */
    this.baseUrl = url.replace(/[^\/]*$/, '');

    /**
     * [read-only] Whether the data has loaded yet
     *
     * @property loaded
     * @type Boolean
     * @readOnly
     */
    this.loaded = false;

};

// constructor
PIXI.JsonLoader.prototype.constructor = PIXI.JsonLoader;
PIXI.EventTarget.mixin(PIXI.JsonLoader.prototype);

/**
 * Loads the JSON data
 *
 * @method load
 */
PIXI.JsonLoader.prototype.load = function () {

    if(window.XDomainRequest && this.crossorigin)
    {
        this.ajaxRequest = new window.XDomainRequest();

        // XDomainRequest has a few querks. Occasionally it will abort requests
        // A way to avoid this is to make sure ALL callbacks are set even if not used
        // More info here: http://stackoverflow.com/questions/15786966/xdomainrequest-aborts-post-on-ie-9
        this.ajaxRequest.timeout = 3000;

        this.ajaxRequest.onerror = this.onError.bind(this);

        this.ajaxRequest.ontimeout = this.onError.bind(this);

        this.ajaxRequest.onprogress = function() {};

        this.ajaxRequest.onload = this.onJSONLoaded.bind(this);
    }
    else
    {
        if (window.XMLHttpRequest)
        {
            this.ajaxRequest = new window.XMLHttpRequest();
        }
        else
        {
            this.ajaxRequest = new window.ActiveXObject('Microsoft.XMLHTTP');
        }

        this.ajaxRequest.onreadystatechange = this.onReadyStateChanged.bind(this);
    }

    this.ajaxRequest.open('GET',this.url,true);

    this.ajaxRequest.send();
};

/**
 * Bridge function to be able to use the more reliable onreadystatechange in XMLHttpRequest.
 *
 * @method onReadyStateChanged
 * @private
 */
PIXI.JsonLoader.prototype.onReadyStateChanged = function () {
    if (this.ajaxRequest.readyState === 4 && (this.ajaxRequest.status === 200 || window.location.href.indexOf('http') === -1)) {
        this.onJSONLoaded();
    }
};

/**
 * Invoke when JSON file is loaded
 *
 * @method onJSONLoaded
 * @private
 */
PIXI.JsonLoader.prototype.onJSONLoaded = function () {

    if(!this.ajaxRequest.responseText )
    {
        this.onError();
        return;
    }

    this.json = JSON.parse(this.ajaxRequest.responseText);

    if(this.json.frames)
    {
        // sprite sheet
        var textureUrl = this.baseUrl + this.json.meta.image;
        var image = new PIXI.ImageLoader(textureUrl, this.crossorigin);
        var frameData = this.json.frames;

        this.texture = image.texture.baseTexture;
        image.addEventListener('loaded', this.onLoaded.bind(this));

        for (var i in frameData)
        {
            var rect = frameData[i].frame;

            if (rect)
            {
                var textureSize = new PIXI.Rectangle(rect.x, rect.y, rect.w, rect.h);
                var crop = textureSize.clone();
                var trim = null;

                //  Check to see if the sprite is trimmed
                if (frameData[i].trimmed)
                {
                    var actualSize = frameData[i].sourceSize;
                    var realSize = frameData[i].spriteSourceSize;
                    trim = new PIXI.Rectangle(realSize.x, realSize.y, actualSize.w, actualSize.h);
                }
                PIXI.TextureCache[i] = new PIXI.Texture(this.texture, textureSize, crop, trim);
            }
        }

        image.load();

    }
    else if(this.json.bones)
    {
		/* check if the json was loaded before */
		if (PIXI.AnimCache[this.url])
		{
			this.onLoaded();
		}
		else
		{
			/* use a bit of hackery to load the atlas file, here we assume that the .json, .atlas and .png files
			 * that correspond to the spine file are in the same base URL and that the .json and .atlas files
			 * have the same name
			*/
			var atlasPath = this.url.substr(0, this.url.lastIndexOf('.')) + '.atlas';
			var atlasLoader = new PIXI.JsonLoader(atlasPath, this.crossorigin);
			// save a copy of the current object for future reference //
			var originalLoader = this;
			// before loading the file, replace the "onJSONLoaded" function for our own //
			atlasLoader.onJSONLoaded = function()
			{
				// at this point "this" points at the atlasLoader (JsonLoader) instance //
				if(!this.ajaxRequest.responseText)
				{
					this.onError(); // FIXME: hmm, this is funny because we are not reponding to errors yet
					return;
				}
				// create a new instance of a spine texture loader for this spine object //
				var textureLoader = new PIXI.SpineTextureLoader(this.url.substring(0, this.url.lastIndexOf('/')));
				// create a spine atlas using the loaded text and a spine texture loader instance //
				var spineAtlas = new spine.Atlas(this.ajaxRequest.responseText, textureLoader);
				// now we use an atlas attachment loader //
				var attachmentLoader = new spine.AtlasAttachmentLoader(spineAtlas);
				// spine animation
				var spineJsonParser = new spine.SkeletonJson(attachmentLoader);
				var skeletonData = spineJsonParser.readSkeletonData(originalLoader.json);
				PIXI.AnimCache[originalLoader.url] = skeletonData;
				originalLoader.spine = skeletonData;
				originalLoader.spineAtlas = spineAtlas;
				originalLoader.spineAtlasLoader = atlasLoader;
				// wait for textures to finish loading if needed
				if (textureLoader.loadingCount > 0)
				{
					textureLoader.addEventListener('loadedBaseTexture', function(evt){
						if (evt.content.content.loadingCount <= 0)
						{
							originalLoader.onLoaded();
						}
					});
				}
				else
				{
					originalLoader.onLoaded();
				}
			};
			// start the loading //
			atlasLoader.load();
		}
    }
    else
    {
        this.onLoaded();
    }
};

/**
 * Invoke when json file loaded
 *
 * @method onLoaded
 * @private
 */
PIXI.JsonLoader.prototype.onLoaded = function () {
    this.loaded = true;
    this.dispatchEvent({
        type: 'loaded',
        content: this
    });
};

/**
 * Invoke when error occured
 *
 * @method onError
 * @private
 */
PIXI.JsonLoader.prototype.onError = function () {

    this.dispatchEvent({
        type: 'error',
        content: this
    });
};
<|endoftext|>


<commit_before>var _ = require('lodash');

var common = require('./common');
var buildOpenFiscaIndividu = require('./individu');
var migrations = require('../../migrations');

var propertyMove = require('./propertyMove');
var last3MonthsDuplication = require('./last3MonthsDuplication');

function allocateIndividualsToEntities(situation) {
    var famille = situation.famille;
    var foyer = situation.foyer_fiscal;
    var menage = situation.menage;

    var demandeur = common.getDemandeur(situation);
    var demandeurId = demandeur && demandeur.id;
    if (demandeurId) {
        famille.parents = [ demandeurId ];
        foyer.declarants = [ demandeurId ];
        menage.personne_de_reference = [ demandeurId ];
    }

    var conjoint = common.getConjoint(situation);
    var conjointId = conjoint && conjoint.id;
    if (conjointId) {
        famille.parents.push(conjointId);
        foyer.declarants.push(conjointId);
        menage.conjoint = [ conjointId ];
    }

    var enfants = common.getEnfants(situation);
    var validEnfants = _.filter(enfants, function(enfant) { return common.isIndividuValid(enfant, situation); });
    var enfantIds = validEnfants.map(function(enfant) { return enfant.id; });
    famille.enfants = enfantIds;
    foyer.personnes_a_charge = enfantIds;
    menage.enfants = enfantIds;
}

function setNonInjectedPrestations(testCase, periods, value) {
    var prestationsFinancieres = _.pickBy(common.requestedVariables, function(definition) {
        return (! definition.type) || definition.type === 'float';
    });

    _.forEach(prestationsFinancieres, function(definition, prestationName) {
        _.forEach(testCase[(definition.entity || 'famille') + 's'], function(entity) {
            entity[prestationName] = entity[prestationName] || {};
            _.forEach(periods, function(period) {
                if (value === undefined) {
                    delete entity[prestationName][period];
                } else {
                    entity[prestationName][period] = entity[prestationName][period] || value;
                }
            });
        });
    });
}
exports.setNonInjectedPrestations = setNonInjectedPrestations;

function mapIndividus(situation) {
    var individus = _.filter(situation.individus, function(individu) {
        return common.isIndividuValid(individu, situation);
    });

    return _.map(individus, function(individu) {
        return buildOpenFiscaIndividu(individu, situation);
    }).reduce(function(accum, individu) {
        accum[individu.id] = individu;
        delete individu.id;
        return accum;
    }, {});
}

function giveValueToRequestedVariables(testCase, periods, value) {
    if (! (periods instanceof Array)) {
        periods = [periods];
    }

    _.forEach(common.requestedVariables, function(definition, prestationName) {
        _.forEach(testCase[(definition.entity || 'famille') + 's'], function(entity) {
            entity[prestationName] = entity[prestationName] || {};
            _.forEach(periods, function(period) {
                if (typeof entity[prestationName][period] !== 'undefined' && entity[prestationName][period] !== null) {
                    return;
                }
                if (value === undefined) {
                    delete entity[prestationName][period];
                } else {
                    entity[prestationName][period] = value;
                }
            });
        });
    });
}
exports.giveValueToRequestedVariables = giveValueToRequestedVariables;

exports.buildOpenFiscaRequest = function(sourceSituation) {
    var situation = sourceSituation.toObject ? migrations.apply(sourceSituation).toObject() : _.cloneDeep(sourceSituation);
    var periods = common.getPeriods(situation.dateDeValeur);

    var individus = mapIndividus(situation);
    allocateIndividualsToEntities(situation);

    delete situation.menage.nom_commune;
    delete situation.menage.code_postal;

    var menage = _.assign({}, {
        logement_conventionne: {},
        aide_logement_date_pret_conventionne: {}
    }, situation.menage);

    menage.logement_conventionne[periods.thisMonth] = menage.statut_occupation_logement == 'primo_accedant' && menage.loyer == 0;
    menage.aide_logement_date_pret_conventionne[periods.thisMonth] = '2017-12-31';

    var testCase = {
        individus: individus,
        familles: {
            _: situation.famille
        },
        foyers_fiscaux: {
            _: situation.foyer_fiscal
        },
        menages: {
            _: menage
        },
    };

    propertyMove.movePropertyValuesToGroupEntity(testCase);

    setNonInjectedPrestations(testCase, periods.last12Months, 0);
    last3MonthsDuplication(testCase, situation.dateDeValeur);
    giveValueToRequestedVariables(testCase, periods.thisMonth, null);

    return testCase;
};
<commit_msg>Comment fix/heuristic<commit_after>var _ = require('lodash');

var common = require('./common');
var buildOpenFiscaIndividu = require('./individu');
var migrations = require('../../migrations');

var propertyMove = require('./propertyMove');
var last3MonthsDuplication = require('./last3MonthsDuplication');

function allocateIndividualsToEntities(situation) {
    var famille = situation.famille;
    var foyer = situation.foyer_fiscal;
    var menage = situation.menage;

    var demandeur = common.getDemandeur(situation);
    var demandeurId = demandeur && demandeur.id;
    if (demandeurId) {
        famille.parents = [ demandeurId ];
        foyer.declarants = [ demandeurId ];
        menage.personne_de_reference = [ demandeurId ];
    }

    var conjoint = common.getConjoint(situation);
    var conjointId = conjoint && conjoint.id;
    if (conjointId) {
        famille.parents.push(conjointId);
        foyer.declarants.push(conjointId);
        menage.conjoint = [ conjointId ];
    }

    var enfants = common.getEnfants(situation);
    var validEnfants = _.filter(enfants, function(enfant) { return common.isIndividuValid(enfant, situation); });
    var enfantIds = validEnfants.map(function(enfant) { return enfant.id; });
    famille.enfants = enfantIds;
    foyer.personnes_a_charge = enfantIds;
    menage.enfants = enfantIds;
}

function setNonInjectedPrestations(testCase, periods, value) {
    var prestationsFinancieres = _.pickBy(common.requestedVariables, function(definition) {
        return (! definition.type) || definition.type === 'float';
    });

    _.forEach(prestationsFinancieres, function(definition, prestationName) {
        _.forEach(testCase[(definition.entity || 'famille') + 's'], function(entity) {
            entity[prestationName] = entity[prestationName] || {};
            _.forEach(periods, function(period) {
                if (value === undefined) {
                    delete entity[prestationName][period];
                } else {
                    entity[prestationName][period] = entity[prestationName][period] || value;
                }
            });
        });
    });
}
exports.setNonInjectedPrestations = setNonInjectedPrestations;

function mapIndividus(situation) {
    var individus = _.filter(situation.individus, function(individu) {
        return common.isIndividuValid(individu, situation);
    });

    return _.map(individus, function(individu) {
        return buildOpenFiscaIndividu(individu, situation);
    }).reduce(function(accum, individu) {
        accum[individu.id] = individu;
        delete individu.id;
        return accum;
    }, {});
}

function giveValueToRequestedVariables(testCase, periods, value) {
    if (! (periods instanceof Array)) {
        periods = [periods];
    }

    _.forEach(common.requestedVariables, function(definition, prestationName) {
        _.forEach(testCase[(definition.entity || 'famille') + 's'], function(entity) {
            entity[prestationName] = entity[prestationName] || {};
            _.forEach(periods, function(period) {
                if (typeof entity[prestationName][period] !== 'undefined' && entity[prestationName][period] !== null) {
                    return;
                }
                if (value === undefined) {
                    delete entity[prestationName][period];
                } else {
                    entity[prestationName][period] = value;
                }
            });
        });
    });
}
exports.giveValueToRequestedVariables = giveValueToRequestedVariables;

exports.buildOpenFiscaRequest = function(sourceSituation) {
    var situation = sourceSituation.toObject ? migrations.apply(sourceSituation).toObject() : _.cloneDeep(sourceSituation);
    var periods = common.getPeriods(situation.dateDeValeur);

    var individus = mapIndividus(situation);
    allocateIndividualsToEntities(situation);

    delete situation.menage.nom_commune;
    delete situation.menage.code_postal;

    var menage = _.assign({}, {
        logement_conventionne: {},
        aide_logement_date_pret_conventionne: {}
    }, situation.menage);

    // Use heuristics to pass functional tests
    // Complexity may be added in the future in the application (new questions to ask)
    // So far, due to a bug or some ambiguity
    // cf. https://github.com/openfisca/openfisca-france/pull/1233
    // logement_conventionne needs to be true when the loan in fully paid
    // to avoid a benefit from appearing
    menage.logement_conventionne[periods.thisMonth] = menage.statut_occupation_logement == 'primo_accedant' && menage.loyer == 0;
    menage.aide_logement_date_pret_conventionne[periods.thisMonth] = '2017-12-31';

    var testCase = {
        individus: individus,
        familles: {
            _: situation.famille
        },
        foyers_fiscaux: {
            _: situation.foyer_fiscal
        },
        menages: {
            _: menage
        },
    };

    propertyMove.movePropertyValuesToGroupEntity(testCase);

    setNonInjectedPrestations(testCase, periods.last12Months, 0);
    last3MonthsDuplication(testCase, situation.dateDeValeur);
    giveValueToRequestedVariables(testCase, periods.thisMonth, null);

    return testCase;
};
<|endoftext|>


<commit_before>var _ = require('lodash');

var common = require('./common');
var buildOpenFiscaIndividu = require('./individu');
var migrations = require('../../migrations');

var propertyMove = require('./propertyMove');
var last3MonthsDuplication = require('./last3MonthsDuplication');

function allocateIndividualsToEntities(situation) {
    var famille = situation.famille;
    var foyer = situation.foyer_fiscal;
    var menage = situation.menage;

    var demandeur = common.getDemandeur(situation);
    var demandeurId = demandeur && demandeur.id;
    if (demandeurId) {
        famille.parents = [ demandeurId ];
        foyer.declarants = [ demandeurId ];
        menage.personne_de_reference = [ demandeurId ];
    }

    var conjoint = common.getConjoint(situation);
    var conjointId = conjoint && conjoint.id;
    if (conjointId) {
        famille.parents.push(conjointId);
        foyer.declarants.push(conjointId);
        menage.conjoint = [ conjointId ];
    }

    var enfants = common.getEnfants(situation);
    var validEnfants = _.filter(enfants, function(enfant) { return common.isIndividuValid(enfant, situation); });
    var enfantIds = validEnfants.map(function(enfant) { return enfant.id; });
    famille.enfants = enfantIds;
    foyer.personnes_a_charge = enfantIds;
    menage.enfants = enfantIds;
}

function setNonInjectedPrestations(testCase, periods, value) {
    var prestationsFinancieres = _.pickBy(common.requestedVariables, function(definition) {
        return ((! definition.type) || definition.type === 'float');
    });

    _.forEach(prestationsFinancieres, function(definition, prestationName) {
        _.forEach(testCase[(definition.entity || 'famille') + 's'], function(entity) {
            entity[prestationName] = entity[prestationName] || {};
            _.forEach(periods, function(period) {
                if (value === undefined) {
                    delete entity[prestationName][period];
                } else {
                    entity[prestationName][period] = entity[prestationName][period] || value;
                }
            });
        });
    });
}
exports.setNonInjectedPrestations = setNonInjectedPrestations;

function mapIndividus(situation) {
    var individus = _.filter(situation.individus, function(individu) {
        return common.isIndividuValid(individu, situation);
    });

    return _.map(individus, function(individu) {
        return buildOpenFiscaIndividu(individu, situation);
    }).reduce(function(accum, individu) {
        accum[individu.id] = individu;
        delete individu.id;
        return accum;
    }, {});
}

function giveValueToRequestedVariables(testCase, periods, value) {
    if (! (periods instanceof Array)) {
        periods = [periods];
    }

    _.forEach(common.requestedVariables, function(definition, prestationName) {
        _.forEach(testCase[(definition.entity || 'famille') + 's'], function(entity) {
            entity[prestationName] = entity[prestationName] || {};
            _.forEach(periods, function(period) {
                if (typeof entity[prestationName][period] !== 'undefined' && entity[prestationName][period] !== null) {
                    return;
                }
                if (value === undefined) {
                    delete entity[prestationName][period];
                } else {
                    entity[prestationName][period] = value;
                }
            });
        });
    });
}
exports.giveValueToRequestedVariables = giveValueToRequestedVariables;

// Use heuristics to pass functional tests
// Complexity may be added in the future in the application (new questions to ask)
// So far, due to a bug or some ambiguity
// cf. https://github.com/openfisca/openfisca-france/pull/1233
// logement_conventionne needs to be true when the loan in fully paid
// to avoid a benefit from appearing
function applyHeuristicsAndFix(testCase, dateDeValeur) {
    var thisMonth = common.getPeriods(dateDeValeur).thisMonth;

    var menage = _.assign({}, {
        logement_conventionne: {},
    }, testCase.menages._);
    menage.logement_conventionne[thisMonth] = menage.statut_occupation_logement && menage.statut_occupation_logement[thisMonth] == 'primo_accedant' && menage.loyer && menage.loyer[thisMonth] == 0;

    testCase.menages._ = menage;
    return testCase;
}

exports.buildOpenFiscaRequest = function(sourceSituation) {
    var situation = sourceSituation.toObject ? migrations.apply(sourceSituation).toObject() : _.cloneDeep(sourceSituation);

    var individus = mapIndividus(situation);
    allocateIndividualsToEntities(situation);

    delete situation.menage.nom_commune;
    delete situation.menage.code_postal;

    var testCase = {
        individus: individus,
        familles: {
            _: situation.famille
        },
        foyers_fiscaux: {
            _: situation.foyer_fiscal
        },
        menages: {
            _: situation.menage
        },
    };

    propertyMove.movePropertyValuesToGroupEntity(testCase);

    var periods = common.getPeriods(situation.dateDeValeur);
    setNonInjectedPrestations(testCase, _.difference(periods.last12Months, periods.last3Months), 0);
    last3MonthsDuplication(testCase, situation.dateDeValeur);
    giveValueToRequestedVariables(testCase, _.concat(periods.last3Months, periods.thisMonth), null);

    return applyHeuristicsAndFix(testCase, sourceSituation.dateDeValeur);
};
<commit_msg>Restore default value for aide_logement_date_pret_conventionne.<commit_after>var _ = require('lodash');

var common = require('./common');
var buildOpenFiscaIndividu = require('./individu');
var migrations = require('../../migrations');

var propertyMove = require('./propertyMove');
var last3MonthsDuplication = require('./last3MonthsDuplication');

function allocateIndividualsToEntities(situation) {
    var famille = situation.famille;
    var foyer = situation.foyer_fiscal;
    var menage = situation.menage;

    var demandeur = common.getDemandeur(situation);
    var demandeurId = demandeur && demandeur.id;
    if (demandeurId) {
        famille.parents = [ demandeurId ];
        foyer.declarants = [ demandeurId ];
        menage.personne_de_reference = [ demandeurId ];
    }

    var conjoint = common.getConjoint(situation);
    var conjointId = conjoint && conjoint.id;
    if (conjointId) {
        famille.parents.push(conjointId);
        foyer.declarants.push(conjointId);
        menage.conjoint = [ conjointId ];
    }

    var enfants = common.getEnfants(situation);
    var validEnfants = _.filter(enfants, function(enfant) { return common.isIndividuValid(enfant, situation); });
    var enfantIds = validEnfants.map(function(enfant) { return enfant.id; });
    famille.enfants = enfantIds;
    foyer.personnes_a_charge = enfantIds;
    menage.enfants = enfantIds;
}

function setNonInjectedPrestations(testCase, periods, value) {
    var prestationsFinancieres = _.pickBy(common.requestedVariables, function(definition) {
        return ((! definition.type) || definition.type === 'float');
    });

    _.forEach(prestationsFinancieres, function(definition, prestationName) {
        _.forEach(testCase[(definition.entity || 'famille') + 's'], function(entity) {
            entity[prestationName] = entity[prestationName] || {};
            _.forEach(periods, function(period) {
                if (value === undefined) {
                    delete entity[prestationName][period];
                } else {
                    entity[prestationName][period] = entity[prestationName][period] || value;
                }
            });
        });
    });
}
exports.setNonInjectedPrestations = setNonInjectedPrestations;

function mapIndividus(situation) {
    var individus = _.filter(situation.individus, function(individu) {
        return common.isIndividuValid(individu, situation);
    });

    return _.map(individus, function(individu) {
        return buildOpenFiscaIndividu(individu, situation);
    }).reduce(function(accum, individu) {
        accum[individu.id] = individu;
        delete individu.id;
        return accum;
    }, {});
}

function giveValueToRequestedVariables(testCase, periods, value) {
    if (! (periods instanceof Array)) {
        periods = [periods];
    }

    _.forEach(common.requestedVariables, function(definition, prestationName) {
        _.forEach(testCase[(definition.entity || 'famille') + 's'], function(entity) {
            entity[prestationName] = entity[prestationName] || {};
            _.forEach(periods, function(period) {
                if (typeof entity[prestationName][period] !== 'undefined' && entity[prestationName][period] !== null) {
                    return;
                }
                if (value === undefined) {
                    delete entity[prestationName][period];
                } else {
                    entity[prestationName][period] = value;
                }
            });
        });
    });
}
exports.giveValueToRequestedVariables = giveValueToRequestedVariables;

// Use heuristics to pass functional tests
// Complexity may be added in the future in the application (new questions to ask)
// So far, due to a bug or some ambiguity
// cf. https://github.com/openfisca/openfisca-france/pull/1233
// logement_conventionne needs to be true when the loan in fully paid
// to avoid a benefit from appearing
function applyHeuristicsAndFix(testCase, dateDeValeur) {
    var thisMonth = common.getPeriods(dateDeValeur).thisMonth;

    var menage = _.assign({}, {
        logement_conventionne: {},
        aide_logement_date_pret_conventionne: {}
    }, testCase.menages._);
    menage.logement_conventionne[thisMonth] = menage.statut_occupation_logement && menage.statut_occupation_logement[thisMonth] == 'primo_accedant' && menage.loyer && menage.loyer[thisMonth] == 0;
    menage.aide_logement_date_pret_conventionne[thisMonth] = '2017-12-31';

    testCase.menages._ = menage;
    return testCase;
}

exports.buildOpenFiscaRequest = function(sourceSituation) {
    var situation = sourceSituation.toObject ? migrations.apply(sourceSituation).toObject() : _.cloneDeep(sourceSituation);

    var individus = mapIndividus(situation);
    allocateIndividualsToEntities(situation);

    delete situation.menage.nom_commune;
    delete situation.menage.code_postal;

    var testCase = {
        individus: individus,
        familles: {
            _: situation.famille
        },
        foyers_fiscaux: {
            _: situation.foyer_fiscal
        },
        menages: {
            _: situation.menage
        },
    };

    propertyMove.movePropertyValuesToGroupEntity(testCase);

    var periods = common.getPeriods(situation.dateDeValeur);
    setNonInjectedPrestations(testCase, _.difference(periods.last12Months, periods.last3Months), 0);
    last3MonthsDuplication(testCase, situation.dateDeValeur);
    giveValueToRequestedVariables(testCase, _.concat(periods.last3Months, periods.thisMonth), null);

    return applyHeuristicsAndFix(testCase, sourceSituation.dateDeValeur);
};
<|endoftext|>