<commit_before>var esprima = require('esprima'),
    escodegen = require('escodegen');

// Executes visitor on the object and its children (recursively).
var traverse = function traverse(object, visitor) {
    var key, child;

    visitor.call(null, object);
    for (key in object) {
        if (object.hasOwnProperty(key)) {
            child = object[key];
            if (typeof child === 'object' && child !== null) {
                traverse(child, visitor);
            }
        }
    }
};

var powerAssertVariableDeclaration = {
    "type": "VariableDeclaration",
    "declarations": [
        {
            "type": "VariableDeclarator",
            "id": {
                "type": "Identifier",
                "name": "passert"
            },
            "init": {
                "type": "CallExpression",
                "callee": {
                    "type": "Identifier",
                    "name": "require"
                },
                "arguments": [
                    {
                        "type": "Literal",
                        "value": "../lib/power-assert"
                    }
                ]
            }
        }
    ],
    "kind": "var"
};

var isAssertOkCall = function (callee) {
    if (callee.type !== 'MemberExpression' || callee.computed !== false) {
        return false;
    }
    var ob = callee.object,
        prop = callee.property;
    return ((ob.type === 'Identifier' && ob.name === 'assert') && (prop.type === 'Identifier' && prop.name === 'ok'));
};

var isAssertCall = function (callee) {
    return (callee.type === 'Identifier' && callee.name === 'assert');
};

// enclose  in __ident__
var capture = function (target, ident) {
    return {
        "type": "CallExpression",
        "callee": {
            "type": "MemberExpression",
            "computed": false,
            "object": {
                "type": "Identifier",
                "name": "passert"
            },
            "property": {
                "type": "Identifier",
                "name": "__ident__"
            }
        },
        "arguments": [
            {
                "type": "Literal",
                "value": ident.name
            },
            target,
            {
                "type": "Literal",
                "value": ident.loc.start.column
            },
            {
                "type": "Literal",
                "value": ident.loc.end.column
            }
        ]
    };
};

var captureIdent = function (ident) {
    return capture(ident, ident);
};

var captureMember = function (member) {
    member.object = captureIdent(member.object);
    return capture(member, member.property);
};

// enclose assert expression in __expr__
var captureFirstArgument = function (firstArgument, line) {
    return {
        "type": "CallExpression",
        "callee": {
            "type": "MemberExpression",
            "computed": false,
            "object": {
                "type": "Identifier",
                "name": "passert"
            },
            "property": {
                "type": "Identifier",
                "name": "__expr__"
            }
        },
        "arguments": [
            firstArgument,
            {
                "type": "Literal",
                "value": line
            }
        ]
    };
};

var instrument = function (expression, line) {
    var firstArgument = expression.arguments[0];

    if (firstArgument.type === 'Identifier') {
        firstArgument = captureIdent(firstArgument);
        expression.arguments[0] = captureFirstArgument(firstArgument, line);
    } else if (firstArgument.type === 'BinaryExpression') {
        var left = firstArgument.left,
            right = firstArgument.right;

        if (left.type === 'Identifier') {
            firstArgument.left = captureIdent(left);
        } else if (left.type === 'MemberExpression') {
            // ex: ary.length
            firstArgument.left = captureMember(left);
        }

        if (right.type === 'Identifier') {
            firstArgument.right = captureIdent(right);
        } else if (right.type === 'MemberExpression') {
            // ex: ary.length
            firstArgument.right = captureMember(right);
        }

        expression.arguments[0] = captureFirstArgument(firstArgument, line);
    }
};

var modifyTree = function (syntax, lines) {
    traverse(syntax, function (node) {
        if (typeof node.type === 'undefined' || node.type !== 'ExpressionStatement') {
            return;
        }
        var expression = node.expression;
        if (typeof expression.type === 'undefined' || expression.type !== 'CallExpression') {
            return;
        }
        var callee = expression.callee;
        if (!(isAssertCall(callee) || isAssertOkCall(callee))) {
            return;
        }
        var line = lines[node.loc.start.line - 1];
        instrument(expression, line);
    });
};

var generator = function generator(source, options) {
    options = options || {};
    var lines = source.split("\n"),
        tree = esprima.parse(source, {tolerant: true, loc: true});
    modifyTree(tree, lines, options);

    if (options['module'] === 'CommonJS') {
        // insert "var passert = require('power-assert');"
        tree.body.unshift(powerAssertVariableDeclaration);
    }

    console.log(escodegen.generate(tree));
};

generator.modifyTree = modifyTree;
generator.instrument = instrument;

/*global exports:false*/
if (typeof exports !== 'undefined') {
    module.exports = generator;
}
<commit_msg>refactored<commit_after>var esprima = require('esprima'),
    escodegen = require('escodegen');

// Executes visitor on the object and its children (recursively).
var traverse = function traverse(object, visitor) {
    var key, child;

    visitor.call(null, object);
    for (key in object) {
        if (object.hasOwnProperty(key)) {
            child = object[key];
            if (typeof child === 'object' && child !== null) {
                traverse(child, visitor);
            }
        }
    }
};

var powerAssertVariableDeclaration = {
    "type": "VariableDeclaration",
    "declarations": [
        {
            "type": "VariableDeclarator",
            "id": {
                "type": "Identifier",
                "name": "passert"
            },
            "init": {
                "type": "CallExpression",
                "callee": {
                    "type": "Identifier",
                    "name": "require"
                },
                "arguments": [
                    {
                        "type": "Literal",
                        "value": "../lib/power-assert"
                    }
                ]
            }
        }
    ],
    "kind": "var"
};

var isAssertOkCall = function (callee) {
    if (callee.type !== 'MemberExpression' || callee.computed !== false) {
        return false;
    }
    var ob = callee.object,
        prop = callee.property;
    return ((ob.type === 'Identifier' && ob.name === 'assert') && (prop.type === 'Identifier' && prop.name === 'ok'));
};

var isAssertCall = function (callee) {
    return (callee.type === 'Identifier' && callee.name === 'assert');
};

// enclose  in __ident__
var capture = function (target, ident) {
    return {
        "type": "CallExpression",
        "callee": {
            "type": "MemberExpression",
            "computed": false,
            "object": {
                "type": "Identifier",
                "name": "passert"
            },
            "property": {
                "type": "Identifier",
                "name": "__ident__"
            }
        },
        "arguments": [
            {
                "type": "Literal",
                "value": ident.name
            },
            target,
            {
                "type": "Literal",
                "value": ident.loc.start.column
            },
            {
                "type": "Literal",
                "value": ident.loc.end.column
            }
        ]
    };
};

var captureIdent = function (ident) {
    return capture(ident, ident);
};

var captureMember = function (member) {
    member.object = captureIdent(member.object);
    return capture(member, member.property);
};

// enclose assert expression in __expr__
var captureFirstArgument = function (firstArgument, line) {
    return {
        "type": "CallExpression",
        "callee": {
            "type": "MemberExpression",
            "computed": false,
            "object": {
                "type": "Identifier",
                "name": "passert"
            },
            "property": {
                "type": "Identifier",
                "name": "__expr__"
            }
        },
        "arguments": [
            firstArgument,
            {
                "type": "Literal",
                "value": line
            }
        ]
    };
};

var instrument = function (expression, line) {
    var firstArgument = expression.arguments[0];
    if (firstArgument.type === 'Identifier') {
        firstArgument = captureIdent(firstArgument);
    } else if (firstArgument.type === 'BinaryExpression') {
        var left = firstArgument.left,
            right = firstArgument.right;
        if (left.type === 'Identifier') {
            firstArgument.left = captureIdent(left);
        } else if (left.type === 'MemberExpression') {
            // ex: ary.length
            firstArgument.left = captureMember(left);
        }
        if (right.type === 'Identifier') {
            firstArgument.right = captureIdent(right);
        } else if (right.type === 'MemberExpression') {
            // ex: ary.length
            firstArgument.right = captureMember(right);
        }
    } else {
        return;
    }
    expression.arguments[0] = captureFirstArgument(firstArgument, line);
};

var modifyTree = function (syntax, lines) {
    traverse(syntax, function (node) {
        if (typeof node.type === 'undefined' || node.type !== 'ExpressionStatement') {
            return;
        }
        var expression = node.expression;
        if (typeof expression.type === 'undefined' || expression.type !== 'CallExpression') {
            return;
        }
        var callee = expression.callee;
        if (!(isAssertCall(callee) || isAssertOkCall(callee))) {
            return;
        }
        var line = lines[node.loc.start.line - 1];
        instrument(expression, line);
    });
};

var generator = function generator(source, options) {
    options = options || {};
    var lines = source.split("\n"),
        tree = esprima.parse(source, {tolerant: true, loc: true});
    modifyTree(tree, lines, options);

    if (options['module'] === 'CommonJS') {
        // insert "var passert = require('power-assert');"
        tree.body.unshift(powerAssertVariableDeclaration);
    }

    console.log(escodegen.generate(tree));
};

generator.modifyTree = modifyTree;
generator.instrument = instrument;

/*global exports:false*/
if (typeof exports !== 'undefined') {
    module.exports = generator;
}
<|endoftext|>


<commit_before>var CompositeDisposable, ProjectDropdown;
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
$ = jQuery = require('jquery');
CompositeDisposable = require('atom').CompositeDisposable;
module.exports = ProjectDropdown = {
    subscriptions: null,
    activate: function(state) {
        var scope = this;
        // Use window ready to identify when the tree view is loaded
        $(window).ready(function(){
            var $treeViewScroller = $('.tree-view-scroller'),
                $projectContainer = $('<div/>', {
                    'class': 'project-dropdown-container'
                }),
                $selectElement = $('<select/>', {
                    'class': 'project-dropdown-select',
                    'id': 'project-dropdown-select'
                }),
                $label = $('<label/>', {
                    'for': 'project-dropdown-select',
                    'text': 'Current Project:'
                });

            $projectContainer.prependTo($treeViewScroller);
            $label.appendTo($projectContainer);
            $selectElement.appendTo($projectContainer);

            scope.createOptions();

            $selectElement.on('change', function(){
                var $this = $(this),
                    $chosenOption = $selectElement.find(':selected');
                $('.tree-view-scroller .directory.project-root').hide();
                $('.tree-view-scroller .directory.project-root:eq(' + $chosenOption.data('index') + ')').show();
            });

            atom.project.onDidChangePaths(function(e){
                var lastItem = e.pop(),
                    projectName = lastItem.split('/').pop(),
                    $selectElement = $('select.project-dropdown-select');

                $('option', $selectElement).remove();

                scope.createOptions(projectName);
            });
        });
    },
    createOptions: function(selectSpecific) {
        $('.tree-view-scroller .directory.project-root').each(function(){
            var $this = $(this);
            $('<option/>', {
                'text': $('.header .name', $this).data('name'),
                'data-index': $this.index()
            }).appendTo($('select.project-dropdown-select'));
        });

        if(selectSpecific) {
            // Get the element of the new item
            var $newActive = $('span.name[data-name="' + selectSpecific + '"]').parents('li');
            // Hide all project roots
            $('.tree-view-scroller .directory.project-root').hide();
            // Show specific item
            $newActive.show();
            // Override the select to the new specific item
            $('select.project-dropdown-select').val(selectSpecific);
        }else{
            // Hide all project roots, show the first
            $('.tree-view-scroller .directory.project-root').hide().first().show();
        }
    },
    deactivate: function() {
        $('.project-dropdown-container').remove();
        $('.tree-view-scroller .directory.project-root').show();
    }
};
<commit_msg>Put projects in alphabetical order<commit_after>var CompositeDisposable, ProjectDropdown,
    __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
    $ = jQuery = require('jquery');

CompositeDisposable = require('atom').CompositeDisposable;

module.exports = ProjectDropdown = {
    subscriptions: null,
    activate: function(state) {
        var scope = this;
        // Use window ready to identify when the tree view is loaded
        $(window).ready(function(){
            var $treeViewScroller = $('.tree-view-scroller'),
                $projectContainer = $('<div/>', {
                    'class': 'project-dropdown-container'
                }),
                $selectElement = $('<select/>', {
                    'class': 'project-dropdown-select',
                    'id': 'project-dropdown-select'
                }),
                $label = $('<label/>', {
                    'for': 'project-dropdown-select',
                    'text': 'Current Project:'
                });

            $projectContainer.prependTo($treeViewScroller);
            $label.appendTo($projectContainer);
            $selectElement.appendTo($projectContainer);

            scope.createOptions();

            $selectElement.on('change', function(){
                var $this = $(this),
                    $chosenOption = $selectElement.find(':selected');
                $('.tree-view-scroller .directory.project-root').hide();
                $('.tree-view-scroller .directory.project-root:eq(' + $chosenOption.data('index') + ')').show();
            });

            atom.project.onDidChangePaths(function(e){
                var lastItem = e.pop(),
                    projectName = lastItem.split('/').pop(),
                    $selectElement = $('select.project-dropdown-select');

                $('option', $selectElement).remove();

                scope.createOptions(projectName);
            });
        });
    },
    createOptions: function(selectSpecific) {
        var $elements = [];

        $('.tree-view-scroller .directory.project-root').each(function(){
            var $this = $(this);
            var $option = $('<option/>', {
                'text': $('.header .name', $this).data('name'),
                'data-index': $this.index()
            });

            $elements.push($option);
        });

        // Re-organise the elements
        $elements.sort(function(a, b){
            // Convert values to uppercase to ensure fair sorting
            var textA = a[0].text.toUpperCase();
            var textB = b[0].text.toUpperCase();
            if(textA < textB) return -1;
            if(textA > textB) return 1;
            return 0;
        });

        // Loop through the elements and append them to the select box
        $.each($elements, function(index, value){
            value.appendTo($('select.project-dropdown-select'));
        });

        if(selectSpecific) {
            // Get the element of the new item
            var $newActive = $('span.name[data-name="' + selectSpecific + '"]').parents('li');
            // Hide all project roots
            $('.tree-view-scroller .directory.project-root').hide();
            // Show specific item
            $newActive.show();
            // Override the select to the new specific item
            $('select.project-dropdown-select').val(selectSpecific);
        }else{
            // Hide all project roots, show the first
            $('.tree-view-scroller .directory.project-root').hide().first().show();
        }
    },
    deactivate: function() {
        $('.project-dropdown-container').remove();
        $('.tree-view-scroller .directory.project-root').show();
    }
};
<|endoftext|>


<commit_before>function morse( string ){
	var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890@?.,- ";
	var morse = [".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----.", "-----", ".--.-.", "..--..", ".-.-.-", "--..--", "-....-", "   "]
	var newString = "";
	for(i = 0; i < string.length; i++){
		var index = chars.indexOf(string[i]);
		if (index != -1) {
			newString += morse[index] + " ";
		}
	}
	return newString;
}

anything.prototype.morse = morse;
<commit_msg>fix morse's indentation<commit_after>function morse( string ){
    var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890@?.,- ";
    var morse = [".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----.", "-----", ".--.-.", "..--..", ".-.-.-", "--..--", "-....-", "   "]
    var newString = "";
    for(i = 0; i < string.length; i++){
        var index = chars.indexOf(string[i]);
        if (index != -1) {
            newString += morse[index] + " ";
        }
    }
    return newString;
}

anything.prototype.morse = morse;
<|endoftext|>


<commit_before>var tab=[];
tab[4]=700;
document.write(tab.length+"
");
document.write("Premiere boucle
");
for (var i in tab){
    document.write("L'element "+i+" vaut
");
}<commit_msg>actually finish ex2<commit_after>var tab=[];

tab[4]=700;
document.write(tab.length+"
");

for(var j=0 ; j<2 ; j++){
    document.write("Premiere boucle
");
    for (var i in tab){
        document.write("L'element "+i+" vaut "+tab[i]+"
");
    }

    document.write("Deuxieme boucle
");
    for (var i=0 ; i<tab.length ; i++){
        document.write("L'element "+i+" vaut "+tab[i]+"
");
    }

    tab[2]=100;
    tab[6]=300;
}<|endoftext|>


<commit_before><commit_msg>HYD-988 use consistent series_end for culling data<commit_after><|endoftext|>


<commit_before>/*!
 * qwebs-nodemailer
 * Copyright(c) 2015 Benoît Claveau
 * MIT Licensed
 */
"use strict";

const nodemailer = require("nodemailer");
const signer = require("nodemailer-dkim").signer;
const smtpPool = require("nodemailer-smtp-pool");
const fs = require("fs");
const DataError = require("qwebs").DataError;

class MailerService {
    constructor($config) {
        if (!$config) throw new DataError({ message: "[MailerService] Qwebs config is not defined."});
        if (!$config.nodemailer) throw new DataError({ message: "Nodemailer section is not defined in qwebs config."});
        if (!$config.nodemailer.transport) throw new DataError({ message: "Nodemailer transport section is not defined in qwebs config."});
        if (!$config.nodemailer.dkim) throw new DataError({ message: "Nodemailer dkim section is not defined in qwebs config."});
        if (!$config.nodemailer.dkim.domainName) throw new DataError({ message: "Nodemailer dkim domainName is not defined in qwebs config."});
        if (!$config.nodemailer.dkim.keySelector) throw new DataError({ message: "Nodemailer dkim keySelector is not defined in qwebs config."});
        if (!$config.nodemailer.dkim.privateKey) throw new DataError({ message: "Nodemailer dkim privateKey is not defined in qwebs config."});

        this.$config = $config;

        let privateKey = fs.readFileSync($config.nodemailer.dkim.privateKey);

        this.transporter = nodemailer.createTransport(smtpPool($config.nodemailer.transport));
        this.transporter.use("stream", signer({
            domainName: $config.nodemailer.dkim.domainName,
            keySelector: $config.nodemailer.dkim.keySelector,
            privateKey: privateKey
        }));
    };

    send(mailOptions) {
        return Promise.resolve().then(() => {
            if (!mailOptions) throw new DataError({ message: "MailOptions are not defined."});

            if (!mailOptions.from) {
                if (!this.$config.nodemailer.from) throw new DataError({ message: "Nodemailer from is not defined in qwebs config."});
                mailOptions.from = this.$config.nodemailer.from;
            }

            if (this.$config.environment != "prod") {
                if (!this.$config.nodemailer.dev) throw new DataError({ message: "Nodemailer debug is not defined in qwebs config."});
                if (!this.$config.nodemailer.dev.to) throw new DataError({ message: "Nodemailer debug to is not defined in qwebs config."});

                mailOptions.to = this.$config.nodemailer.dev.to;
            }

            return new Promise((resolve, reject) => {
                this.transporter.sendMail(mailOptions, (err, data) => {
                    if (err) reject(err);
                    else resolve(data);
                });
            });
        });
    };
};

exports = module.exports = MailerService;<commit_msg>optional dkim config<commit_after>/*!
 * qwebs-nodemailer
 * Copyright(c) 2015 Benoît Claveau
 * MIT Licensed
 */
"use strict";

const nodemailer = require("nodemailer");
const signer = require("nodemailer-dkim").signer;
const smtpPool = require("nodemailer-smtp-pool");
const fs = require("fs");
const DataError = require("qwebs").DataError;

class MailerService {
    constructor($config) {
        if (!$config) throw new DataError({ message: "[MailerService] Qwebs config is not defined."});
        if (!$config.nodemailer) throw new DataError({ message: "Nodemailer section is not defined in qwebs config."});
        if (!$config.nodemailer.transport) throw new DataError({ message: "Nodemailer transport section is not defined in qwebs config."});

        this.$config = $config;
        this.transporter = nodemailer.createTransport(smtpPool($config.nodemailer.transport));

        if ($config.nodemailer.dkim) {
            if (!$config.nodemailer.dkim) throw new DataError({ message: "Nodemailer dkim section is not defined in qwebs config."});
            if (!$config.nodemailer.dkim.domainName) throw new DataError({ message: "Nodemailer dkim domainName is not defined in qwebs config."});
            if (!$config.nodemailer.dkim.keySelector) throw new DataError({ message: "Nodemailer dkim keySelector is not defined in qwebs config."});
            if (!$config.nodemailer.dkim.privateKey) throw new DataError({ message: "Nodemailer dkim privateKey is not defined in qwebs config."});

            let privateKey = fs.readFileSync($config.nodemailer.dkim.privateKey);

            this.transporter.use("stream", signer({
                domainName: $config.nodemailer.dkim.domainName,
                keySelector: $config.nodemailer.dkim.keySelector,
                privateKey: privateKey
            }));
        }
    };

    send(mailOptions) {
        return Promise.resolve().then(() => {
            if (!mailOptions) throw new DataError({ message: "MailOptions are not defined."});

            if (!mailOptions.from) {
                if (!this.$config.nodemailer.from) throw new DataError({ message: "Nodemailer from is not defined in qwebs config."});
                mailOptions.from = this.$config.nodemailer.from;
            }

            if (this.$config.environment != "prod") {
                if (!this.$config.nodemailer.dev) throw new DataError({ message: "Nodemailer debug is not defined in qwebs config."});
                if (!this.$config.nodemailer.dev.to) throw new DataError({ message: "Nodemailer debug to is not defined in qwebs config."});

                mailOptions.to = this.$config.nodemailer.dev.to;
            }

            return new Promise((resolve, reject) => {
                this.transporter.sendMail(mailOptions, (err, data) => {
                    if (err) reject(err);
                    else resolve(data);
                });
            });
        });
    };
};

exports = module.exports = MailerService;<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * TestFixture for SUID Sandbox testing.
 * @extends {testing.Test}
 * @constructor
 */
function SandboxStatusUITest() {}

SandboxStatusUITest.prototype = {
  __proto__: testing.Test.prototype,
  /**
   * Browse to the options page & call our preLoad().
   */
  browsePreload: 'chrome://sandbox',

};

// This test is for Linux only.
// PLEASE READ:
// - If failures of this test are a problem on a bot under your care,
//   the proper way to address such failures is to install the SUID
//   sandbox. See:
//     http://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment
// - PLEASE DO NOT GLOBALLY DISABLE THIS TEST.
// SUID sandbox is currently incompatible with AddressSanitizer,
// see http://crbug.com/137653.
GEN('#if defined(OS_LINUX) && !defined(ADDRESS_SANITIZER)');
GEN('# define MAYBE_testSUIDSandboxEnabled \\');
GEN('     testSUIDSandboxEnabled');
GEN('#else');
GEN('# define MAYBE_testSUIDSandboxEnabled \\');
GEN('     DISABLED_testSUIDSandboxEnabled');
GEN('#endif');

/**
 * Test if the SUID sandbox is enabled.
 */
TEST_F('SandboxStatusUITest', 'MAYBE_testSUIDSandboxEnabled', function() {
    var suidyesstring = 'SUID Sandbox\tYes';
    var suidnostring = 'SUID Sandbox\tNo';
    var suidyes = document.body.innerText.match(suidyesstring);
    var suidno = document.body.innerText.match(suidnostring);

    expectEquals(null, suidno);
    assertFalse(suidyes === null);
    expectEquals(suidyesstring, suidyes[0]);
});

// The seccomp-bpf sandbox is also not compatible with ASAN.
GEN('#if defined(OS_LINUX) && !defined(ADDRESS_SANITIZER)');
GEN('# define MAYBE_testBPFSandboxEnabled \\');
GEN('     testBPFSandboxEnabled');
GEN('#else');
GEN('# define MAYBE_testBPFSandboxEnabled \\');
GEN('     DISABLED_testBPFSandboxEnabled');
GEN('#endif');

/**
 * Test if the seccomp-bpf sandbox is enabled.
 */
TEST_F('SandboxStatusUITest', 'MAYBE_testBPFSandboxEnabled', function() {
    var bpfyesstring = 'Seccomp-BPF sandbox\tYes';
    var bpfnostring = 'Seccomp-BPF sandbox\tNo';
    var bpfyes = document.body.innerText.match(bpfyesstring);
    var bpfno = document.body.innerText.match(bpfnostring);

    expectEquals(null, bpfno);
    assertFalse(bpfyes === null);
    expectEquals(bpfyesstring, bpfyes[0]);
});
<commit_msg>Disable testBPFSandboxEnabled on ARM linux<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * TestFixture for SUID Sandbox testing.
 * @extends {testing.Test}
 * @constructor
 */
function SandboxStatusUITest() {}

SandboxStatusUITest.prototype = {
  __proto__: testing.Test.prototype,
  /**
   * Browse to the options page & call our preLoad().
   */
  browsePreload: 'chrome://sandbox',

};

// This test is for Linux only.
// PLEASE READ:
// - If failures of this test are a problem on a bot under your care,
//   the proper way to address such failures is to install the SUID
//   sandbox. See:
//     http://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment
// - PLEASE DO NOT GLOBALLY DISABLE THIS TEST.
// SUID sandbox is currently incompatible with AddressSanitizer,
// see http://crbug.com/137653.
GEN('#if defined(OS_LINUX) && !defined(ADDRESS_SANITIZER)');
GEN('# define MAYBE_testSUIDSandboxEnabled \\');
GEN('     testSUIDSandboxEnabled');
GEN('#else');
GEN('# define MAYBE_testSUIDSandboxEnabled \\');
GEN('     DISABLED_testSUIDSandboxEnabled');
GEN('#endif');

/**
 * Test if the SUID sandbox is enabled.
 */
TEST_F('SandboxStatusUITest', 'MAYBE_testSUIDSandboxEnabled', function() {
    var suidyesstring = 'SUID Sandbox\tYes';
    var suidnostring = 'SUID Sandbox\tNo';
    var suidyes = document.body.innerText.match(suidyesstring);
    var suidno = document.body.innerText.match(suidnostring);

    expectEquals(null, suidno);
    assertFalse(suidyes === null);
    expectEquals(suidyesstring, suidyes[0]);
});

// The seccomp-bpf sandbox is also not compatible with ASAN.
GEN('#if !defined(OS_LINUX) || defined(ADDRESS_SANITIZER)');
GEN('# define MAYBE_testBPFSandboxEnabled \\');
GEN('     DISABLED_testBPFSandboxEnabled');
GEN('#elif !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)');
// Not yet available on the ARM linux bots: http://crbug.com/243478
GEN('# define MAYBE_testBPFSandboxEnabled \\');
GEN('     DISABLED_testBPFSandboxEnabled');
GEN('#else');
GEN('# define MAYBE_testBPFSandboxEnabled \\');
GEN('     testBPFSandboxEnabled');
GEN('#endif');

/**
 * Test if the seccomp-bpf sandbox is enabled.
 */
TEST_F('SandboxStatusUITest', 'MAYBE_testBPFSandboxEnabled', function() {
    var bpfyesstring = 'Seccomp-BPF sandbox\tYes';
    var bpfnostring = 'Seccomp-BPF sandbox\tNo';
    var bpfyes = document.body.innerText.match(bpfyesstring);
    var bpfno = document.body.innerText.match(bpfnostring);

    expectEquals(null, bpfno);
    assertFalse(bpfyes === null);
    expectEquals(bpfyesstring, bpfyes[0]);
});
<|endoftext|>


<commit_before>import React, { PropTypes, Component } from 'react'
import * as d3 from 'd3'
import ReactFauxDOM from 'react-faux-dom'
import { connect } from 'react-redux'

class BarChart extends Component {
  constructor(props) {
    super(props)
    this.state = {
      chart: null
    }
  }

  componentDidMount() {
    this.buildChart(this.props.pollData)
  }

  buildChart({ entries }) {
    let pollEntries = entries
    const that = this
    const fauxDOM = ReactFauxDOM.createElement('div')
    const padding = { left: 30, top: 10, right: 10, bottom: 20 }
    const chartWidth = (600 - (padding.left + padding.right))
    const chartHeight = (400 - (padding.top + padding.bottom))

    const xScale = d3.scaleBand()
        .rangeRound([0, chartWidth])
        .domain(pollEntries.map(entry => entry.title))
        .paddingOuter(0.05)
        .padding(0.05)

    const yScale = d3.scaleLinear()
        .range([chartHeight, 0])
        .domain(getYScaleDomain())

    const colorScale = d3.scaleOrdinal(d3.schemeCategory10)
        .domain([0, pollEntries.length])

    const xAxis = d3.axisBottom(xScale)
    const yAxis = d3.axisLeft(yScale)

    let chart = d3.select(fauxDOM).append('svg')
        .attr('width', (chartWidth + padding.left + padding.right))
        .attr('height', (chartHeight + padding.top + padding.bottom))
        .style('background-color', 'purple')

    // console.log('computed styles:', fauxDOM.getComputedStyle(chart))
    // console.log('xyz:', fauxDOM)
    // console.log('fuck width:', d3.select(fauxDOM).node().getBoundingClientRect().width)

    chart = chart.append('g')
        .classed('inner-chart', true)
        .attr('transform', `translate(${padding.left}, ${padding.top})`)
        .attr('width', chartWidth)
        .attr('height', chartHeight)

    const bars = chart.selectAll('rect')
        .data(pollEntries).enter()
      .append('rect')
        .attr('fill', (entry) => colorScale(entry.originalEntryIndex))
        .attr('width', xScale.bandwidth())
        .attr('height', getBarHeight)
        .attr('x', entry => xScale(entry.title))
        .attr('y', entry => yScale(entry.votes.length))
        .on('click', callOnBarClickEvent)

    const xAxisElement = chart.append('g')
        .classed('x axis', true)
        .attr('transform', `translate(0, ${chartHeight})`)
        .attr('shape-rendering', 'crispEdges')
        .call(xAxis)

    const yAxisElement = chart.append('g')
        .classed('y axis', true)
        .attr('transform', 'translate(0, 0)')
        .attr('shape-rendering', 'crispEdges')
        .call(yAxis)

    function getYScaleDomain() {
      const lowestVotedBar = d3.min(pollEntries, entry => entry.votes.length)
      const heighestVotedBar = d3.max(pollEntries, entry => entry.votes.length)
      return [
        lowestVotedBar > 0 ? 0 : -1,
        heighestVotedBar > 0 ? heighestVotedBar : 1
      ]
    }

    function getBarHeight(entry) {
      return chartHeight - yScale(entry.votes.length)
    }

    function callOnBarClickEvent(bar) {
      const eventCallback = that.props.barClickedEvent
      if (eventCallback) {
        eventCallback(bar, updateVotedOnBars.bind(this))
      }
    }

    function updateVotedOnBars() {
      pollEntries = that.props.pollData.entries
      const transitionDuration = 500

      xScale.domain(pollEntries.map(entry => entry.title))
      yScale.domain(getYScaleDomain())

      let counter = 0

      bars
          .data(that.props.pollData.entries)
          .transition()
          .duration(transitionDuration)
          .attr('fill', entry => colorScale(entry.originalEntryIndex))
          .attr('height', entry => chartHeight - yScale(entry.votes.length))
          .attr('x', entry => xScale(entry.title))
          .attr('y', entry => yScale(entry.votes.length))
          .ease(frame => {
            // this is a hack so the chart gets updated every time the first entry gets updated
            // beginning of hack
            counter++
            if (counter >= entries.length) {
              counter = 0
              that.updateChartState(fauxDOM)
            }
            // end of hack
            return ease(frame)
          })
          .on('end', () => {
            // call the x and y axis elements to make the text crisp again
            xAxisElement.call(xAxis)
            yAxisElement.call(yAxis)

            that.updateChartState(fauxDOM)
          })

      xAxisElement
          .transition()
          .duration(transitionDuration)
          .ease(ease)
          .call(xAxis)

      yAxisElement
          .transition()
          .duration(transitionDuration)
          .ease(ease)
          .call(yAxis)

      function ease(frame) {
        /* make these in the options when setting up the chart */
        // return d3.easeBounceInOut(frame)
        // return d3.easeCubicInOut(frame)
        return d3.easeExpOut(frame)
      }
    }

    this.updateChartState(fauxDOM)

    if (that.props.setTriggerUpdate) {
      that.props.setTriggerUpdate(() => {
        this.buildChart(this.props.pollData)
      })
    }
  }

  updateChartState(fauxDOM) {
    this.setState({ chart: fauxDOM.toReact() })
  }

  render() {
    return
{this.state.chart}

  }
}

BarChart.propTypes = {
  pollData: PropTypes.shape({
    title: PropTypes.string.isRequired,
    author: PropTypes.string.isRequired,
    authorID: PropTypes.string.isRequired,
    sortOrder: PropTypes.string.isRequired,
    entries: PropTypes.array.isRequired,
    cuid: PropTypes.string.isRequired,
    dateCreated: PropTypes.number.isRequired
  }),
  dispatch: PropTypes.func.isRequired,
  barClickedEvent: PropTypes.func,
  setTriggerUpdate: PropTypes.func
}

export default connect()(BarChart)
<commit_msg>stil trying to get Element.getBoundingClientRect() to work on the ReactFauxDOM and svg bar chart<commit_after>import React, { PropTypes, Component } from 'react'
import * as d3 from 'd3'
import ReactFauxDOM from 'react-faux-dom'
import { connect } from 'react-redux'

class BarChart extends Component {
  constructor(props) {
    super(props)
    this.state = {
      chart: '...loading'
    }
  }

  componentDidMount() {
    this.buildChart(this.props.pollData)
  }

  buildChart({ entries }) {
    let pollEntries = entries
    const that = this
    const fauxDOM = ReactFauxDOM.createElement('div')
    const padding = { left: 30, top: 10, right: 10, bottom: 20 }
    const chartWidth = (600 - (padding.left + padding.right))
    const chartHeight = (400 - (padding.top + padding.bottom))

    const xScale = d3.scaleBand()
        .rangeRound([0, chartWidth])
        .domain(pollEntries.map(entry => entry.title))
        .paddingOuter(0.05)
        .padding(0.05)

    const yScale = d3.scaleLinear()
        .range([chartHeight, 0])
        .domain(getYScaleDomain())

    const colorScale = d3.scaleOrdinal(d3.schemeCategory10)
        .domain([0, pollEntries.length])

    const xAxis = d3.axisBottom(xScale)
    const yAxis = d3.axisLeft(yScale)

    let chart = d3.select(fauxDOM).append('svg')
        .attr('width', (chartWidth + padding.left + padding.right))
        .attr('height', (chartHeight + padding.top + padding.bottom))
        .style('background-color', 'white')

    fauxDOM.appendChild(ReactFauxDOM.createElement('div'))
    console.log(new ReactFauxDOM.Element('div').getBoundingClientRect())
    return

    chart = chart.append('g')
        .classed('inner-chart', true)
        .attr('transform', `translate(${padding.left}, ${padding.top})`)
        .attr('width', chartWidth)
        .attr('height', chartHeight)

    const bars = chart.selectAll('rect')
        .data(pollEntries).enter()
      .append('rect')
        .attr('fill', (entry) => colorScale(entry.originalEntryIndex))
        .attr('width', xScale.bandwidth())
        .attr('height', getBarHeight)
        .attr('x', entry => xScale(entry.title))
        .attr('y', entry => yScale(entry.votes.length))
        .on('click', callOnBarClickEvent)

    const xAxisElement = chart.append('g')
        .classed('x axis', true)
        .attr('transform', `translate(0, ${chartHeight})`)
        .attr('shape-rendering', 'crispEdges')
        .call(xAxis)

    const yAxisElement = chart.append('g')
        .classed('y axis', true)
        .attr('transform', 'translate(0, 0)')
        .attr('shape-rendering', 'crispEdges')
        .call(yAxis)

    function getYScaleDomain() {
      const lowestVotedBar = d3.min(pollEntries, entry => entry.votes.length)
      const heighestVotedBar = d3.max(pollEntries, entry => entry.votes.length)
      return [
        lowestVotedBar > 0 ? 0 : -1,
        heighestVotedBar > 0 ? heighestVotedBar : 1
      ]
    }

    function getBarHeight(entry) {
      return chartHeight - yScale(entry.votes.length)
    }

    function callOnBarClickEvent(bar) {
      const eventCallback = that.props.barClickedEvent
      if (eventCallback) {
        eventCallback(bar, updateVotedOnBars.bind(this))
      }
    }

    function updateVotedOnBars() {
      pollEntries = that.props.pollData.entries
      const transitionDuration = 500

      xScale.domain(pollEntries.map(entry => entry.title))
      yScale.domain(getYScaleDomain())

      let counter = 0

      bars
          .data(that.props.pollData.entries)
          .transition()
          .duration(transitionDuration)
          .attr('fill', entry => colorScale(entry.originalEntryIndex))
          .attr('height', entry => chartHeight - yScale(entry.votes.length))
          .attr('x', entry => xScale(entry.title))
          .attr('y', entry => yScale(entry.votes.length))
          .ease(frame => {
            // this is a hack so the chart gets updated every time the first entry gets updated
            // beginning of hack
            counter++
            if (counter >= entries.length) {
              counter = 0
              that.updateChartState(fauxDOM)
            }
            // end of hack
            return ease(frame)
          })
          .on('end', () => {
            // call the x and y axis elements to make the text crisp again
            xAxisElement.call(xAxis)
            yAxisElement.call(yAxis)

            that.updateChartState(fauxDOM)
          })

      xAxisElement
          .transition()
          .duration(transitionDuration)
          .ease(ease)
          .call(xAxis)

      yAxisElement
          .transition()
          .duration(transitionDuration)
          .ease(ease)
          .call(yAxis)

      function ease(frame) {
        /* make these in the options when setting up the chart */
        // return d3.easeBounceInOut(frame)
        // return d3.easeCubicInOut(frame)
        return d3.easeExpOut(frame)
      }
    }

    this.updateChartState(fauxDOM)

    if (that.props.setTriggerUpdate) {
      that.props.setTriggerUpdate(() => {
        this.buildChart(this.props.pollData)
      })
    }
  }

  updateChartState(fauxDOM) {
    this.setState({ chart: fauxDOM.toReact() })
  }

  render() {
    return
{this.state.chart}

  }
}

BarChart.propTypes = {
  pollData: PropTypes.shape({
    title: PropTypes.string.isRequired,
    author: PropTypes.string.isRequired,
    authorID: PropTypes.string.isRequired,
    sortOrder: PropTypes.string.isRequired,
    entries: PropTypes.array.isRequired,
    cuid: PropTypes.string.isRequired,
    dateCreated: PropTypes.number.isRequired
  }),
  dispatch: PropTypes.func.isRequired,
  barClickedEvent: PropTypes.func,
  setTriggerUpdate: PropTypes.func
}

export default connect()(BarChart)
<|endoftext|>


<commit_before>// Copyright 2011 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Interface for storing, retieving and scanning data using some
 * persistence mechanism.
 *
 */

goog.provide('goog.storage.mechanism.IterableMechanism');

goog.require('goog.array');
goog.require('goog.asserts');
goog.require('goog.iter');
goog.require('goog.storage.mechanism.Mechanism');

/**
 * Interface for all iterable storage mechanisms.
 *
 * @constructor
 * @struct
 * @extends {goog.storage.mechanism.Mechanism}
 */
goog.storage.mechanism.IterableMechanism = function() {
  goog.storage.mechanism.IterableMechanism.base(this, 'constructor');
};
goog.inherits(
    goog.storage.mechanism.IterableMechanism, goog.storage.mechanism.Mechanism);

/**
 * Get the number of stored key-value pairs.
 *
 * Could be overridden in a subclass, as the default implementation is not very
 * efficient - it iterates over all keys.
 *
 * @return {number} Number of stored elements.
 */
goog.storage.mechanism.IterableMechanism.prototype.getCount = function() {
  var count = 0;
  goog.iter.forEach(this.__iterator__(true), function(key) {
    goog.asserts.assertString(key);
    count++;
  });
  return count;
};

/**
 * Returns an iterator that iterates over the elements in the storage. Will
 * throw goog.iter.StopIteration after the last element.
 *
 * @param {boolean=} opt_keys True to iterate over the keys. False to iterate
 *     over the values.  The default value is false.
 * @return {!goog.iter.Iterator} The iterator.
 */
goog.storage.mechanism.IterableMechanism.prototype.__iterator__ =
    goog.abstractMethod;

/**
 * Remove all key-value pairs.
 *
 * Could be overridden in a subclass, as the default implementation is not very
 * efficient - it iterates over all keys.
 */
goog.storage.mechanism.IterableMechanism.prototype.clear = function() {
  var keys = goog.iter.toArray(this.__iterator__(true));
  var selfObj = this;
  goog.array.forEach(keys, function(key) { selfObj.remove(key); });
};
<commit_msg>Add comment to warn future users not to change the serialization to array of keys first before removing.<commit_after>// Copyright 2011 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Interface for storing, retieving and scanning data using some
 * persistence mechanism.
 *
 */

goog.provide('goog.storage.mechanism.IterableMechanism');

goog.require('goog.array');
goog.require('goog.asserts');
goog.require('goog.iter');
goog.require('goog.storage.mechanism.Mechanism');

/**
 * Interface for all iterable storage mechanisms.
 *
 * @constructor
 * @struct
 * @extends {goog.storage.mechanism.Mechanism}
 */
goog.storage.mechanism.IterableMechanism = function() {
  goog.storage.mechanism.IterableMechanism.base(this, 'constructor');
};
goog.inherits(
    goog.storage.mechanism.IterableMechanism, goog.storage.mechanism.Mechanism);

/**
 * Get the number of stored key-value pairs.
 *
 * Could be overridden in a subclass, as the default implementation is not very
 * efficient - it iterates over all keys.
 *
 * @return {number} Number of stored elements.
 */
goog.storage.mechanism.IterableMechanism.prototype.getCount = function() {
  var count = 0;
  goog.iter.forEach(this.__iterator__(true), function(key) {
    goog.asserts.assertString(key);
    count++;
  });
  return count;
};

/**
 * Returns an iterator that iterates over the elements in the storage. Will
 * throw goog.iter.StopIteration after the last element.
 *
 * @param {boolean=} opt_keys True to iterate over the keys. False to iterate
 *     over the values.  The default value is false.
 * @return {!goog.iter.Iterator} The iterator.
 */
goog.storage.mechanism.IterableMechanism.prototype.__iterator__ =
    goog.abstractMethod;

/**
 * Remove all key-value pairs.
 *
 * Could be overridden in a subclass, as the default implementation is not very
 * efficient - it iterates over all keys.
 */
goog.storage.mechanism.IterableMechanism.prototype.clear = function() {
  // This converts the keys to an array first because otherwise
  // removing while iterating results in unstable ordering of keys and
  // can skip keys or terminate early.
  var keys = goog.iter.toArray(this.__iterator__(true));
  var selfObj = this;
  goog.array.forEach(keys, function(key) { selfObj.remove(key); });
};
<|endoftext|>


<commit_before>/*jshint -W058 */

import { FIELDS as CARD_FIELDS } from './token';
import each from 'component-each';
import find from 'component-find';
import { parseCard } from '../util/parse-card';

const debug = require('debug')('recurly:validate');

/**
 * Card patterns.
 *
 * @private
 */
const TYPES = [
  {
    type: 'discover',
    pattern: {
      test: (n) => {
        let firstEight = parseInt(n.substr(0, 8), 10);
        let accepted_ranges = [
          [60110000,60110399],
          [60110500,60110999],
          [60112000,60114999],
          [60117400,60117499],
          [60117700,60117999],
          [60118600,60119999],
          [64400000,65059999],
          [65060100,65060999],
          [65061100,65999999]
        ];

        return accepted_ranges.indexOf(([minimum, maximum]) => firstEight >= minimum && firstEight <= maximum) !== undefined;
      }
    },
    lengths: [16, 17, 18, 19]
  },
  {
    type: 'master',
    pattern: {
      test: (n) => {
        let firstSix = parseInt(n.substr(0, 6), 10);
        if (/^5[1-5]/.test(n)) return true;
        if (firstSix >= 222100 && firstSix <= 272099) return true;
        return false;
      }
    },
    lengths: [16]
  },
  {
    type: 'american_express',
    pattern: /^3[47]/,
    lengths: [15]
  },
  {
    type: 'visa',
    pattern: /^4/,
    lengths: [13, 16]
  },
  {
    type: 'jcb',
    pattern: /^35[2-8]\d/,
    lengths: [16]
  },
  {
    type: 'diners_club',
    pattern: /^(30[0-5]|309|36|3[89]|54|55|2014|2149)/,
    lengths: [14]
  }
];

/**
 * Validation error messages
 * @type {String}
 * @private
 */
const INVALID = 'is invalid';
const BLANK = "can't be blank";
const DOES_NOT_MATCH = 'does not match';

/**
 * Fields required by bank account tokenization
 * @type {Array}
 */
const BANK_ACCOUNT_REQUIRED_FIELDS = [
  'account_number',
  'account_number_confirmation',
  'routing_number',
  'account_type',
  'name_on_account',
  'country'
];

/**
 * Fields required by IBAN bank account tokenization
 * @type {Array}
 */
const IBAN_BANK_ACCOUNT_REQUIRED_FIELDS = [
  'iban',
  'name_on_account',
];

export const publicMethods = { cardNumber, cardType, expiry, cvv };

/**
 * Validates a credit card number via length check and luhn algorithm.
 *
 * @param {Number|String} number The card number.
 * @return {Boolean}
 * @see https://sites.google.com/site/abapexamples/javascript/luhn-validation
 */

export function cardNumber (number) {
  const str = parseCard(number);
  let ca, sum = 0, mul = 1;
  let i = str.length;

  if (i < 12 || i > 19) return false;

  while (i--) {
    ca = parseInt(str.charAt(i), 10) * mul;
    sum += ca - (ca > 9) * 9;
    mul ^= 3;
  }

  return sum % 10 === 0 && sum > 0;
}

/**
 * Returns the type of the card number as a string.
 *
 * @param {Number|String} number The card number
 * @param {Boolean} partial detect card type on a partial (incomplete) number
 * @return {String} card type
 */

export function cardType (number, partial = false) {
  const str = parseCard(number);
  const len = str.length;
  const card = find(TYPES, card => card.pattern.test(str) && (partial || ~card.lengths.indexOf(len)));
  return card && card.type || 'unknown';
}

/**
 * Validates whether an expiry month is present or future.
 *
 * @param {Numer|String} month The 2 digit month
 * @param {Numer|String} year The 2 or 4 digit year
 * @return {Boolean}
 */

export function expiry (month, year) {
  month = Number(month) - 1;
  if (month < 0 || month > 11) return false;
  year = Number(year);
  year += year < 100 ? 2000 : 0;

  let expiry = new Date;
  expiry.setYear(year);
  expiry.setDate(1);
  expiry.setHours(0);
  expiry.setMinutes(0);
  expiry.setSeconds(0);
  expiry.setMonth(month + 1);
  return new Date < expiry;
}

/**
 * Validates whether a number looks like a cvv.
 *
 * e.g.: '123', '0321'
 *
 * @param {Number|String} number The card verification value
 * @return {Boolean}
 */

export function cvv (number) {
  number = String(number).trim();
  if (!~[3, 4].indexOf(number.length)) return false;
  return /^\d+$/.test(number);
}

/**
 * Checks user input on a card token call
 *
 * @param {Recurly} recurly
 * @param {Object} inputs
 * @return {Array} formatted array of invalid fields with descriptive messages
 */
export function validateCardInputs (recurly, inputs) {
  const format = formatFieldValidationError;
  let errors = [];

  if (!cardNumber(inputs.number)) {
    errors.push(format('number', INVALID));
  }

  if (!expiry(inputs.month, inputs.year)) {
    errors.push(format('month', INVALID), format('year', INVALID));
  }

  if (!inputs.first_name) {
    errors.push(format('first_name', BLANK));
  }

  if (!inputs.last_name) {
    errors.push(format('last_name', BLANK));
  }

  if (~recurly.config.required.indexOf('cvv') && !inputs.cvv) {
    errors.push(format('cvv', BLANK));
  } else if ((~recurly.config.required.indexOf('cvv') || inputs.cvv) && !cvv(inputs.cvv)) {
    errors.push(format('cvv', INVALID));
  }

  each(recurly.config.required, function (field) {
    if (!inputs[field] && ~CARD_FIELDS.indexOf(field)) {
      errors.push(format(field, BLANK));
    }
  });

  debug('validate errors', errors);

  return errors;
}

/**
 * Checks user input on a bank account token call
 *
 * @param {Object} inputs
 * @return {Array} formatted array of invalid fields with descriptive messages
 */
export function validateBankAccountInputs (inputs) {
  const format = formatFieldValidationError;
  let required = [];
  let errors = [];

  if ('iban' in inputs) {
    required = IBAN_BANK_ACCOUNT_REQUIRED_FIELDS;
  } else {
    required = BANK_ACCOUNT_REQUIRED_FIELDS;

    if (inputs.account_number !== inputs.account_number_confirmation) {
      errors.push(format('account_number_confirmation', DOES_NOT_MATCH));
    }
  }

  required.forEach(name => {
    if (!inputs[name]) {
      errors.push(format(name, BLANK));
    } else if (typeof inputs[name] !== 'string') {
      errors.push(format(name, INVALID));
    }
  });

  debug('bank account validate errors', errors);

  return errors;
}

/**
 * Validates a bank account routing number
 * @param  {[type]} routingNumber
 * @return {Array} formatted array of invalid fields with descriptive messages
 */
export function validateBankRoutingNumber (routingNumber) {
  let errors = [];

  if (!routingNumber) {
    errors.push(formatFieldValidationError('routing_number', BLANK));
  } else if (typeof routingNumber !== 'string') {
    errors.push(formatFieldValidationError('routing_number', INVALID));
  }

  debug('validate errors', errors);

  return errors;
}

/**
 * Formats a field validation error
 *
 * @param {string} field
 * @param {String} message
 * @return {Object}
 */
function formatFieldValidationError (field, message) {
  return { field, messages: [message] };
}
<commit_msg>Verify first 4 of BIN...<commit_after>/*jshint -W058 */

import { FIELDS as CARD_FIELDS } from './token';
import each from 'component-each';
import find from 'component-find';
import { parseCard } from '../util/parse-card';

const debug = require('debug')('recurly:validate');

/**
 * Card patterns.
 *
 * @private
 */
const TYPES = [
  {
    type: 'discover',
    pattern: {
      test: (n) => {
        let firstEight = parseInt(n.substr(0, 8), 10);
        let accepted_ranges = [
          [60110000,60110399],
          [60110500,60110999],
          [60112000,60114999],
          [60117400,60117499],
          [60117700,60117999],
          [60118600,60119999],
          [64400000,65059999],
          [65060100,65060999],
          [65061100,65999999]
        ];

        if (!(/^6[045]/.test(firstEight))) return false;
        return accepted_ranges.indexOf(([minimum, maximum]) => firstEight >= minimum && firstEight <= maximum) !== undefined;
      }
    },
    lengths: [16, 17, 18, 19]
  },
  {
    type: 'master',
    pattern: {
      test: (n) => {
        let firstSix = parseInt(n.substr(0, 6), 10);
        if (/^5[1-5]/.test(n)) return true;
        if (firstSix >= 222100 && firstSix <= 272099) return true;
        return false;
      }
    },
    lengths: [16]
  },
  {
    type: 'american_express',
    pattern: /^3[47]/,
    lengths: [15]
  },
  {
    type: 'visa',
    pattern: /^4/,
    lengths: [13, 16]
  },
  {
    type: 'jcb',
    pattern: /^35[2-8]\d/,
    lengths: [16]
  },
  {
    type: 'diners_club',
    pattern: /^(30[0-5]|309|36|3[89]|54|55|2014|2149)/,
    lengths: [14]
  }
];

/**
 * Validation error messages
 * @type {String}
 * @private
 */
const INVALID = 'is invalid';
const BLANK = "can't be blank";
const DOES_NOT_MATCH = 'does not match';

/**
 * Fields required by bank account tokenization
 * @type {Array}
 */
const BANK_ACCOUNT_REQUIRED_FIELDS = [
  'account_number',
  'account_number_confirmation',
  'routing_number',
  'account_type',
  'name_on_account',
  'country'
];

/**
 * Fields required by IBAN bank account tokenization
 * @type {Array}
 */
const IBAN_BANK_ACCOUNT_REQUIRED_FIELDS = [
  'iban',
  'name_on_account',
];

export const publicMethods = { cardNumber, cardType, expiry, cvv };

/**
 * Validates a credit card number via length check and luhn algorithm.
 *
 * @param {Number|String} number The card number.
 * @return {Boolean}
 * @see https://sites.google.com/site/abapexamples/javascript/luhn-validation
 */

export function cardNumber (number) {
  const str = parseCard(number);
  let ca, sum = 0, mul = 1;
  let i = str.length;

  if (i < 12 || i > 19) return false;

  while (i--) {
    ca = parseInt(str.charAt(i), 10) * mul;
    sum += ca - (ca > 9) * 9;
    mul ^= 3;
  }

  return sum % 10 === 0 && sum > 0;
}

/**
 * Returns the type of the card number as a string.
 *
 * @param {Number|String} number The card number
 * @param {Boolean} partial detect card type on a partial (incomplete) number
 * @return {String} card type
 */

export function cardType (number, partial = false) {
  const str = parseCard(number);
  const len = str.length;
  const card = find(TYPES, card => card.pattern.test(str) && (partial || ~card.lengths.indexOf(len)));
  return card && card.type || 'unknown';
}

/**
 * Validates whether an expiry month is present or future.
 *
 * @param {Numer|String} month The 2 digit month
 * @param {Numer|String} year The 2 or 4 digit year
 * @return {Boolean}
 */

export function expiry (month, year) {
  month = Number(month) - 1;
  if (month < 0 || month > 11) return false;
  year = Number(year);
  year += year < 100 ? 2000 : 0;

  let expiry = new Date;
  expiry.setYear(year);
  expiry.setDate(1);
  expiry.setHours(0);
  expiry.setMinutes(0);
  expiry.setSeconds(0);
  expiry.setMonth(month + 1);
  return new Date < expiry;
}

/**
 * Validates whether a number looks like a cvv.
 *
 * e.g.: '123', '0321'
 *
 * @param {Number|String} number The card verification value
 * @return {Boolean}
 */

export function cvv (number) {
  number = String(number).trim();
  if (!~[3, 4].indexOf(number.length)) return false;
  return /^\d+$/.test(number);
}

/**
 * Checks user input on a card token call
 *
 * @param {Recurly} recurly
 * @param {Object} inputs
 * @return {Array} formatted array of invalid fields with descriptive messages
 */
export function validateCardInputs (recurly, inputs) {
  const format = formatFieldValidationError;
  let errors = [];

  if (!cardNumber(inputs.number)) {
    errors.push(format('number', INVALID));
  }

  if (!expiry(inputs.month, inputs.year)) {
    errors.push(format('month', INVALID), format('year', INVALID));
  }

  if (!inputs.first_name) {
    errors.push(format('first_name', BLANK));
  }

  if (!inputs.last_name) {
    errors.push(format('last_name', BLANK));
  }

  if (~recurly.config.required.indexOf('cvv') && !inputs.cvv) {
    errors.push(format('cvv', BLANK));
  } else if ((~recurly.config.required.indexOf('cvv') || inputs.cvv) && !cvv(inputs.cvv)) {
    errors.push(format('cvv', INVALID));
  }

  each(recurly.config.required, function (field) {
    if (!inputs[field] && ~CARD_FIELDS.indexOf(field)) {
      errors.push(format(field, BLANK));
    }
  });

  debug('validate errors', errors);

  return errors;
}

/**
 * Checks user input on a bank account token call
 *
 * @param {Object} inputs
 * @return {Array} formatted array of invalid fields with descriptive messages
 */
export function validateBankAccountInputs (inputs) {
  const format = formatFieldValidationError;
  let required = [];
  let errors = [];

  if ('iban' in inputs) {
    required = IBAN_BANK_ACCOUNT_REQUIRED_FIELDS;
  } else {
    required = BANK_ACCOUNT_REQUIRED_FIELDS;

    if (inputs.account_number !== inputs.account_number_confirmation) {
      errors.push(format('account_number_confirmation', DOES_NOT_MATCH));
    }
  }

  required.forEach(name => {
    if (!inputs[name]) {
      errors.push(format(name, BLANK));
    } else if (typeof inputs[name] !== 'string') {
      errors.push(format(name, INVALID));
    }
  });

  debug('bank account validate errors', errors);

  return errors;
}

/**
 * Validates a bank account routing number
 * @param  {[type]} routingNumber
 * @return {Array} formatted array of invalid fields with descriptive messages
 */
export function validateBankRoutingNumber (routingNumber) {
  let errors = [];

  if (!routingNumber) {
    errors.push(formatFieldValidationError('routing_number', BLANK));
  } else if (typeof routingNumber !== 'string') {
    errors.push(formatFieldValidationError('routing_number', INVALID));
  }

  debug('validate errors', errors);

  return errors;
}

/**
 * Formats a field validation error
 *
 * @param {string} field
 * @param {String} message
 * @return {Object}
 */
function formatFieldValidationError (field, message) {
  return { field, messages: [message] };
}
<|endoftext|>


<commit_before>Occasion.Modules.push(function(library) {
  library.Order = class Order extends library.Base {
    static construct(attributes) {
      var order = this.includes('currency').build(attributes);

      order.sessionIdentifier = order.sessionIdentifier ||
        Math.random().toString(36).substring(7) + '-' + Date.now();

      if(order.customer() == null) {
        order.buildCustomer({
          email: null,
          firstName: null,
          lastName: null,
          zip: null
        });
      }

      var promises = [new Promise(function(resolve) {
        resolve(order);
      })];

      if(order.product() != null) {
        promises.push(order.product().questions().includes('options').perPage(500).load());

        if(!order.product().requiresTimeSlotSelection) {
          promises.push(
            order.product().timeSlots()
            .includes({ product: 'merchant' })
            .where({ status: 'bookable' })
            .perPage(500).all()
          );
        }
      }

      var _this = this;
      return Promise.all(promises)
      .then(function(args) {
        order = args[0];
        var questions = args[1];
        var timeSlots = args[2];

        if(questions != undefined) questions.inject(order, _this.__constructAnswer);
        if(timeSlots != undefined) order.timeSlots().assign(timeSlots, false);

        return order;
      });
    }

    // POSTs the order to `/orders/price`, which calculates price related fields and adds them to the order
    // @return [Promise] a promise for the order with price-related fields
    calculatePrice() {
      return this.interface().post(this.klass().links()['related'] + 'price', this);
    }

    // POSTs the order to `/orders/information`, which calculates price + quantity related fields and adds them to the
    //   order
    // @return [Promise] a promise for the order with price & quantity related fields
    retrieveInformation() {
      return this.interface().post(this.klass().links()['related'] + 'information', this);
    }

    // Creates a transaction with a payment method and an amount
    //
    // @param [PaymentMethod] paymentMethod the payment method to charge
    // @param [Number] amount the amount to charge to the payment method
    // @return [Transaction] the built transaction representing the charge
    charge(paymentMethod, amount) {
      return this.transactions().build({
        amount: amount,
        paymentMethod: paymentMethod
      });
    }

    // Edits a transaction with a given payment method to have a new amount
    //
    // @param [PaymentMethod] paymentMethod the payment method to search transactions for
    // @param [Number] amount the new amount to charge to the payment method
    // @return [Transaction] the edited transaction representing the charge
    editCharge(paymentMethod, amount) {
      var transaction = this.transactions().target().detect(function(t) { return t.paymentMethod() == paymentMethod; });

      if(transaction) {
        transaction.amount = amount;
      }
    }

    // Removes a transaction for a given payment method
    //
    // @param [PaymentMethod] paymentMethod the payment method to remove the transaction for
    removeCharge(paymentMethod) {
      var transaction = this.transactions().target().detect(function(t) { return t.paymentMethod() == paymentMethod; });

      if(transaction) {
        this.transactions().target().delete(transaction);
      }
    }

    // @private

    // Called by Order.construct, which injects order
    // @note Must return order
    //
    // @param [Occsn.Order] order the order that wants an answer to the question
    // @param [Occsn.Question] question the question to construct an answer for
    static __constructAnswer(order, question) {
      if(question.category != 'static') {
        let answer = order.answers().build({
          question: question
        });

        switch(question.formControl) {
          case 'drop_down':
          case 'option_list':
            answer.assignOption(question.options().target().detect((o) => { return o.default }));
            break;
          case 'spin_button':
            answer.value = question.min;
            break;
        }
      }

      return order;
    }
  };

  library.Order.className = 'Order';
  library.Order.queryName = 'orders';

  library.Order.attributes(
    'sessionIdentifier',
    'status'
  );

  library.Order.attributes(
    'couponAmount',
    'giftCardAmount',
    'outstandingBalance',
    'price',
    'quantity',
    'subtotal',
    'tax',
    'taxPercentage',
    'total',
    { readOnly: true }
  );

  library.Order.belongsTo('coupon');
  library.Order.belongsTo('currency');
  library.Order.belongsTo('customer', { autosave: true, inverseOf: 'orders' });
  library.Order.belongsTo('merchant');
  library.Order.belongsTo('product');

  library.Order.hasMany('answers', { autosave: true, inverseOf: 'order' });
  library.Order.hasMany('attendees', { autosave: true, inverseOf: 'order' });
  library.Order.hasMany('timeSlots');
  library.Order.hasMany('transactions', { autosave: true, inverseOf: 'order' });

  library.Order.afterRequest(function() {
    if(this.product() && !this.product().attendeeQuestions.empty()) {
      var diff = this.quantity - this.attendees().size();

      if(diff != 0) {
        for(var i = 0; i < Math.abs(diff); i++) {
          if(diff > 0) {
            this.attendees().build();
          } else {
            this.attendees().target().pop();
          }
        }
      }
    }

    ActiveResource.Collection.build([
      'subtotal',
      'couponAmount',
      'tax',
      'giftCardAmount',
      'price',
      'total',
      'outstandingBalance'
    ])
    .select((attr) => this[attr])
    .each((attr) => {
      this[attr] = new Decimal(this[attr]);
    });

    if(this.outstandingBalance && !this.outstandingBalance.isZero()) {
      var giftCardTransactions = this.transactions().target().select((t) => t.paymentMethod() && t.paymentMethod().isA(library.GiftCard));
      var remainingBalanceTransaction = this.transactions().target().detect((t) => !(t.paymentMethod() && t.paymentMethod().isA(library.GiftCard)));

      if(this.outstandingBalance.isPositive()) {
        if(!giftCardTransactions.empty()) {
          giftCardTransactions
          .each((t) => {
            if(this.outstandingBalance.isZero()) return;

            let amount = new Decimal(t.amount);
            let giftCardValue = new Decimal(t.paymentMethod().value);
            let remainingGiftCardBalance = giftCardValue.minus(amount);

            if(remainingGiftCardBalance.isZero()) return;

            if(remainingGiftCardBalance.greaterThanOrEqualTo(this.outstandingBalance)) {
              amount = amount.plus(this.outstandingBalance);
              this.outstandingBalance = new Decimal(0);
            } else {
              amount = remainingGiftCardBalance;
              this.outstandingBalance = this.outstandingBalance.minus(remainingGiftCardBalance);
            }

            t.amount = amount.toString();

            this.transactions().target().delete(t);
            t.__createClone({ cloner: this });
          });
        }
      } else {
        if(!giftCardTransactions.empty()) {
          ActiveResource.Collection.build(giftCardTransactions.toArray().reverse())
          .each((t) => {
            if(this.outstandingBalance.isZero()) return;

            let amount = new Decimal(t.amount);

            if(amount.greaterThan(this.outstandingBalance.abs())) {
              amount = amount.plus(this.outstandingBalance);
              this.outstandingBalance = new Decimal(0);
            } else {
              this.outstandingBalance = this.outstandingBalance.plus(amount);

              this.removeCharge(t.paymentMethod());
              return;
            }

            t.amount = amount.toString();
            this.transactions().target().delete(t);
            t.__createClone({ cloner: this });
          });
        }
      }

      if(!giftCardTransactions.empty()) {
        this.giftCardAmount = this.transactions().target()
          .select((t) => t.paymentMethod() && t.paymentMethod().isA(library.GiftCard))
          .inject(
            new Decimal(0),
            (total, transaction) => total.plus(transaction.amount)
          );
      }

      if(remainingBalanceTransaction) {
        remainingBalanceTransaction.amount = this.outstandingBalance.toString();

        this.transactions().target().delete(remainingBalanceTransaction);
        remainingBalanceTransaction.__createClone({ cloner: this });
      }
    }
  });
});
<commit_msg>Add priceDueOnInitialOrder to order<commit_after>Occasion.Modules.push(function(library) {
  library.Order = class Order extends library.Base {
    static construct(attributes) {
      var order = this.includes('currency').build(attributes);

      order.sessionIdentifier = order.sessionIdentifier ||
        Math.random().toString(36).substring(7) + '-' + Date.now();

      if(order.customer() == null) {
        order.buildCustomer({
          email: null,
          firstName: null,
          lastName: null,
          zip: null
        });
      }

      var promises = [new Promise(function(resolve) {
        resolve(order);
      })];

      if(order.product() != null) {
        promises.push(order.product().questions().includes('options').perPage(500).load());

        if(!order.product().requiresTimeSlotSelection) {
          promises.push(
            order.product().timeSlots()
            .includes({ product: 'merchant' })
            .where({ status: 'bookable' })
            .perPage(500).all()
          );
        }
      }

      var _this = this;
      return Promise.all(promises)
      .then(function(args) {
        order = args[0];
        var questions = args[1];
        var timeSlots = args[2];

        if(questions != undefined) questions.inject(order, _this.__constructAnswer);
        if(timeSlots != undefined) order.timeSlots().assign(timeSlots, false);

        return order;
      });
    }

    // POSTs the order to `/orders/price`, which calculates price related fields and adds them to the order
    // @return [Promise] a promise for the order with price-related fields
    calculatePrice() {
      return this.interface().post(this.klass().links()['related'] + 'price', this);
    }

    // POSTs the order to `/orders/information`, which calculates price + quantity related fields and adds them to the
    //   order
    // @return [Promise] a promise for the order with price & quantity related fields
    retrieveInformation() {
      return this.interface().post(this.klass().links()['related'] + 'information', this);
    }

    // Creates a transaction with a payment method and an amount
    //
    // @param [PaymentMethod] paymentMethod the payment method to charge
    // @param [Number] amount the amount to charge to the payment method
    // @return [Transaction] the built transaction representing the charge
    charge(paymentMethod, amount) {
      return this.transactions().build({
        amount: amount,
        paymentMethod: paymentMethod
      });
    }

    // Edits a transaction with a given payment method to have a new amount
    //
    // @param [PaymentMethod] paymentMethod the payment method to search transactions for
    // @param [Number] amount the new amount to charge to the payment method
    // @return [Transaction] the edited transaction representing the charge
    editCharge(paymentMethod, amount) {
      var transaction = this.transactions().target().detect(function(t) { return t.paymentMethod() == paymentMethod; });

      if(transaction) {
        transaction.amount = amount;
      }
    }

    // Removes a transaction for a given payment method
    //
    // @param [PaymentMethod] paymentMethod the payment method to remove the transaction for
    removeCharge(paymentMethod) {
      var transaction = this.transactions().target().detect(function(t) { return t.paymentMethod() == paymentMethod; });

      if(transaction) {
        this.transactions().target().delete(transaction);
      }
    }

    // @private

    // Called by Order.construct, which injects order
    // @note Must return order
    //
    // @param [Occsn.Order] order the order that wants an answer to the question
    // @param [Occsn.Question] question the question to construct an answer for
    static __constructAnswer(order, question) {
      if(question.category != 'static') {
        let answer = order.answers().build({
          question: question
        });

        switch(question.formControl) {
          case 'drop_down':
          case 'option_list':
            answer.assignOption(question.options().target().detect((o) => { return o.default }));
            break;
          case 'spin_button':
            answer.value = question.min;
            break;
        }
      }

      return order;
    }
  };

  library.Order.className = 'Order';
  library.Order.queryName = 'orders';

  library.Order.attributes(
    'sessionIdentifier',
    'status'
  );

  library.Order.attributes(
    'couponAmount',
    'giftCardAmount',
    'outstandingBalance',
    'price',
    'quantity',
    'subtotal',
    'tax',
    'taxPercentage',
    'total',
    'priceDueOnInitialOrder',
    { readOnly: true }
  );

  library.Order.belongsTo('coupon');
  library.Order.belongsTo('currency');
  library.Order.belongsTo('customer', { autosave: true, inverseOf: 'orders' });
  library.Order.belongsTo('merchant');
  library.Order.belongsTo('product');

  library.Order.hasMany('answers', { autosave: true, inverseOf: 'order' });
  library.Order.hasMany('attendees', { autosave: true, inverseOf: 'order' });
  library.Order.hasMany('timeSlots');
  library.Order.hasMany('transactions', { autosave: true, inverseOf: 'order' });

  library.Order.afterRequest(function() {
    if(this.product() && !this.product().attendeeQuestions.empty()) {
      var diff = this.quantity - this.attendees().size();

      if(diff != 0) {
        for(var i = 0; i < Math.abs(diff); i++) {
          if(diff > 0) {
            this.attendees().build();
          } else {
            this.attendees().target().pop();
          }
        }
      }
    }

    ActiveResource.Collection.build([
      'subtotal',
      'couponAmount',
      'tax',
      'giftCardAmount',
      'price',
      'total',
      'outstandingBalance'
    ])
    .select((attr) => this[attr])
    .each((attr) => {
      this[attr] = new Decimal(this[attr]);
    });

    if(this.outstandingBalance && !this.outstandingBalance.isZero()) {
      var giftCardTransactions = this.transactions().target().select((t) => t.paymentMethod() && t.paymentMethod().isA(library.GiftCard));
      var remainingBalanceTransaction = this.transactions().target().detect((t) => !(t.paymentMethod() && t.paymentMethod().isA(library.GiftCard)));

      if(this.outstandingBalance.isPositive()) {
        if(!giftCardTransactions.empty()) {
          giftCardTransactions
          .each((t) => {
            if(this.outstandingBalance.isZero()) return;

            let amount = new Decimal(t.amount);
            let giftCardValue = new Decimal(t.paymentMethod().value);
            let remainingGiftCardBalance = giftCardValue.minus(amount);

            if(remainingGiftCardBalance.isZero()) return;

            if(remainingGiftCardBalance.greaterThanOrEqualTo(this.outstandingBalance)) {
              amount = amount.plus(this.outstandingBalance);
              this.outstandingBalance = new Decimal(0);
            } else {
              amount = remainingGiftCardBalance;
              this.outstandingBalance = this.outstandingBalance.minus(remainingGiftCardBalance);
            }

            t.amount = amount.toString();

            this.transactions().target().delete(t);
            t.__createClone({ cloner: this });
          });
        }
      } else {
        if(!giftCardTransactions.empty()) {
          ActiveResource.Collection.build(giftCardTransactions.toArray().reverse())
          .each((t) => {
            if(this.outstandingBalance.isZero()) return;

            let amount = new Decimal(t.amount);

            if(amount.greaterThan(this.outstandingBalance.abs())) {
              amount = amount.plus(this.outstandingBalance);
              this.outstandingBalance = new Decimal(0);
            } else {
              this.outstandingBalance = this.outstandingBalance.plus(amount);

              this.removeCharge(t.paymentMethod());
              return;
            }

            t.amount = amount.toString();
            this.transactions().target().delete(t);
            t.__createClone({ cloner: this });
          });
        }
      }

      if(!giftCardTransactions.empty()) {
        this.giftCardAmount = this.transactions().target()
          .select((t) => t.paymentMethod() && t.paymentMethod().isA(library.GiftCard))
          .inject(
            new Decimal(0),
            (total, transaction) => total.plus(transaction.amount)
          );
      }

      if(remainingBalanceTransaction) {
        remainingBalanceTransaction.amount = this.outstandingBalance.toString();

        this.transactions().target().delete(remainingBalanceTransaction);
        remainingBalanceTransaction.__createClone({ cloner: this });
      }
    }
  });
});
<|endoftext|>


<commit_before>(function() {

  var isObject = function(obj) {
    var type = typeof obj;
    return type === 'function' || type === 'object' && !!obj;
  }, isString = function(str) {
    return (typeof str === 'string' && str);
  }, isFunction = function(str) {
    return (typeof str === 'function');
  }, copy = function(dest, src){
    if(!isObject(dest)) dest = {};
    if(!isObject(src)) return dest;
    for(var key in src){
      if(src.hasOwnProperty(key)){
        dest[key] = src[key];
      }
    }
    return dest;
  }, extractParameters = function(str){ // https://jsfiddle.net/jv0328tp/18/
    var ar = [];
    if(typeof str === 'string' && str.length){
      var chars = str.split(','), cl = chars.length;
      var pushInto = function(n){
        chars[n] = chars[n].trim();
        var len = chars[n].length;
        //convert single quoted string to double quoted string for JSON parse
        if(len >= 2 && chars[n].charAt(0) === "'" && chars[n].charAt(len - 1) === "'"){
          chars[n] = '"' + chars[n].substring(1, len - 1) + '"';
        }
        try {
          ar.push(JSON.parse(chars[n]));
        } catch(er){
          console.log(er);
          ar.push(undefined);
        }
      };
      for(var di, si, eg, fg, n = 0; n < cl; n++){
        eg = chars[n].charAt(0);
        fg = chars[n].charAt(chars[n].length - 1);
        if(!(eg === fg && (eg === '"' || eg === "'"))){
          chars[n] = chars[n].trim();
          eg = chars[n].charAt(0);
          fg = chars[n].charAt(chars[n].length - 1);
        }
        di = chars[n].indexOf('"');
        si = chars[n].indexOf("'");
        if(((si === -1) && (di === -1)) || (eg === fg && (eg === '"' || eg === "'")) ||
           (chars[n].charAt(0) === "{" && chars[n].charAt(chars[n].length-1) === "}" && (chars[n].match(/\{/g).length === chars[n].match(/\}/g).length))){
          pushInto(n);
        } else if(n < (cl-1)) {
          chars[n] = chars[n] + ','+ chars[n+1];
          chars.splice(n+1,1);
          n--;
          cl--;
          continue;
        }
      }
    }
    return ar;
  };

  var VAR_MAP = {}, FUNC_MAP = {}, DEF_NOT_FOUND_MSG = 'VAR_NOT_FOUND',
      START_VAR = '{{', END_VAR = '}}', SVAR_L = START_VAR.length, EVAR_L = END_VAR.length;

  // tested here https://jsfiddle.net/zg85982k/1/

  var extractVarName = function(variable){
    return variable.substring(SVAR_L, variable.length - EVAR_L); // will remove the enclosing braces
  };

  //this method will extract all the variables available in the string
  //variable names will be having enclosing braces
  var extractVars = function(str){
    var regex = /(\{\{[a-z_A-Z0-9:\-]+\}\})+/g;
    return str.match(regex) || [];
  };

  //extract method name from input method string e.g. {{method_name("hello", "world")}}
  // will return "method_name"
  var extractMethodName = function(methodDec){
    return methodDec.substring(SVAR_L, methodDec.indexOf('('));
  };

  //this method will extract all the methods available in the string
  var extractMethods = function(str){
    var regex = /(\{\{[a-z_A-Z0-9:\-]+\(.*?\)\}\})+/g;
    return str.match(regex) || [];
  };

  //replaces a single variable (only variable) in the string, if exists
  var replaceVariable = function(str, varName, varValue){
    if(str === varName) return varValue;
    var strType = typeof varValue === "string";
    return str.replace(strType ? varName : '"'+varName+'"', strType ? varValue : JSON.stringify(varValue));
  };

  var replaceVariables = function(str, vars, variablesMap){
    for(var i = 0; i < vars.length; i++){
      var varName = extractVarName(vars[i]);
      str = replaceVariable(str, vars[i], variablesMap[varName] || vars[i]);
    }
    return str;
  };

  var invokeMethod = function(method, params){
    return method.apply(undefined, params);
  };

  var extractMethodParams = function(methodDec, methodName, options){
    var params = [];
    if(Array.isArray(options.prefixes)){
      copy(params, options.prefixes);
    }
    var baseDec = methodDec.substring(methodName.length + SVAR_L + 1, methodDec.length - (EVAR_L + 1)).trim();
    params = params.concat(extractParameters(baseDec));
    return params;
  };

  var getMethodValue = function(methodDec, methodName, method, options){
    var methodParams = extractMethodParams(methodDec, methodName, options);
    return invokeMethod(method, methodParams);
  };

  //invokes a single method and replaces its value in the string
  var replaceMethod = function(str, methodDec, methodName, method, options){
    var methodValue = getMethodValue(methodDec, methodName, method, options);
    if(str === methodDec) return methodValue;
    return str.replace(methodDec, methodValue);
  };

  var replaceMethods = function(str, methods, methodsMap, options){
    var methodName = "";
    for(var i = 0; i < methods.length; i++){
      methodName = extractMethodName(methods[i]);
      str = replaceMethod(str, methods[i], methodName, methodsMap[methodName] || function(){ return 'NO_UTILITY_METHOD'; }, options);
    }
    return str;
  };

  var myModule = {
    init : function(options){
      if(!isObject(options)) options = {};
      copy(VAR_MAP, options.variablesMap);
      copy(FUNC_MAP, options.functionsMap);
      if(typeof options.defaultNotFoundMsg === 'string' && options.defaultNotFoundMsg) {
        DEF_NOT_FOUND_MSG = options.defaultNotFoundMsg;
      }
      if(typeof options.startVar === 'string' && options.startVar) {
        START_VAR = options.startVar;
        SVAR_L = START_VAR.length;
      }
      if(typeof options.endVar === 'string' && options.endVar) {
        END_VAR = options.endVar;
        EVAR_L = END_VAR.length;
      }
    },

    replace : function(str, options){
      if(!isString(str)) return str;
      if(!isObject(options)) options = {};

      str = replaceVariables(str, extractVars(str), VAR_MAP);

      //if str becomes not a string then return as it is
      if(!isString(str)) return str;

      //now in our input string, all the variables are replaced
      //now the below method will automatically find all the methods, bcoz no variables are there in the string
      return replaceMethods(str, extractMethods(str), FUNC_MAP, options);
    },

    getVars : function(){
      return VAR_MAP;
    },

    clearVars: function(){
      for (var prop in VAR_MAP) { if (VAR_MAP.hasOwnProperty(prop)) { delete VAR_MAP[prop]; } }
    },

    getFuncs : function(){
      return FUNC_MAP;
    }

  };

  var root = this;

  if (typeof exports !== 'undefined') {
    if (typeof module !== 'undefined' && module.exports) {
      exports = module.exports = myModule;
    }
    exports.myModule = myModule;
  } else {
    root.myModule = myModule;
  }

  if(typeof define === 'function' && define.amd) {
    define('replaceStringModule', [], function() {
      return myModule;
    });
  }

}).call(this);
<commit_msg>modified<commit_after>(function() {

  var isObject = function(obj) {
    var type = typeof obj;
    return type === 'function' || type === 'object' && !!obj;
  }, isString = function(str) {
    return (typeof str === 'string' && str);
  }, isFunction = function(str) {
    return (typeof str === 'function');
  }, copy = function(dest, src){
    if(!isObject(dest)) dest = {};
    if(!isObject(src)) return dest;
    for(var key in src){
      if(src.hasOwnProperty(key)){
        dest[key] = src[key];
      }
    }
    return dest;
  }, extractParameters = function(str){ // https://jsfiddle.net/jv0328tp/18/
    var ar = [];
    if(typeof str === 'string' && str.length){
      var chars = str.split(','), cl = chars.length;
      var pushInto = function(n){
        chars[n] = chars[n].trim();
        var len = chars[n].length;
        //convert single quoted string to double quoted string for JSON parse
        if(len >= 2 && chars[n].charAt(0) === "'" && chars[n].charAt(len - 1) === "'"){
          chars[n] = '"' + chars[n].substring(1, len - 1) + '"';
        }
        try {
          ar.push(JSON.parse(chars[n]));
        } catch(er){
          console.log(er);
          ar.push(undefined);
        }
      };
      for(var di, si, eg, fg, n = 0; n < cl; n++){
        eg = chars[n].charAt(0);
        fg = chars[n].charAt(chars[n].length - 1);
        if(!(eg === fg && (eg === '"' || eg === "'"))){
          chars[n] = chars[n].trim();
          eg = chars[n].charAt(0);
          fg = chars[n].charAt(chars[n].length - 1);
        }
        di = chars[n].indexOf('"');
        si = chars[n].indexOf("'");
        if(((si === -1) && (di === -1)) || (eg === fg && (eg === '"' || eg === "'")) ||
           (chars[n].charAt(0) === "{" && chars[n].charAt(chars[n].length-1) === "}" && (chars[n].match(/\{/g).length === chars[n].match(/\}/g).length))){
          pushInto(n);
        } else if(n < (cl-1)) {
          chars[n] = chars[n] + ','+ chars[n+1];
          chars.splice(n+1,1);
          n--;
          cl--;
          continue;
        }
      }
    }
    return ar;
  };

  var VAR_MAP = {}, FUNC_MAP = {}, DEF_NOT_FOUND_MSG = 'VAR_NOT_FOUND',
      START_VAR = '{{', END_VAR = '}}', SVAR_L = START_VAR.length, EVAR_L = END_VAR.length;

  // tested here https://jsfiddle.net/zg85982k/1/

  var extractVarName = function(variable){
    return variable.substring(SVAR_L, variable.length - EVAR_L); // will remove the enclosing braces
  };

  //this method will extract all the variables available in the string
  //variable names will be having enclosing braces
  var extractVars = function(str){
    var regex = /(\{\{[a-z_A-Z0-9:\-]+\}\})+/g;
    return str.match(regex) || [];
  };

  //extract method name from input method string e.g. {{method_name("hello", "world")}}
  // will return "method_name"
  var extractMethodName = function(methodDec){
    return methodDec.substring(SVAR_L, methodDec.indexOf('('));
  };

  //this method will extract all the methods available in the string
  var extractMethods = function(str){
    var regex = /(\{\{[a-z_A-Z0-9:\-]+\(.*?\)\}\})+/g;
    return str.match(regex) || [];
  };

  //replaces a single variable (only variable) in the string, if exists
  var replaceVariable = function(str, varName, varValue){
    if(str === varName) return varValue;
    var strType = typeof varValue === "string", ln = str.length;
    return str.replace((strType || (str.indexOf('{{') !== 0 || str.indexOf('}}') !== (ln-1))) ? varName : '"'+varName+'"',
        strType ? varValue : JSON.stringify(varValue));
  };

  var replaceVariables = function(str, vars, variablesMap){
    for(var i = 0; i < vars.length; i++){
      var varName = extractVarName(vars[i]);
      str = replaceVariable(str, vars[i], variablesMap.hasOwnProperty(varName) ? variablesMap[varName] : vars[i]);
    }
    return str;
  };

  var invokeMethod = function(method, params){
    return method.apply(undefined, params);
  };

  var extractMethodParams = function(methodDec, methodName, options){
    var params = [];
    if(Array.isArray(options.prefixes)){
      copy(params, options.prefixes);
    }
    var baseDec = methodDec.substring(methodName.length + SVAR_L + 1, methodDec.length - (EVAR_L + 1)).trim();
    params = params.concat(extractParameters(baseDec));
    return params;
  };

  var getMethodValue = function(methodDec, methodName, method, options){
    var methodParams = extractMethodParams(methodDec, methodName, options);
    return invokeMethod(method, methodParams);
  };

  //invokes a single method and replaces its value in the string
  var replaceMethod = function(str, methodDec, methodName, method, options){
    var methodValue = getMethodValue(methodDec, methodName, method, options);
    if(str === methodDec) return methodValue;
    return str.replace(methodDec, methodValue);
  };

  var replaceMethods = function(str, methods, methodsMap, options){
    var methodName = "";
    for(var i = 0; i < methods.length; i++){
      methodName = extractMethodName(methods[i]);
      str = replaceMethod(str, methods[i], methodName, methodsMap[methodName] || function(){ return 'NO_UTILITY_METHOD'; }, options);
    }
    return str;
  };

  var myModule = {
    init : function(options){
      if(!isObject(options)) options = {};
      copy(VAR_MAP, options.variablesMap);
      copy(FUNC_MAP, options.functionsMap);
      if(typeof options.defaultNotFoundMsg === 'string' && options.defaultNotFoundMsg) {
        DEF_NOT_FOUND_MSG = options.defaultNotFoundMsg;
      }
      if(typeof options.startVar === 'string' && options.startVar) {
        START_VAR = options.startVar;
        SVAR_L = START_VAR.length;
      }
      if(typeof options.endVar === 'string' && options.endVar) {
        END_VAR = options.endVar;
        EVAR_L = END_VAR.length;
      }
    },

    replace : function(str, options){
      if(!isString(str)) return str;
      if(!isObject(options)) options = {};

      str = replaceVariables(str, extractVars(str), VAR_MAP);

      //if str becomes not a string then return as it is
      if(!isString(str)) return str;

      //now in our input string, all the variables are replaced
      //now the below method will automatically find all the methods, bcoz no variables are there in the string
      return replaceMethods(str, extractMethods(str), FUNC_MAP, options);
    },

    getVars : function(){
      return VAR_MAP;
    },

    clearVars: function(){
      for (var prop in VAR_MAP) { if (VAR_MAP.hasOwnProperty(prop)) { delete VAR_MAP[prop]; } }
    },

    getFuncs : function(){
      return FUNC_MAP;
    }

  };

  var root = this;

  if (typeof exports !== 'undefined') {
    if (typeof module !== 'undefined' && module.exports) {
      exports = module.exports = myModule;
    }
    exports.myModule = myModule;
  } else {
    root.myModule = myModule;
  }

  if(typeof define === 'function' && define.amd) {
    define('replaceStringModule', [], function() {
      return myModule;
    });
  }

}).call(this);
<|endoftext|>