<commit_before>/**
 * @fileOverview ECMAScript 5.1 semantics.
 */
define(['atum/compute',
        'atum/context/environment', 'atum/context/execution_context', 'atum/context/global',
        'atum/reference',
        'atum/value/value',
        'atum/value/boolean', 'atum/value/number', 'atum/value/string', 'atum/value/undef',
        'atum/semantics/environment', 'atum/semantics/number', 'atum/semantics/type_conversion',
        'atum/semantics/completion', 'atum/semantics/reference'],
function(compute,
        environment, execution_context, global,
        reference,
        value,
        boolean, number, string, undef,
        environment_semantics, number_semantics, type_conversion,
        completion, reference_semantics){
//"use strict";

var curry = function(f) {
    return ((arguments.length === 1) ? f : f.bind.apply(f, arguments));
};

/* Statement Semantics
 ******************************************************************************/
/**
 * Semantics for a list of statements.
 */
var statementList = function(statements) {
    if (statements.length === 0) {
        return compute.always(new undef.Undefined());
    } else {
        return compute.bind(statements[0], function(x) {
            return (x instanceof completion.Completion || statements.length <= 1 ?
                compute.always(x) :
                statementList(statements.slice(1)));
        });
    }
};

/**
 * Semantics for an expression statement.
 */
var expressionStatement = function(expression) {
    return reference_semantics.getValue(expression);
};

/**
 * Semantics for an if statement
 */
var ifStatement = function(test, consequent, alternate) {
    return compute.bind(reference_semantics.getValue(test), function(x) {
        return (x.value ?
            consequent :
            alternate);
    });
};

/**
 * Semantics for a return statement.
 */
var returnStatement = function(argument) {
    return compute.bind(argument, function(x) {
        return compute.always(new completion.ReturnCompletion(x));
    });
};

/**
 * Semantics for a throw statement.
 */
var throwStatement = function(argument) {
    return compute.bind(argument, function(x) {
        return compute.never(new ThrowCompletion(x));
    });
};

/**
 * Semantics for a break statement.
 */
var breakStatement = function(label) {
    return compute.bind(argument, function() {
        return compute.always(new completion.BreakCompletion(label));
    });
};

/**
 * Semantics for a continue statement
 */
var continueStatement = function(label) {
    return compute.bind(argument, function() {
        return compute.always(new completion.ContinueCompletion(label));
    });
};

/* Binary Operator Semantics
 ******************************************************************************/
/**
 *
 */
var addOperator = function(left, right) {
    return compute.bind(
        type_conversion.toPrimitive(reference_semantics.getValue(left)),
        function(lprim) {
            return compute.bind(
                type_conversion.toPrimitive(reference_semantics.getValue(right)),
                function(rprim) {
                    return (value.type(lprim) === "string" || value.type(rprim) === "string" ?
                        string.concat(
                             type_conversion.toString(compute.always(lprim)),
                             type_conversion.toString(compute.always(rprim))) :
                        number_semantics.add(
                            type_conversion.toNumber(compute.always(lprim)),
                            type_conversion.toNumber(compute.always(rprim))));
                });
        });
};

/**
 *
 */
var subtractOperator = function(left, right) {
    return number_semantics.subtract(
        type_conversion.toNumber(reference_semantics.getValue(left)),
        type_conversion.toNumber(reference_semantics.getValue(right)));
};

/**
 *
 */
var multiplyOperator = function(left, right) {
    return number_semantics.multiply(
        type_conversion.toNumber(reference_semantics.getValue(left)),
        type_conversion.toNumber(reference_semantics.getValue(right)));
};

/**
 *
 */
var divideOperator = function(left, right) {
    return number_semantics.divide(
        type_conversion.toNumber(reference_semantics.getValue(left)),
        type_conversion.toNumber(reference_semantics.getValue(right)));
};

/**
 *
 */
var remainderOperator = function(left, right) {
    return number_semantics.remainder(
        type_conversion.toNumber(reference_semantics.getValue(left)),
        type_conversion.toNumber(reference_semantics.getValue(right)));
};

/**
 *
 */
var leftShiftOperator = function(left, right) {
    return number_semantics.leftShift(
        type_conversion.toInt32(reference_semantics.getValue(left)),
        type_conversion.toUint32(reference_semantics.getValue(right)));
};

/**
 *
 */
var signedRightShiftOperator = function(left, right) {
    return number_semantics.signedRightShift(
        type_conversion.toInt32(reference_semantics.getValue(left)),
        type_conversion.toUint32(reference_semantics.getValue(right)));
};

/**
 *
 */
var unsignedRightShiftOperator = function(left, right) {
    return number_semantics.unsignedRightShift(
        type_conversion.toInt32(reference_semantics.getValue(left)),
        type_conversion.toUint32(reference_semantics.getValue(right)));
};

/**
 *
 */
var bitwiseAndOperator = function(left, right) {
    return number_semantics.unsignedRightShift(
        type_conversion.toInt32(reference_semantics.getValue(left)),
        type_conversion.toInt32(reference_semantics.getValue(right)));
};

/**
 *
 */
var bitwiseXorOperator = function(left, right) {
    return number_semantics.unsignedRightShift(
        type_conversion.toInt32(reference_semantics.getValue(left)),
        type_conversion.toInt32(reference_semantics.getValue(right)));
};

/**
 *
 */
var bitwiseOrOperator = function(left, right) {
    return number_semantics.unsignedRightShift(
        type_conversion.toInt32(reference_semantics.getValue(left)),
        type_conversion.toInt32(reference_semantics.getValue(right)));
};

/* Binary Relational Operators
 *
 * @TODO Should we return undefined values when NaN is used?
 ******************************************************************************/
var _relationalOperator = function(op) {
    return function(left, right) {
        return op(
            type_conversion.toNumber(reference_semantics.getValue(left)),
            type_conversion.toNumber(reference_semantics.getValue(right)));
    };
};

/**
 *
 */
var ltOperator = _relationalOperator(number_semantics.lt);

/**
 *
 */
var lteOperator = _relationalOperator(number_semantics.lte);

/**
 *
 */
var gtOperator = _relationalOperator(number_semantics.gt);

/**
 *
 */
var gteOperator = _relationalOperator(number_semantics.gte);

var instanceofOperator = function(left, right) {
    return compute.bind(
        reference.getValue(left),
        function(l) {
            return compute.bind(
                reference.getValue(right),
                function(r) {
                    return function(ctx, ok, err) {
                        if (value.type(r) !== 'object') {
                            return err('Instanceof', ctx);
                        }
                        return ok(value.hasInstance(l), ctx);
                    };
                });
        });
};

var inOperator;

/* Unary Operator Semantics
 ******************************************************************************/
/**
 *
 */
var unaryPlusOperator = function(argument) {
    return type_conversion.toNumber(reference_semantics.getValue(argument));
};

/**
 *
 */
var unaryMinusOperator = function(argument) {
    return number_semantics.negate(type_conversion.toNumber(reference_semantics.getValue(argument)));
};

/**
 *
 */
var logicalNotOperator = function(argument) {
    return boolean.logicalNot(type_conversion.toBoolean(reference_semantics.getValue(argument)));
};

var bitwiseNotOperator = function(argument) {
    return number_semantics.bitwiseNot(type_conversion.toInt32(reference_semantics.getValue(argument)));
};

/**
 *
 */
var voidOperator = function(argument) {
    return compute.next(reference_semantics.getValue(argument)),
        compute.always(new undef.Undefined());
};

/**
 *
 */
var typeofOperator = function(argument) {
    return compute.bind(argument, function(val) {
        if (val instanceof reference_semantics.Reference) {
            return (reference_semantics.isUnresolvableReference(val) ?
                compute.always("undefined") :
                typeofOperator(reference_semantics.getValue(val)));
        }
        return compute.always(value.type(val));
    });
};

/* Update Operator Semantics
 ******************************************************************************/
var _prefixOperator = function(op) {
    return function(argument) {
        return compute.bind(argument, op);
    };
};

var _postfixOperator = function(op) {
    return function(argument) {
        return compute.bind(argument, function(oldValue) {
            return compute.next(
                op(oldValue),
                compute.always(oldValue));
        });
    };
};

var _increment = function(expr) {
    return compute.bind(
        type_conversion.toNumber(reference_semantics.getValue(compute.always(expr))),
        function(oldValue) {
            return reference_semantics.putValue(compute.always(expr), compute.always(number.add(oldValue, new number.Number(1))));
        });
};

var _decrement = function(expr) {
    return compute.bind(
        type_conversion.toNumber(reference_semantics.getValue(compute.always(expr))),
        function(oldValue) {
            return reference_semantics.putValue(compute.always(expr), compute.always(number.add(oldValue, new number.Number(-1))));
        });
};

/**
 *
 */
var prefixIncrement = _prefixOperator(_increment);

/**
 *
 */
var postfixIncrement =  _postfixOperator(_increment);

/**
 *
 */
var prefixDecrement = _prefixOperator(_decrement);

/**
 *
 */
var postfixDecrement =  _postfixOperator(_decrement);

/* Logical Binary Operator Semantics
 ******************************************************************************/
/**
 * Semantics for a logical or operation. Shorts when left evaluates to true.
 */
var logicalOr = function(left, right) {
    return compute.bind(
        type_conversion.toBoolean(left),
        function(result) {
            return (result.value === true ?
                left :
                right);
    });
};

/**
 * Semantics for a logical and operation. Shorts when left evaluates to false.
 */
var logicalAnd = function(left, right) {
    return compute.bind(
        type_conversion.toBoolean(left),
        function(result) {
            return (result.value === true ?
                right :
                left);
        });
};

/*
 ******************************************************************************/
/**
 * Semantics for a conditional Expression.
 */
var conditionalExpression = function(test, consequent, alternate) {
    return compute.bind(
        type_conversion.toBoolean(reference_semantics.getValue(test)),
        function(x) {
            return reference_semantics.getValue(x.value ?
                consequent :
                alternate);
        });
};

/**
 * Semantics for a sequence of expressions.
 */
var sequenceExpression = function(expressions) {
    return (expressions.length === 1 ?
        reference_semantics.getValue(expressions[0]) :
        compute.next(
            reference_semantics.getValue(expressions[0]),
            sequenceExpression(expressions.slice(1))));
};

/* Assignment Semantics
 ******************************************************************************/
var _dereference = function(lref) {
    if (lref instanceof reference.Reference &&
        lref.strict &&
        lref.base instanceof e
        (lref.name === "eval" || lref.name === "arguments")) {
        return compute.never("Using eval/arguments in stricts");
    }
    return compute.always(lref);
};

/**
 * Semantics for simple assignment.
 */
var assignment = function(left, right) {
    return reference_semantics.putValue(
        compute.bind(left, _dereference),
        reference_semantics.getValue(right));
};

/**
 * Semantics for an assignment that modifies a value assigned value by
 * operating on its current value.
 */
var compoundAssignment = function(op) {
    return function(left, right) {
        return reference_semantics.putValue(
            compute.bind(left, _dereference),
            op(
                reference_semantics.getValue(left),
                reference_semantics.getValue(right)));
    };
};

/* Declaration Semantics
 ******************************************************************************/
/**
 * Semantics for a variable declaration.
 */
var variableDeclaration = function(declarations) {
    return declarations.reduce(compute.next);
};

/**
 * Semantics for a single variable declarator.
 */
var variableDeclarator = function(id, init) {
    return compute.bind(reference_semantics.getValue(init), function(x) {
        return function(ctx, ok, err) {
            var newCtx = new execution_context.ExecutionContext(
                ctx.type,
                ctx.strict,
                environment.putIdentifierReference(ctx.lexicalEnvironment, id, x),
                ctx.variableEnvironment,
                ctx.thisBinding);
            return ok(x, newCtx);
        };
    });
};

/* Values
 ******************************************************************************/
var numberLiteral = function(value) {
    return compute.always(new number.Number(value));
};

var booleanLiteral = function(value) {
    return compute.always(new boolean.Boolean(value));
};

var stringLiteral = function(value) {
    return compute.always(new string.String(value));
};

var identifier = function(name) {
    return environment_semantics.getIdentifierReference(name);
};

/* Export
 ******************************************************************************/
return {
// Statement Semantics
    'statementList': statementList,
    'expressionStatement': expressionStatement,
    'returnStatement': returnStatement,
    'throwStatement': throwStatement,
    'breakStatement': breakStatement,
    'continueStatement': continueStatement,

// Binary Operator Semantics
    'addOperator': addOperator,
    'subtractOperator': subtractOperator,
    'multiplyOperator': multiplyOperator,
    'divideOperator': divideOperator,
    'remainderOperator': remainderOperator,

    'leftShiftOperator': leftShiftOperator,
    'signedRightShiftOperator': signedRightShiftOperator,
    'unsignedRightShiftOperator': unsignedRightShiftOperator,
    'bitwiseAndOperator': bitwiseAndOperator,
    'bitwiseXorOperator': bitwiseXorOperator,
    'bitwiseOrOperator': bitwiseOrOperator,

//Binary Relational Operator Semantics
    'ltOperator': ltOperator,
    'lteOperator': lteOperator,
    'gtOperator': gtOperator,
    'gteOperator': gteOperator,
    'instanceofOperator': instanceofOperator,
    'inOperator': inOperator,

// Increment and Decrement Operator Semantics
    'prefixIncrement': prefixIncrement,
    'postfixIncrement': postfixIncrement,
    'prefixDecrement': prefixDecrement,
    'postfixDecrement': postfixDecrement,

// Unary Operator Semantics
    'unaryPlusOperator': unaryPlusOperator,
    'unaryMinusOperator': unaryMinusOperator,
    'logicalNotOperator': logicalNotOperator,
    'bitwiseNotOperator': bitwiseNotOperator,
    'voidOperator': voidOperator,
    'typeofOperator': typeofOperator,

    // Logical Semantics
    'logicalOr': logicalOr,
    'logicalAnd': logicalAnd,

// Expression Semantics
    'conditionalExpression': conditionalExpression,
    'sequenceExpression': sequenceExpression,

// Assignment
    'assignment': assignment,
    'compoundAssignment': compoundAssignment,

// Declaration Semantics
    'variableDeclaration': variableDeclaration,
    'variableDeclarator': variableDeclarator,

// Values
    'numberLiteral': numberLiteral,
    'booleanLiteral': booleanLiteral,
    'stringLiteral': stringLiteral,
    'identifier': identifier
};

});<commit_msg>Made logical expressions get reference values.<commit_after>/**
 * @fileOverview ECMAScript 5.1 semantics.
 */
define(['atum/compute',
        'atum/context/environment', 'atum/context/execution_context', 'atum/context/global',
        'atum/reference',
        'atum/value/value',
        'atum/value/boolean', 'atum/value/number', 'atum/value/string', 'atum/value/undef',
        'atum/semantics/environment', 'atum/semantics/number', 'atum/semantics/type_conversion',
        'atum/semantics/completion', 'atum/semantics/reference'],
function(compute,
        environment, execution_context, global,
        reference,
        value,
        boolean, number, string, undef,
        environment_semantics, number_semantics, type_conversion,
        completion, reference_semantics){
//"use strict";

var curry = function(f) {
    return ((arguments.length === 1) ? f : f.bind.apply(f, arguments));
};

/* Statement Semantics
 ******************************************************************************/
/**
 * Semantics for a list of statements.
 */
var statementList = function(statements) {
    if (statements.length === 0) {
        return compute.always(new undef.Undefined());
    } else {
        return compute.bind(statements[0], function(x) {
            return (x instanceof completion.Completion || statements.length <= 1 ?
                compute.always(x) :
                statementList(statements.slice(1)));
        });
    }
};

/**
 * Semantics for an expression statement.
 */
var expressionStatement = function(expression) {
    return reference_semantics.getValue(expression);
};

/**
 * Semantics for an if statement
 */
var ifStatement = function(test, consequent, alternate) {
    return compute.bind(reference_semantics.getValue(test), function(x) {
        return (x.value ?
            consequent :
            alternate);
    });
};

/**
 * Semantics for a return statement.
 */
var returnStatement = function(argument) {
    return compute.bind(argument, function(x) {
        return compute.always(new completion.ReturnCompletion(x));
    });
};

/**
 * Semantics for a throw statement.
 */
var throwStatement = function(argument) {
    return compute.bind(argument, function(x) {
        return compute.never(new ThrowCompletion(x));
    });
};

/**
 * Semantics for a break statement.
 */
var breakStatement = function(label) {
    return compute.bind(argument, function() {
        return compute.always(new completion.BreakCompletion(label));
    });
};

/**
 * Semantics for a continue statement
 */
var continueStatement = function(label) {
    return compute.bind(argument, function() {
        return compute.always(new completion.ContinueCompletion(label));
    });
};

/* Binary Operator Semantics
 ******************************************************************************/
/**
 *
 */
var addOperator = function(left, right) {
    return compute.bind(
        type_conversion.toPrimitive(reference_semantics.getValue(left)),
        function(lprim) {
            return compute.bind(
                type_conversion.toPrimitive(reference_semantics.getValue(right)),
                function(rprim) {
                    return (value.type(lprim) === "string" || value.type(rprim) === "string" ?
                        string.concat(
                             type_conversion.toString(compute.always(lprim)),
                             type_conversion.toString(compute.always(rprim))) :
                        number_semantics.add(
                            type_conversion.toNumber(compute.always(lprim)),
                            type_conversion.toNumber(compute.always(rprim))));
                });
        });
};

/**
 *
 */
var subtractOperator = function(left, right) {
    return number_semantics.subtract(
        type_conversion.toNumber(reference_semantics.getValue(left)),
        type_conversion.toNumber(reference_semantics.getValue(right)));
};

/**
 *
 */
var multiplyOperator = function(left, right) {
    return number_semantics.multiply(
        type_conversion.toNumber(reference_semantics.getValue(left)),
        type_conversion.toNumber(reference_semantics.getValue(right)));
};

/**
 *
 */
var divideOperator = function(left, right) {
    return number_semantics.divide(
        type_conversion.toNumber(reference_semantics.getValue(left)),
        type_conversion.toNumber(reference_semantics.getValue(right)));
};

/**
 *
 */
var remainderOperator = function(left, right) {
    return number_semantics.remainder(
        type_conversion.toNumber(reference_semantics.getValue(left)),
        type_conversion.toNumber(reference_semantics.getValue(right)));
};

/**
 *
 */
var leftShiftOperator = function(left, right) {
    return number_semantics.leftShift(
        type_conversion.toInt32(reference_semantics.getValue(left)),
        type_conversion.toUint32(reference_semantics.getValue(right)));
};

/**
 *
 */
var signedRightShiftOperator = function(left, right) {
    return number_semantics.signedRightShift(
        type_conversion.toInt32(reference_semantics.getValue(left)),
        type_conversion.toUint32(reference_semantics.getValue(right)));
};

/**
 *
 */
var unsignedRightShiftOperator = function(left, right) {
    return number_semantics.unsignedRightShift(
        type_conversion.toInt32(reference_semantics.getValue(left)),
        type_conversion.toUint32(reference_semantics.getValue(right)));
};

/**
 *
 */
var bitwiseAndOperator = function(left, right) {
    return number_semantics.unsignedRightShift(
        type_conversion.toInt32(reference_semantics.getValue(left)),
        type_conversion.toInt32(reference_semantics.getValue(right)));
};

/**
 *
 */
var bitwiseXorOperator = function(left, right) {
    return number_semantics.unsignedRightShift(
        type_conversion.toInt32(reference_semantics.getValue(left)),
        type_conversion.toInt32(reference_semantics.getValue(right)));
};

/**
 *
 */
var bitwiseOrOperator = function(left, right) {
    return number_semantics.unsignedRightShift(
        type_conversion.toInt32(reference_semantics.getValue(left)),
        type_conversion.toInt32(reference_semantics.getValue(right)));
};

/* Binary Relational Operators
 *
 * @TODO Should we return undefined values when NaN is used?
 ******************************************************************************/
var _relationalOperator = function(op) {
    return function(left, right) {
        return op(
            type_conversion.toNumber(reference_semantics.getValue(left)),
            type_conversion.toNumber(reference_semantics.getValue(right)));
    };
};

/**
 *
 */
var ltOperator = _relationalOperator(number_semantics.lt);

/**
 *
 */
var lteOperator = _relationalOperator(number_semantics.lte);

/**
 *
 */
var gtOperator = _relationalOperator(number_semantics.gt);

/**
 *
 */
var gteOperator = _relationalOperator(number_semantics.gte);

var instanceofOperator = function(left, right) {
    return compute.bind(
        reference.getValue(left),
        function(l) {
            return compute.bind(
                reference.getValue(right),
                function(r) {
                    return function(ctx, ok, err) {
                        if (value.type(r) !== 'object') {
                            return err('Instanceof', ctx);
                        }
                        return ok(value.hasInstance(l), ctx);
                    };
                });
        });
};

var inOperator;

/* Unary Operator Semantics
 ******************************************************************************/
/**
 *
 */
var unaryPlusOperator = function(argument) {
    return type_conversion.toNumber(reference_semantics.getValue(argument));
};

/**
 *
 */
var unaryMinusOperator = function(argument) {
    return number_semantics.negate(type_conversion.toNumber(reference_semantics.getValue(argument)));
};

/**
 *
 */
var logicalNotOperator = function(argument) {
    return boolean.logicalNot(type_conversion.toBoolean(reference_semantics.getValue(argument)));
};

var bitwiseNotOperator = function(argument) {
    return number_semantics.bitwiseNot(type_conversion.toInt32(reference_semantics.getValue(argument)));
};

/**
 *
 */
var voidOperator = function(argument) {
    return compute.next(reference_semantics.getValue(argument)),
        compute.always(new undef.Undefined());
};

/**
 *
 */
var typeofOperator = function(argument) {
    return compute.bind(argument, function(val) {
        if (val instanceof reference_semantics.Reference) {
            return (reference_semantics.isUnresolvableReference(val) ?
                compute.always("undefined") :
                typeofOperator(reference_semantics.getValue(val)));
        }
        return compute.always(value.type(val));
    });
};

/* Update Operator Semantics
 ******************************************************************************/
var _prefixOperator = function(op) {
    return function(argument) {
        return compute.bind(argument, op);
    };
};

var _postfixOperator = function(op) {
    return function(argument) {
        return compute.bind(argument, function(oldValue) {
            return compute.next(
                op(oldValue),
                compute.always(oldValue));
        });
    };
};

var _increment = function(expr) {
    return compute.bind(
        type_conversion.toNumber(reference_semantics.getValue(compute.always(expr))),
        function(oldValue) {
            return reference_semantics.putValue(compute.always(expr), compute.always(number.add(oldValue, new number.Number(1))));
        });
};

var _decrement = function(expr) {
    return compute.bind(
        type_conversion.toNumber(reference_semantics.getValue(compute.always(expr))),
        function(oldValue) {
            return reference_semantics.putValue(compute.always(expr), compute.always(number.add(oldValue, new number.Number(-1))));
        });
};

/**
 *
 */
var prefixIncrement = _prefixOperator(_increment);

/**
 *
 */
var postfixIncrement =  _postfixOperator(_increment);

/**
 *
 */
var prefixDecrement = _prefixOperator(_decrement);

/**
 *
 */
var postfixDecrement =  _postfixOperator(_decrement);

/* Logical Binary Operator Semantics
 ******************************************************************************/
/**
 * Semantics for a logical or operation. Shorts when left evaluates to true.
 */
var logicalOr = function(left, right) {
    return compute.bind(
        type_conversion.toBoolean(reference_semantics.getValue(left)),
        function(result) {
            return (result.value === true ?
                left :
                right);
    });
};

/**
 * Semantics for a logical and operation. Shorts when left evaluates to false.
 */
var logicalAnd = function(left, right) {
    return compute.bind(
        type_conversion.toBoolean(reference_semantics.getValue(left)),
        function(result) {
            return (result.value === true ?
                right :
                left);
        });
};

/*
 ******************************************************************************/
/**
 * Semantics for a conditional Expression.
 */
var conditionalExpression = function(test, consequent, alternate) {
    return compute.bind(
        type_conversion.toBoolean(reference_semantics.getValue(test)),
        function(x) {
            return reference_semantics.getValue(x.value ?
                consequent :
                alternate);
        });
};

/**
 * Semantics for a sequence of expressions.
 */
var sequenceExpression = function(expressions) {
    return (expressions.length === 1 ?
        reference_semantics.getValue(expressions[0]) :
        compute.next(
            reference_semantics.getValue(expressions[0]),
            sequenceExpression(expressions.slice(1))));
};

/* Assignment Semantics
 ******************************************************************************/
var _dereference = function(lref) {
    if (lref instanceof reference.Reference &&
        lref.strict &&
        lref.base instanceof e
        (lref.name === "eval" || lref.name === "arguments")) {
        return compute.never("Using eval/arguments in stricts");
    }
    return compute.always(lref);
};

/**
 * Semantics for simple assignment.
 */
var assignment = function(left, right) {
    return reference_semantics.putValue(
        compute.bind(left, _dereference),
        reference_semantics.getValue(right));
};

/**
 * Semantics for an assignment that modifies a value assigned value by
 * operating on its current value.
 */
var compoundAssignment = function(op) {
    return function(left, right) {
        return reference_semantics.putValue(
            compute.bind(left, _dereference),
            op(
                reference_semantics.getValue(left),
                reference_semantics.getValue(right)));
    };
};

/* Declaration Semantics
 ******************************************************************************/
/**
 * Semantics for a variable declaration.
 */
var variableDeclaration = function(declarations) {
    return declarations.reduce(compute.next);
};

/**
 * Semantics for a single variable declarator.
 */
var variableDeclarator = function(id, init) {
    return compute.bind(reference_semantics.getValue(init), function(x) {
        return function(ctx, ok, err) {
            var newCtx = new execution_context.ExecutionContext(
                ctx.type,
                ctx.strict,
                environment.putIdentifierReference(ctx.lexicalEnvironment, id, x),
                ctx.variableEnvironment,
                ctx.thisBinding);
            return ok(x, newCtx);
        };
    });
};

/* Values
 ******************************************************************************/
var numberLiteral = function(value) {
    return compute.always(new number.Number(value));
};

var booleanLiteral = function(value) {
    return compute.always(new boolean.Boolean(value));
};

var stringLiteral = function(value) {
    return compute.always(new string.String(value));
};

var identifier = function(name) {
    return environment_semantics.getIdentifierReference(name);
};

/* Export
 ******************************************************************************/
return {
// Statement Semantics
    'statementList': statementList,
    'expressionStatement': expressionStatement,
    'returnStatement': returnStatement,
    'throwStatement': throwStatement,
    'breakStatement': breakStatement,
    'continueStatement': continueStatement,

// Binary Operator Semantics
    'addOperator': addOperator,
    'subtractOperator': subtractOperator,
    'multiplyOperator': multiplyOperator,
    'divideOperator': divideOperator,
    'remainderOperator': remainderOperator,

    'leftShiftOperator': leftShiftOperator,
    'signedRightShiftOperator': signedRightShiftOperator,
    'unsignedRightShiftOperator': unsignedRightShiftOperator,
    'bitwiseAndOperator': bitwiseAndOperator,
    'bitwiseXorOperator': bitwiseXorOperator,
    'bitwiseOrOperator': bitwiseOrOperator,

//Binary Relational Operator Semantics
    'ltOperator': ltOperator,
    'lteOperator': lteOperator,
    'gtOperator': gtOperator,
    'gteOperator': gteOperator,
    'instanceofOperator': instanceofOperator,
    'inOperator': inOperator,

// Increment and Decrement Operator Semantics
    'prefixIncrement': prefixIncrement,
    'postfixIncrement': postfixIncrement,
    'prefixDecrement': prefixDecrement,
    'postfixDecrement': postfixDecrement,

// Unary Operator Semantics
    'unaryPlusOperator': unaryPlusOperator,
    'unaryMinusOperator': unaryMinusOperator,
    'logicalNotOperator': logicalNotOperator,
    'bitwiseNotOperator': bitwiseNotOperator,
    'voidOperator': voidOperator,
    'typeofOperator': typeofOperator,

    // Logical Semantics
    'logicalOr': logicalOr,
    'logicalAnd': logicalAnd,

// Expression Semantics
    'conditionalExpression': conditionalExpression,
    'sequenceExpression': sequenceExpression,

// Assignment
    'assignment': assignment,
    'compoundAssignment': compoundAssignment,

// Declaration Semantics
    'variableDeclaration': variableDeclaration,
    'variableDeclarator': variableDeclarator,

// Values
    'numberLiteral': numberLiteral,
    'booleanLiteral': booleanLiteral,
    'stringLiteral': stringLiteral,
    'identifier': identifier
};

});<|endoftext|>


<commit_before>'use strict';

var natmus = require('natmus-js');
var Q = require('q');
// Used to parse a UTF16-LE to UTF16-BE string.
var Iconv  = require('iconv').Iconv;
var config = require('../config/config');

var nm = new natmus.NatmusClient();
var originalRequest = nm.request.bind(nm);

nm.initSession = function(forceInit) {
  if (!this.isConnected() || forceInit) {
    if (!config.cip.username || !config.cip.password) {
      throw new Error('Please set CIP username and password!');
    }
    return this.sessionOpen(config.cip.username, config.cip.password).then(() => {
      return this;
    }, (err) => {
      if (!err) {
        throw new Error('Could not open CIP session: ' +
                        'Check connection, username and password.');
      } else {
        throw err;
      }
    });
  } else {
    return new Q(this);
  }
};

nm.request = function(operation, namedParameters, data) {
  var performRequest = () => {
    // Try to do the operation
    return originalRequest(operation, namedParameters, data)
    .then(undefined, (err) => {
      console.error('Error communicating with CIP (retrying): ' + err.message);
      // Let's reinitialize the session and try again.
      return this.initSession(true).then(() => {
        return originalRequest(operation, namedParameters, data);
      });
    });
  };

  var operationString = typeof(operation) === 'string' ?
                        operation :
                        operation.join('/');

  if (!this.isConnected() && operationString !== 'session/open') {
    // Open a session and then perform the request.
    return this.initSession().then(performRequest);
  } else {
    return performRequest();
  }
};

nm.getRecentAssets = function(nm, catalog, fromDate) {
  var searchString = '"Record Modification Date" >= ' + fromDate;
  return nm.criteriaSearch({
    catalog: catalog
  }, searchString, null);
};

nm.setFieldValues = function(catalogAlias, id, view, values) {
  var operation = [
    'metadata',
    'setfieldvalues',
    catalogAlias,
    view
  ].join('/');

  values.id = parseInt(id);
  return this.request(operation, {}, {
    items: [values]
  });
};

nm.findCatalog = function(catalogs, alias) {
  for (var i = 0; i < catalogs.length; ++i) {
    if (catalogs[i].alias === alias) {
      return catalogs[i];
    }
  }
  return null;
};

nm.getRelatedAssets = function(asset, relation) {
  if (asset && relation) {
    return asset.getRelatedAssets(relation);
  } else {
    throw new Error('The asset or relation was not provided.');
  }
};

/*
var depth = 0;

function depthTabs() {
    var result = '';
    for (var d = 0; d < depth; d++) {
        result += '\t';
    }
    return result;
}
*/

var utf16BE2LE = new Iconv('UTF-16BE', 'UTF-16LE');

// We need to use this jshint option, because the three functions reference
// each other circularly value -> list -> element -> value -> ...
/* jshint latedef:nofunc */

function parseBinaryValue(buf, type) {
  if (type === 'UChr') {
    return utf16BE2LE.convert(buf).toString('utf16le');
  } else if (type === 'list') {
    return parseBinaryList(buf);
  } else if (type === 'gUid') {
    if (buf.length !== 16) {
      throw new Error('Expected a gUid buffer to be of length 16.');
    }
    var parts = [
      buf.slice(0, 4).toString('hex'),
      buf.slice(4, 6).toString('hex'),
      buf.slice(6, 8).toString('hex'),
      buf.slice(8, 10).toString('hex'),
      buf.slice(10, 16).toString('hex')
    ];
    return parts.join('-');
  } else if (type === 'Long') {
    if (buf.length !== 4) {
      throw new Error('Expected a Long buffer to be of length 4.');
    }
    return buf.readUInt32BE(0);
  } else {
    throw new Error('binary_value: Unimplemented type ' + type);
  }
}

function parseBinaryElement(buf, type) {
  var fieldCount = buf.readUInt32BE(0);
  // console.log(depth_tabs(), 'Parsing binary element type', type, 'size',
  //     buf.length, 'with', fieldCount, 'fields.');

  var result = {
    'type': type
  };

  var offset = 4;
  // depth++;
  for (var f = 0; f < fieldCount; f++) {
    // console.log(depth_tabs(), 'Parsing binary field indexed', f);
    // console.log(depth_tabs(), buf.slice(offset), buf.slice(offset).toString());
    var fieldSize = buf.readUInt32BE(offset);
    // console.log(depth_tabs(), 'Field size:', fieldSize);
    var fieldName = buf.slice(offset + 4, offset + 8).toString('utf8');
    // console.log(depth_tabs(), 'Field name:', fieldName);
    var fieldType = buf.slice(offset + 8, offset + 12).toString('utf8');
    // console.log(depth_tabs(), 'Field type:', fieldType);
    var fieldBuffer = buf.slice(offset + 12, offset + fieldSize + 12);
    var fieldValue = parseBinaryValue(fieldBuffer, fieldType);
    // The CIP has a bug where a null-terminated string's size
    // does not include the two null bytes in the field size.
    // If we read the 4 bytes just after the field value's buffer and
    // they are all zero's, this is probably not the length of the next
    // field's value, thus this the two first are assumed to be null bytes
    // from the string.
    // To make sure we don't read outside the stream, we check the bounds.
    if (f < fieldCount - 1) {
      var checked = buf.readUInt32BE(offset + fieldSize + 12);
      if (fieldType === 'UChr' && checked === 0 && f !== fieldCount - 1) {
        fieldSize += 2;
      }
    }
    // console.log(depth_tabs(), 'Field value:', fieldValue);
    result[fieldName] = fieldValue;

    offset += fieldSize + 12;
  }
  // depth--;

  return result;
}

function parseBinaryList(buf) {
  var listLength = buf.readUInt32BE(0);
  // console.log( depth_tabs(), 'Parsing a list of length', listLength );
  var result = [];

  var offset = 4;
  // depth++;
  for (var i = 0; i < listLength; i++) {
    // console.log( depth_tabs(), 'Parsing a list element indexed', i );
    var elementSize = buf.readUInt32BE(offset);
    // console.log( depth_tabs(), 'List element indexed', i, 'has size', elementSize );
    var elementType = buf.slice(offset + 4, offset + 8).toString('utf8');
    // console.log( depth_tabs(), 'List element indexed', i, 'has type', elementType );
    var elementBuffer = buf.slice(offset + 8, offset + elementSize + 8);
    var element = parseBinaryElement(elementBuffer, elementType);
    result.push(element);
    offset += elementSize + 8;
  }
  // depth--;

  return result;
}

// Parse binary field value (64 encoded string) to object.
nm.binaryToObject = function(binaryBase64Encoded) {
  if (binaryBase64Encoded) {
    var buf = new Buffer(binaryBase64Encoded, 'base64');
    // We expect that we start with a list.
    var type = buf.slice(0, 4).toString('utf8');
    var elementBuffer = buf.slice(4);
    return parseBinaryValue(elementBuffer, type);
  } else {
    return null;
  }
};

nm.parseBinaryRelations = function(binaryBase64Encoded) {
  var result = [];
  var relatedAssets = this.binaryToObject(binaryBase64Encoded);
  if (relatedAssets) {
    // Perform a transformation.
    for (var r in relatedAssets) {
      var relatedAsset = relatedAssets[r];
      if (relatedAsset.type !== 'reco') {
        continue;
      }

      for (var ref in relatedAsset.Refs) {
        var reference = relatedAsset.Refs[ref];
        if (reference.type !== 'reco') {
          continue;
        }

        result.push({
          id: reference.RcID,
          filename: relatedAsset.Name,
          relation: reference.RlID
        });
      }
    }
  }
  return result;
};

module.exports = nm;
<commit_msg>Fixing linting<commit_after>'use strict';

var natmus = require('natmus-js');
var Q = require('q');
// Used to parse a UTF16-LE to UTF16-BE string.
var Iconv  = require('iconv').Iconv;
var config = require('../config/config');

var nm = new natmus.NatmusClient();
var originalRequest = nm.request.bind(nm);

nm.initSession = function(forceInit) {
  if (!this.isConnected() || forceInit) {
    if (!config.cip.username || !config.cip.password) {
      throw new Error('Please set CIP username and password!');
    }
    return this.sessionOpen(config.cip.username, config.cip.password)
    .then(() => {
      return this;
    }, (err) => {
      if (!err) {
        throw new Error('Could not open CIP session: ' +
                        'Check connection, username and password.');
      } else {
        throw err;
      }
    });
  } else {
    return new Q(this);
  }
};

nm.request = function(operation, namedParameters, data) {
  var performRequest = () => {
    // Try to do the operation
    return originalRequest(operation, namedParameters, data)
    .then(undefined, (err) => {
      console.error('Error communicating with CIP (retrying): ' + err.message);
      // Let's reinitialize the session and try again.
      return this.initSession(true).then(() => {
        return originalRequest(operation, namedParameters, data);
      });
    });
  };

  var operationString = typeof(operation) === 'string' ?
                        operation :
                        operation.join('/');

  if (!this.isConnected() && operationString !== 'session/open') {
    // Open a session and then perform the request.
    return this.initSession().then(performRequest);
  } else {
    return performRequest();
  }
};

nm.getRecentAssets = function(nm, catalog, fromDate) {
  var searchString = '"Record Modification Date" >= ' + fromDate;
  return nm.criteriaSearch({
    catalog: catalog
  }, searchString, null);
};

nm.setFieldValues = function(catalogAlias, id, view, values) {
  var operation = [
    'metadata',
    'setfieldvalues',
    catalogAlias,
    view
  ].join('/');

  values.id = parseInt(id);
  return this.request(operation, {}, {
    items: [values]
  });
};

nm.findCatalog = function(catalogs, alias) {
  for (var i = 0; i < catalogs.length; ++i) {
    if (catalogs[i].alias === alias) {
      return catalogs[i];
    }
  }
  return null;
};

nm.getRelatedAssets = function(asset, relation) {
  if (asset && relation) {
    return asset.getRelatedAssets(relation);
  } else {
    throw new Error('The asset or relation was not provided.');
  }
};

/*
var depth = 0;

function depthTabs() {
    var result = '';
    for (var d = 0; d < depth; d++) {
        result += '\t';
    }
    return result;
}
*/

var utf16BE2LE = new Iconv('UTF-16BE', 'UTF-16LE');

// We need to use this jshint option, because the three functions reference
// each other circularly value -> list -> element -> value -> ...
/* jshint latedef:nofunc */

function parseBinaryValue(buf, type) {
  if (type === 'UChr') {
    return utf16BE2LE.convert(buf).toString('utf16le');
  } else if (type === 'list') {
    return parseBinaryList(buf);
  } else if (type === 'gUid') {
    if (buf.length !== 16) {
      throw new Error('Expected a gUid buffer to be of length 16.');
    }
    var parts = [
      buf.slice(0, 4).toString('hex'),
      buf.slice(4, 6).toString('hex'),
      buf.slice(6, 8).toString('hex'),
      buf.slice(8, 10).toString('hex'),
      buf.slice(10, 16).toString('hex')
    ];
    return parts.join('-');
  } else if (type === 'Long') {
    if (buf.length !== 4) {
      throw new Error('Expected a Long buffer to be of length 4.');
    }
    return buf.readUInt32BE(0);
  } else {
    throw new Error('binary_value: Unimplemented type ' + type);
  }
}

function parseBinaryElement(buf, type) {
  var fieldCount = buf.readUInt32BE(0);
  // console.log(depth_tabs(), 'Parsing binary element type', type, 'size',
  //     buf.length, 'with', fieldCount, 'fields.');

  var result = {
    'type': type
  };

  var offset = 4;
  // depth++;
  for (var f = 0; f < fieldCount; f++) {
    // console.log(depth_tabs(), 'Parsing binary field indexed', f);
    // console.log(depth_tabs(), buf.slice(offset), buf.slice(offset).toString());
    var fieldSize = buf.readUInt32BE(offset);
    // console.log(depth_tabs(), 'Field size:', fieldSize);
    var fieldName = buf.slice(offset + 4, offset + 8).toString('utf8');
    // console.log(depth_tabs(), 'Field name:', fieldName);
    var fieldType = buf.slice(offset + 8, offset + 12).toString('utf8');
    // console.log(depth_tabs(), 'Field type:', fieldType);
    var fieldBuffer = buf.slice(offset + 12, offset + fieldSize + 12);
    var fieldValue = parseBinaryValue(fieldBuffer, fieldType);
    // The CIP has a bug where a null-terminated string's size
    // does not include the two null bytes in the field size.
    // If we read the 4 bytes just after the field value's buffer and
    // they are all zero's, this is probably not the length of the next
    // field's value, thus this the two first are assumed to be null bytes
    // from the string.
    // To make sure we don't read outside the stream, we check the bounds.
    if (f < fieldCount - 1) {
      var checked = buf.readUInt32BE(offset + fieldSize + 12);
      if (fieldType === 'UChr' && checked === 0 && f !== fieldCount - 1) {
        fieldSize += 2;
      }
    }
    // console.log(depth_tabs(), 'Field value:', fieldValue);
    result[fieldName] = fieldValue;

    offset += fieldSize + 12;
  }
  // depth--;

  return result;
}

function parseBinaryList(buf) {
  var listLength = buf.readUInt32BE(0);
  // console.log( depth_tabs(), 'Parsing a list of length', listLength );
  var result = [];

  var offset = 4;
  // depth++;
  for (var i = 0; i < listLength; i++) {
    // console.log( depth_tabs(), 'Parsing a list element indexed', i );
    var elementSize = buf.readUInt32BE(offset);
    // console.log( depth_tabs(), 'List element indexed', i, 'has size', elementSize );
    var elementType = buf.slice(offset + 4, offset + 8).toString('utf8');
    // console.log( depth_tabs(), 'List element indexed', i, 'has type', elementType );
    var elementBuffer = buf.slice(offset + 8, offset + elementSize + 8);
    var element = parseBinaryElement(elementBuffer, elementType);
    result.push(element);
    offset += elementSize + 8;
  }
  // depth--;

  return result;
}

// Parse binary field value (64 encoded string) to object.
nm.binaryToObject = function(binaryBase64Encoded) {
  if (binaryBase64Encoded) {
    var buf = new Buffer(binaryBase64Encoded, 'base64');
    // We expect that we start with a list.
    var type = buf.slice(0, 4).toString('utf8');
    var elementBuffer = buf.slice(4);
    return parseBinaryValue(elementBuffer, type);
  } else {
    return null;
  }
};

nm.parseBinaryRelations = function(binaryBase64Encoded) {
  var result = [];
  var relatedAssets = this.binaryToObject(binaryBase64Encoded);
  if (relatedAssets) {
    // Perform a transformation.
    for (var r in relatedAssets) {
      var relatedAsset = relatedAssets[r];
      if (relatedAsset.type !== 'reco') {
        continue;
      }

      for (var ref in relatedAsset.Refs) {
        var reference = relatedAsset.Refs[ref];
        if (reference.type !== 'reco') {
          continue;
        }

        result.push({
          id: reference.RcID,
          filename: relatedAsset.Name,
          relation: reference.RlID
        });
      }
    }
  }
  return result;
};

module.exports = nm;
<|endoftext|>


<commit_before>var natmus = require('natmus-js'),
    cache = require('memory-cache'),
    Q = require('q'),
    Iconv  = require('iconv').Iconv, // Used to parse a UTF16-LE to UTF16-BE string.
    request = require('request');

// Cache in 30 s.
var CACHE_TIME = 1000 * 30;

exports.initSession = function(forceInit) {
  var nm = cache.get('nm');

  if(nm && !forceInit) {
    return new Q(nm);
  } else {
    if(process.env.CIP_USERNAME === undefined || process.env.CIP_PASSWORD === undefined) {
      throw new Error("Please set CIP_USERNAME and CIP_PASSWORD!");
    }

    nm = new natmus.NatmusClient();
    return nm.sessionOpen(process.env.CIP_USERNAME, process.env.CIP_PASSWORD)
    .then(function() {
      console.log('CIP session initialized successfully:', nm.jsessionid);
      cache.put('nm', nm, CACHE_TIME);
      return nm;
    }, function() {
      throw new Error("Couldn't open session, check connection, username and password.");
    });
  }
};

exports.getCatalogs = function(nm) {
    var catalogs = cache.get('catalogs');
    if(catalogs) {
      return new Q(catalogs);
    } else {
	    return nm.getCatalogs().then(function(catalogs) {
        if(catalogs) {
          cache.put('catalogs', catalogs, CACHE_TIME);
          return catalogs;
        }
      });
    }
};

exports.getRecentAssets = function(nm, catalog, fromDate) {
    var searchString = '"Record Modification Date" >= ' + fromDate;
    return nm.criteriaSearch({
      catalog: catalog
    }, searchString, null);
};

exports.getAsset = function(nm, catalog, id) {
    var idString = 'ID is "' + id + '"';
    var cacheKey = 'asset_' + catalog + '_' + id;
    var asset = cache.get(cacheKey);

    if(asset) {
      return new Q(asset);
    } else {
      // Search for the id, no searchterm or sorting. The final boolean argument
      // tells the search to return a single asset, without creating an
      // intermediary result object.
      return nm.getAsset(catalog, id, true)
      .then(function(result) {
        if(result) {
          cache.put(cacheKey, result, CACHE_TIME);
          return result;
        }
      });
    }
};

exports.setFieldValues = function(nm, catalogAlias, id, view, values) {
  var operation = [
    'metadata',
    'setfieldvalues',
    catalogAlias,
    view
  ].join('/');

  values.id = parseInt(id);
  return nm.request(operation, {}, {
    items: [values]
  });
};

exports.findCatalog = function(catalogs, alias) {
    for(var i=0; i < catalogs.length; ++i) {
        if(catalogs[i].alias === alias) {
            return catalogs[i];
        }
    }
    return null;
};

exports.getRelatedAssets = function(asset, relation) {
    if(asset && relation) {
      return asset.getRelatedAssets(relation);
    } else {
      throw new Error("The asset or relation was not provided.");
    }
};

/*
var depth = 0;

function depthTabs() {
    var result = '';
    for(var d = 0; d < depth; d++) {
        result += '\t';
    }
    return result;
}
*/

var utf16_be2le = new Iconv('UTF-16BE', 'UTF-16LE');

// We need to use this jshint option, because the three functions reference
// each other circularly value -> list -> element -> value -> ...
/* jshint latedef:nofunc */

function parseBinaryValue( buf, type ) {
    if(type === 'UChr') {
        return utf16_be2le.convert(buf).toString('utf16le');
    } else if(type === 'list') {
        return parseBinaryList(buf);
    } else if(type === 'gUid') {
        if(buf.length !== 16) {
            throw new Error('Expected a gUid buffer to be of length 16.');
        }
        var parts = [
            buf.slice(0, 4).toString('hex'),
            buf.slice(4, 6).toString('hex'),
            buf.slice(6, 8).toString('hex'),
            buf.slice(8, 10).toString('hex'),
            buf.slice(10, 16).toString('hex')
        ];
        return parts.join('-');
    } else if(type === 'Long') {
        if(buf.length !== 4) {
            throw new Error('Expected a Long buffer to be of length 4.');
        }
        return buf.readUInt32BE(0);
    } else {
        throw new Error( 'binary_value: Unimplemented type ' + type );
    }
}

function parseBinaryElement( buf, type ) {
    var field_count = buf.readUInt32BE(0);
    // console.log(depth_tabs(), 'Parsing binary element type', type, 'size',
    //     buf.length, 'with', field_count, 'fields.');

    var result = { type: type };

    var offset = 4;
    // depth++;
    for(var f = 0; f < field_count; f++) {
        // console.log(depth_tabs(), 'Parsing binary field indexed', f);
        // console.log(depth_tabs(), buf.slice(offset), buf.slice(offset).toString());
        var field_size = buf.readUInt32BE(offset);
        // console.log(depth_tabs(), 'Field size:', field_size);
        var field_name = buf.slice(offset+4, offset+8).toString('utf8');
        // console.log(depth_tabs(), 'Field name:', field_name);
        var field_type = buf.slice(offset+8, offset+12).toString('utf8');
        // console.log(depth_tabs(), 'Field type:', field_type);
        var field_buffer = buf.slice(offset+12, offset+field_size+12);
        var field_value = parseBinaryValue(field_buffer, field_type);
        // The CIP has a bug where a null-terminated string's size
        // does not include the two null bytes in the field size.
        // If we read the 4 bytes just after the field value's buffer and
        // they are all zero's, this is probably not the length of the next
        // field's value, thus this the two first are assumed to be null bytes
        // from the string.
        // To make sure we don't read outside the stream, we check the bounds.
        if(f < field_count-1) {
            var checked = buf.readUInt32BE(offset+field_size+12);
            if(field_type === 'UChr' && checked === 0 && f !== field_count-1) {
                field_size+=2;
            }
        }
        // console.log(depth_tabs(), 'Field value:', field_value);
        result[field_name] = field_value;

        offset += field_size+12;
    }
    // depth--;

    return result;
}

function parseBinaryList( buf ) {
    var list_length = buf.readUInt32BE(0);
    // console.log( depth_tabs(), 'Parsing a list of length', list_length );
    var result = [];

    var offset = 4;
    // depth++;
    for(var i = 0; i < list_length; i++) {
        // console.log( depth_tabs(), 'Parsing a list element indexed', i );
        var element_size = buf.readUInt32BE(offset);
        // console.log( depth_tabs(), 'List element indexed', i, 'has size', element_size );
        var element_type = buf.slice(offset+4, offset+8).toString('utf8');
        // console.log( depth_tabs(), 'List element indexed', i, 'has type', element_type );
        var element_buffer = buf.slice(offset+8, offset+element_size+8);
        var element = parseBinaryElement(element_buffer, element_type);
        result.push( element );
        offset += element_size+8;
    }
    // depth--;

    return result;
}

// Parse binary field value (64 encoded string) to object.
exports.binaryToObject = function(binary_base64_encoded) {
    if(binary_base64_encoded) {
        var buf = new Buffer( binary_base64_encoded, 'base64' );
        // We expect that we start with a list.
        var type = buf.slice(0, 4).toString('utf8');
        var element_buffer = buf.slice(4);
        return parseBinaryValue( element_buffer, type );
    } else {
        return null;
    }
};

exports.parseBinaryRelations = function(binary_base64_encoded) {
    var result = [];
    var related_assets = exports.binaryToObject(binary_base64_encoded);
    if(related_assets) {
        // Perform a transformation.
        for(var r in related_assets) {
            var related_asset = related_assets[r];
            if(related_asset.type !== 'reco') {
                continue;
            }

            for(var ref in related_asset.Refs) {
                var reference = related_asset.Refs[ref];
                if(reference.type !== 'reco') {
                    continue;
                }

                result.push({
                    id: reference.RcID,
                    filename: related_asset.Name,
                    relation: reference.RlID
                });
            }
        }
    }
    return result;
};
<commit_msg>Longer cache time on the Cumulus CIP client.<commit_after>var natmus = require('natmus-js'),
    cache = require('memory-cache'),
    Q = require('q'),
    Iconv  = require('iconv').Iconv, // Used to parse a UTF16-LE to UTF16-BE string.
    request = require('request');

// Cache in 30 s.
var CACHE_TIME = 1000 * 30;
// Cache the client for 10 minutes.
var CLIENT_CACHE_TIME = 1000 * 60 * 10;

exports.initSession = function(forceInit) {
  var nm = cache.get('nm');

  if(nm && !forceInit) {
    return new Q(nm);
  } else {
    if(process.env.CIP_USERNAME === undefined || process.env.CIP_PASSWORD === undefined) {
      throw new Error("Please set CIP_USERNAME and CIP_PASSWORD!");
    }

    nm = new natmus.NatmusClient();
    return nm.sessionOpen(process.env.CIP_USERNAME, process.env.CIP_PASSWORD)
    .then(function() {
      console.log('CIP session initialized successfully:', nm.jsessionid);
      cache.put('nm', nm, CLIENT_CACHE_TIME);
      return nm;
    }, function() {
      throw new Error("Couldn't open session, check connection, username and password.");
    });
  }
};

exports.getCatalogs = function(nm) {
    var catalogs = cache.get('catalogs');
    if(catalogs) {
      return new Q(catalogs);
    } else {
	    return nm.getCatalogs().then(function(catalogs) {
        if(catalogs) {
          cache.put('catalogs', catalogs, CACHE_TIME);
          return catalogs;
        }
      });
    }
};

exports.getRecentAssets = function(nm, catalog, fromDate) {
    var searchString = '"Record Modification Date" >= ' + fromDate;
    return nm.criteriaSearch({
      catalog: catalog
    }, searchString, null);
};

exports.getAsset = function(nm, catalog, id) {
    var idString = 'ID is "' + id + '"';
    var cacheKey = 'asset_' + catalog + '_' + id;
    var asset = cache.get(cacheKey);

    if(asset) {
      return new Q(asset);
    } else {
      // Search for the id, no searchterm or sorting. The final boolean argument
      // tells the search to return a single asset, without creating an
      // intermediary result object.
      return nm.getAsset(catalog, id, true)
      .then(function(result) {
        if(result) {
          cache.put(cacheKey, result, CACHE_TIME);
          return result;
        }
      });
    }
};

exports.setFieldValues = function(nm, catalogAlias, id, view, values) {
  var operation = [
    'metadata',
    'setfieldvalues',
    catalogAlias,
    view
  ].join('/');

  values.id = parseInt(id);
  return nm.request(operation, {}, {
    items: [values]
  });
};

exports.findCatalog = function(catalogs, alias) {
    for(var i=0; i < catalogs.length; ++i) {
        if(catalogs[i].alias === alias) {
            return catalogs[i];
        }
    }
    return null;
};

exports.getRelatedAssets = function(asset, relation) {
    if(asset && relation) {
      return asset.getRelatedAssets(relation);
    } else {
      throw new Error("The asset or relation was not provided.");
    }
};

/*
var depth = 0;

function depthTabs() {
    var result = '';
    for(var d = 0; d < depth; d++) {
        result += '\t';
    }
    return result;
}
*/

var utf16_be2le = new Iconv('UTF-16BE', 'UTF-16LE');

// We need to use this jshint option, because the three functions reference
// each other circularly value -> list -> element -> value -> ...
/* jshint latedef:nofunc */

function parseBinaryValue( buf, type ) {
    if(type === 'UChr') {
        return utf16_be2le.convert(buf).toString('utf16le');
    } else if(type === 'list') {
        return parseBinaryList(buf);
    } else if(type === 'gUid') {
        if(buf.length !== 16) {
            throw new Error('Expected a gUid buffer to be of length 16.');
        }
        var parts = [
            buf.slice(0, 4).toString('hex'),
            buf.slice(4, 6).toString('hex'),
            buf.slice(6, 8).toString('hex'),
            buf.slice(8, 10).toString('hex'),
            buf.slice(10, 16).toString('hex')
        ];
        return parts.join('-');
    } else if(type === 'Long') {
        if(buf.length !== 4) {
            throw new Error('Expected a Long buffer to be of length 4.');
        }
        return buf.readUInt32BE(0);
    } else {
        throw new Error( 'binary_value: Unimplemented type ' + type );
    }
}

function parseBinaryElement( buf, type ) {
    var field_count = buf.readUInt32BE(0);
    // console.log(depth_tabs(), 'Parsing binary element type', type, 'size',
    //     buf.length, 'with', field_count, 'fields.');

    var result = { type: type };

    var offset = 4;
    // depth++;
    for(var f = 0; f < field_count; f++) {
        // console.log(depth_tabs(), 'Parsing binary field indexed', f);
        // console.log(depth_tabs(), buf.slice(offset), buf.slice(offset).toString());
        var field_size = buf.readUInt32BE(offset);
        // console.log(depth_tabs(), 'Field size:', field_size);
        var field_name = buf.slice(offset+4, offset+8).toString('utf8');
        // console.log(depth_tabs(), 'Field name:', field_name);
        var field_type = buf.slice(offset+8, offset+12).toString('utf8');
        // console.log(depth_tabs(), 'Field type:', field_type);
        var field_buffer = buf.slice(offset+12, offset+field_size+12);
        var field_value = parseBinaryValue(field_buffer, field_type);
        // The CIP has a bug where a null-terminated string's size
        // does not include the two null bytes in the field size.
        // If we read the 4 bytes just after the field value's buffer and
        // they are all zero's, this is probably not the length of the next
        // field's value, thus this the two first are assumed to be null bytes
        // from the string.
        // To make sure we don't read outside the stream, we check the bounds.
        if(f < field_count-1) {
            var checked = buf.readUInt32BE(offset+field_size+12);
            if(field_type === 'UChr' && checked === 0 && f !== field_count-1) {
                field_size+=2;
            }
        }
        // console.log(depth_tabs(), 'Field value:', field_value);
        result[field_name] = field_value;

        offset += field_size+12;
    }
    // depth--;

    return result;
}

function parseBinaryList( buf ) {
    var list_length = buf.readUInt32BE(0);
    // console.log( depth_tabs(), 'Parsing a list of length', list_length );
    var result = [];

    var offset = 4;
    // depth++;
    for(var i = 0; i < list_length; i++) {
        // console.log( depth_tabs(), 'Parsing a list element indexed', i );
        var element_size = buf.readUInt32BE(offset);
        // console.log( depth_tabs(), 'List element indexed', i, 'has size', element_size );
        var element_type = buf.slice(offset+4, offset+8).toString('utf8');
        // console.log( depth_tabs(), 'List element indexed', i, 'has type', element_type );
        var element_buffer = buf.slice(offset+8, offset+element_size+8);
        var element = parseBinaryElement(element_buffer, element_type);
        result.push( element );
        offset += element_size+8;
    }
    // depth--;

    return result;
}

// Parse binary field value (64 encoded string) to object.
exports.binaryToObject = function(binary_base64_encoded) {
    if(binary_base64_encoded) {
        var buf = new Buffer( binary_base64_encoded, 'base64' );
        // We expect that we start with a list.
        var type = buf.slice(0, 4).toString('utf8');
        var element_buffer = buf.slice(4);
        return parseBinaryValue( element_buffer, type );
    } else {
        return null;
    }
};

exports.parseBinaryRelations = function(binary_base64_encoded) {
    var result = [];
    var related_assets = exports.binaryToObject(binary_base64_encoded);
    if(related_assets) {
        // Perform a transformation.
        for(var r in related_assets) {
            var related_asset = related_assets[r];
            if(related_asset.type !== 'reco') {
                continue;
            }

            for(var ref in related_asset.Refs) {
                var reference = related_asset.Refs[ref];
                if(reference.type !== 'reco') {
                    continue;
                }

                result.push({
                    id: reference.RcID,
                    filename: related_asset.Name,
                    relation: reference.RlID
                });
            }
        }
    }
    return result;
};
<|endoftext|>


<commit_before>angular.module('spiral')
.factory('spiralGridGenerator', ['$document', function($document) {
	var scrollbar_size = measureScrollbar();

	return {
		makeTemplate: function($container, def, numberOfRows) {
			var model = generateColumnModel(def),
				rowAttrs = model.attrs,
				rowAttrTemplate = '',
				i;

			var columnsTemplate = model.reduce(function(prev, cur, idx) {
					var attrsTemplate = '',
						attrs = cur.attrs;

					attrs.style = 'width: ' + cur.width + ';' + (attrs.style || '');
					attrs['class'] = 's-col s-col-' + (idx + 1) + (attrs['class'] && ' ' + attrs['class'] || '');

					for(var p in attrs) {
						attrsTemplate += ' ' + p + '="' + attrs[p] + '"';
					}

					return prev + '
' + cur.content + '
';
				}, ''),
				body = '';

			for(i = 0; i < model.length; i++) {
				columnsTemplate = '
' + columnsTemplate + '
';
			}

			if(!def.is('[data-header]')) {
				rowAttrs['class'] = 's-row ng-hide' + (rowAttrs['class'] && ' ' + rowAttrs['class'] || '');

				for(var p in rowAttrs) {
					rowAttrTemplate += ' ' + p + '="' + rowAttrs[p] + '"';
				}

				for(i = 0; i < numberOfRows; i++) {
					body += '
' + columnsTemplate.replace(/dataItem/g, 'bucket[' + i + ']') + '
\n';
				}
			} else {
				body = columnsTemplate;
				$container.css('padding-right', scrollbar_size);
			}

			$container.html(body);
		},
		api: function($element, ctrl) {
			ctrl.toggleSelection = function(colIdx, selected) {
				$element.find('.s-col-' + colIdx + ' input').prop('checked', selected);
			}
			ctrl.removeItem = function(item, skipRecompute) {
				var buckets = ctrl.buckets,
					bucket,
					i = 0, x;

				for(; i < buckets.length; i++) {
					bucket = buckets[i];

					for(x = 0; x < bucket.length; x++) {
						if(bucket[x] === item) {
							bucket[x] = null;
							bucket.pristine = false;

							$element.find('.s-bucket:eq(' + i + ') .s-row:eq(' + x + ')').hide();

							if(!skipRecompute) {
								$element.trigger('spiral:re-compute');
							}

							return;
						}
					}
				}
			}
		}
	};

	function generateColumnModel(def) {
		var $items = def.children(),
			numOfAutoWidths = 0,
			cols = [],
			i, $el, autoWidth;

		cols.attrs = allAttrsButWidth(def);

		for(i = 0; i < $items.length; i++) {
			$el = $items.eq(i);

			switch($el.prop('tagName')) {
				case 'SPIRAL-COL':
					cols.push({
						title: $el.attr('title') || 'Column ' + i,
						width: $el.attr('width') || (++numOfAutoWidths && 'auto'),
						content: $el.html(),
						attrs: allAttrsButWidth($el)
					});
					break;
				default:
					throw new Error('Unknown column type ' + $items[i].tagName);
			}
		}

		if(numOfAutoWidths > 0) {
			autoWidth = (100 / numOfAutoWidths) + '%';

			if(numOfAutoWidths !== cols.length) {
				autoWidth = 'calc(' + autoWidth + ' - ' + cols.reduce(function(prev, cur) {
					if(cur.width !== 'auto') {
						prev.push((parseFloat(cur.width) / numOfAutoWidths) + cur.width.replace(/\d/g, ''));
					}

					return prev;
				}, []).join(' - ') + ')';
			}

			for(i = 0; i < cols.length; i++) {
				if(cols[i].width === 'auto') {
					cols[i].width = autoWidth;
				}
			}
		}

		return cols;
	}

	function allAttrsButWidth($el) {
		var nodeAttrs = $el[0].attributes,
			attrs = {},
			i = 0, c = nodeAttrs.length;

		for(;i < c; i++) {
			if(nodeAttrs[i].nodeName === 'width') {
				continue;
			}

			attrs[nodeAttrs[i].nodeName] = nodeAttrs[i].nodeValue;
		}

		return attrs;
	}

	function measureScrollbar() {
		var scrollDiv = angular.element('

')[0],
			body = $document[0].body;

		body.appendChild(scrollDiv);

		var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;

		body.removeChild(scrollDiv);

		return scrollbarWidth;
	}
}]);<commit_msg>Reducing canvas size.<commit_after>angular.module('spiral')
.factory('spiralGridGenerator', ['$document', function($document) {
	var scrollbar_size = measureScrollbar();

	return {
		makeTemplate: function($container, def, numberOfRows) {
			var model = generateColumnModel(def),
				rowAttrs = model.attrs,
				rowAttrTemplate = '',
				i;

			var columnsTemplate = model.reduce(function(prev, cur, idx) {
					var attrsTemplate = '',
						attrs = cur.attrs;

					attrs.style = 'width: ' + cur.width + ';' + (attrs.style || '');
					attrs['class'] = 's-col s-col-' + (idx + 1) + (attrs['class'] && ' ' + attrs['class'] || '');

					for(var p in attrs) {
						attrsTemplate += ' ' + p + '="' + attrs[p] + '"';
					}

					return prev + '
' + cur.content + '
';
				}, ''),
				body = '';

			for(i = 0; i < model.length; i++) {
				columnsTemplate = '
' + columnsTemplate + '
';
			}

			if(!def.is('[data-header]')) {
				rowAttrs['class'] = 's-row ng-hide' + (rowAttrs['class'] && ' ' + rowAttrs['class'] || '');

				for(var p in rowAttrs) {
					rowAttrTemplate += ' ' + p + '="' + rowAttrs[p] + '"';
				}

				for(i = 0; i < numberOfRows; i++) {
					body += '
' + columnsTemplate.replace(/dataItem/g, 'bucket[' + i + ']') + '
\n';
				}
			} else {
				body = columnsTemplate;
				$container.css('padding-right', scrollbar_size);
			}

			$container.html(body);
		},
		api: function($element, ctrl) {
			ctrl.toggleSelection = function(colIdx, selected) {
				$element.find('.s-col-' + colIdx + ' input').prop('checked', selected);
			}
			ctrl.removeItem = function(item, skipRecompute) {
				var buckets = ctrl.buckets,
					bucket,
					i = 0, x;

				for(; i < buckets.length; i++) {
					bucket = buckets[i];

					for(x = 0; x < bucket.length; x++) {
						if(bucket[x] === item) {
							bucket[x] = null;
							bucket.pristine = false;

							$element.find('.s-bucket:eq(' + i + ') .s-row:eq(' + x + ')').hide();

							if(!skipRecompute) {
								$element.trigger('spiral:re-compute');
							}

							return;
						}
					}
				}
			}
		}
	};

	function generateColumnModel(def) {
		var $items = def.children(),
			numOfAutoWidths = 0,
			cols = [],
			i, $el, autoWidth;

		cols.attrs = allAttrsButWidth(def);

		for(i = 0; i < $items.length; i++) {
			$el = $items.eq(i);

			switch($el.prop('tagName')) {
				case 'SPIRAL-COL':
					cols.push({
						title: $el.attr('title') || 'Column ' + i,
						width: $el.attr('width') || (++numOfAutoWidths && 'auto'),
						content: $el.html(),
						attrs: allAttrsButWidth($el)
					});
					break;
				default:
					throw new Error('Unknown column type ' + $items[i].tagName);
			}
		}

		if(numOfAutoWidths > 0) {
			autoWidth = (100 / numOfAutoWidths) + '%';

			if(numOfAutoWidths !== cols.length) {
				autoWidth = 'calc(' + autoWidth + ' - ' + cols.reduce(function(prev, cur) {
					if(cur.width !== 'auto') {
						prev.push((parseFloat(cur.width) / numOfAutoWidths) + cur.width.replace(/\d/g, ''));
					}

					return prev;
				}, []).join(' - ') + ')';
			}

			for(i = 0; i < cols.length; i++) {
				if(cols[i].width === 'auto') {
					cols[i].width = autoWidth;
				}
			}
		}

		return cols;
	}

	function allAttrsButWidth($el) {
		var nodeAttrs = $el[0].attributes,
			attrs = {},
			i = 0, c = nodeAttrs.length;

		for(;i < c; i++) {
			if(nodeAttrs[i].nodeName === 'width') {
				continue;
			}

			attrs[nodeAttrs[i].nodeName] = nodeAttrs[i].nodeValue;
		}

		return attrs;
	}

	function measureScrollbar() {
		var scrollDiv = angular.element('

')[0],
			body = $document[0].body;

		body.appendChild(scrollDiv);

		var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;

		body.removeChild(scrollDiv);

		return scrollbarWidth;
	}
}]);<|endoftext|>


<commit_before>export default ({
  cacheHit,
  renderCycles,
  props,
  context,
  startTime,
  endTime,
  filteredProps,
  keyValues,
  passedOnProps,
  // If we added any css it will be the last element
  generatedCss
}) => {
  if (
    typeof console !== 'undefined' &&
    typeof console.groupCollapsed !== 'undefined'
  ) {
    const duration = endTime.getTime() - startTime.getTime();

    const title = [
      `${renderCycles}`,
      `%c${props.__swissOptions.type}`,
      `%c${cacheHit ? 'HIT' : 'MISS'}`,
      `%c${duration}ms`
    ];
    const styles = [
      'color: gray; font-weight: lighter;',
      '',
      cacheHit ? 'color: green;' : 'color: red;',
      duration > 1 ? '' : 'color: gray; font-weight: lighter;'
    ];
    if (passedOnProps.className) {
      title.push(`%c.${passedOnProps.className.split(' ')[1]}`);
      styles.push('color: gray; font-weight: lighter;');
    }
    if (passedOnProps.style) {
      title.push(`%cinline`);
      styles.push('color: gray; font-weight: lighter;');
    }

    console.groupCollapsed(`%c ${title.join(' ')}`, ...styles);

    console.groupCollapsed(
      '%cstarted component render()',
      'color:black; font-weight: normal;'
    );
    console.log('with these options');
    console.log(
      JSON.stringify(
        Object.assign({}, context.options, props.__swissOptions),
        null,
        2
      )
    );
    console.groupEnd();

    console.groupCollapsed(
      '%casking for styles with props prepareToRender()',
      'color:black; font-weight: normal;'
    );
    console.log('%ccomponent props', 'color: black; font-weight: bold;');
    console.log(props);
    console.log(
      'and %ccontext props <SW.ProvideContext ...>',
      'color: black; font-weight: bold;'
    );
    console.log(context.contextProps);
    console.groupEnd();

    if (cacheHit) {
      console.groupCollapsed(
        '%cHIT%c on the cache',
        'color: green; font-weight: bold;',
        'color: black; font-weight: normal;'
      );
      console.log('found the cache row with this prop combination');
      console.log(JSON.stringify(keyValues, null, 2));
      console.groupEnd();
    } else {
      console.log(
        '%cMISS%c on the cache',
        'color: red; font-weight: bold;',
        'color: black; font-weight: normal;'
      );
      console.groupCollapsed(
        `%cCalculated new styles in %c${duration}ms`,
        'font-weight: normal; color: black',
        `color: black; font-weight: bold;`
      );
      console.log(
        '%ccreated a cache row%c with this prop combination',
        `color: black; font-weight: bold;`,
        'font-weight: normal; color: black'
      );
      console.log(JSON.stringify(keyValues, null, 2));
      console.log('\n');
      console.log(
        `and created ${
          generatedCss
            ? `className %c(${passedOnProps.className}) and css:`
            : '%cinline styles:'
        }`,
        'color: black; font-weight: bold;'
      );
      console.log(
        generatedCss
          ? generatedCss
          : JSON.stringify(passedOnProps.style, null, 2)
      );
      console.groupEnd();
    }

    console.groupCollapsed(
      '%ccomponent render() with props',
      'color: black; font-weight: normal;'
    );
    console.log('%cfrom swiss:', 'color: black; font-weight: bold;');
    console.log(`${JSON.stringify(passedOnProps, null, 2)}`);
    console.log('\n');
    console.log(
      'and %cpassed on from parent',
      'color: black; font-weight: bold;'
    );
    console.log(filteredProps);
    console.groupEnd();
    console.groupEnd();
  }
};
<commit_msg>performance: improved debugging styles<commit_after>export default ({
  cacheHit,
  renderCycles,
  props,
  context,
  startTime,
  endTime,
  filteredProps,
  keyValues,
  passedOnProps,
  // If we added any css it will be the last element
  generatedCss
}) => {
  if (
    typeof console !== 'undefined' &&
    typeof console.groupCollapsed !== 'undefined'
  ) {
    const duration = endTime.getTime() - startTime.getTime();

    const title = [
      `${renderCycles}`,
      `%c${props.__swissOptions.type}`,
      `%c${cacheHit ? 'HIT' : 'MISS'}`,
      `%c${duration}ms`
    ];
    const styles = [
      'color: gray; font-weight: lighter;',
      '',
      cacheHit ? 'color: green;' : 'color: red;',
      duration > 1 ? '' : 'color: gray; font-weight: lighter;'
    ];
    if (passedOnProps.className) {
      title.push(`%c.${passedOnProps.className.split(' ')[1]}`);
      styles.push('color: gray; font-weight: lighter;');
    }
    if (passedOnProps.style) {
      title.push(`%cinline`);
      styles.push('color: gray; font-weight: lighter;');
    }

    console.groupCollapsed(`%c ${title.join(' ')}`, ...styles);

    console.groupCollapsed(
      '%c> started component render()',
      'color:black; font-weight: normal;'
    );
    console.log('with these options');
    const options = Object.assign({}, context.options, props.__swissOptions);
    delete options.styles;
    delete options.originalStyles;
    console.log(options);
    console.groupEnd();

    console.groupCollapsed(
      '%c> asking for styles with props prepareToRender()',
      'color:black; font-weight: normal;'
    );
    console.log('%ccomponent props', 'color: black; font-weight: bold;');
    console.log(props);
    console.log(
      'and %ccontext props <SW.ProvideContext ...>',
      'color: black; font-weight: bold;'
    );
    console.log(context.contextProps);
    console.groupEnd();

    if (cacheHit) {
      console.groupCollapsed(
        '> %cHIT%c on the cache',
        'color: green; font-weight: bold;',
        'color: black; font-weight: normal;'
      );
      console.log('found the cache row with this prop combination');
      console.log(JSON.stringify(keyValues, null, 2));
      console.groupEnd();
    } else {
      console.log(
        '> %cMISS%c on the cache',
        'color: red; font-weight: bold;',
        'color: black; font-weight: normal;'
      );
      console.groupCollapsed(
        `%c> calculated new styles in %c${duration}ms`,
        'font-weight: normal; color: black',
        `color: black; font-weight: bold;`
      );
      console.log(
        '%ccreated a cache row%c with this prop combination',
        `color: black; font-weight: bold;`,
        'font-weight: normal; color: black'
      );
      console.log(JSON.stringify(keyValues, null, 2));
      console.log('\n');
      console.log(
        `and created ${
          generatedCss
            ? `className %c(${passedOnProps.className}) and css:`
            : '%cinline styles:'
        }`,
        'color: black; font-weight: bold;'
      );
      console.log(
        generatedCss
          ? generatedCss
          : JSON.stringify(passedOnProps.style, null, 2)
      );
      console.groupEnd();
    }

    console.groupCollapsed(
      '%c> component render() with props',
      'color: black; font-weight: normal;'
    );
    console.log('%cfrom swiss:', 'color: black; font-weight: bold;');
    console.log(`${JSON.stringify(passedOnProps, null, 2)}`);
    console.log('\n');
    console.log(
      'and %cpassed on from parent',
      'color: black; font-weight: bold;'
    );
    console.log(filteredProps);
    console.groupEnd();
    console.groupEnd();
  }
};
<|endoftext|>


<commit_before>dop.core.storeAndSendRequests = function(node, message, wrapper) {
    dop.core.storeRequest(node, message, wrapper)
    dop.core.sendRequests(node)
}
<commit_msg>Naming message to request<commit_after>dop.core.storeAndSendRequests = function(node, request, wrapper) {
    dop.core.storeRequest(node, request, wrapper)
    dop.core.sendRequests(node)
}
<|endoftext|>


<commit_before>/*
 * staticx
 * https://github.com/badsyntax/staticx
 *
 * Copyright (c) 2013 Richard Willis
 * Licensed under the MIT license.
 */

'use strict';

/**
 * Load dependencies.
 */
var path = require('path');
var fs = require('fs-extra');
var util = require('util');
var getSlug = require('speakingurl');
var globalize = require('globalize');
var validator = require('../validator');
var BaseModel = require('./Base');
var _ = require('lodash');

/**
 * Page model.
 * @param  {object} data The page data.
 */
var PageModel = module.exports = function(data) {

  this.setSchema(PageModel.schema);

  this.schema.parent.conform = function(parent) {
    return validator.parentPageExists(parent, this.destination, this.fileExtension);
  }.bind(this);

  this.__defineGetter__('slug', this.getSlug.bind(this));
  this.__defineGetter__('url', this.getUrl.bind(this));
  this.__defineGetter__('fileName', this.getFileName.bind(this));
  this.__defineGetter__('metadata', this.getFormattedMetadata.bind(this));

  if (!data || data['filePath'] === undefined)
    this.__defineGetter__('filePath', this.getFilePath.bind(this));

  BaseModel.apply(this, arguments);
};

util.inherits(PageModel, BaseModel);

PageModel.schema = {
  date: {
    type: 'string',
    required: true,
    format: 'date-time',
  },
  title: {
    type: 'string',
    required: true
  },
  slug: {
    type: 'string',
    required: false
  },
  url: {
    type: 'string',
    required: false
  },
  destination: {
    type: 'string',
    message: 'Destination path does not exist',
    required: true,
    default: '.',
    conform: validator.fileExists
  },
  parent: {
    type: 'string',
    required: false,
    default: '',
    message: 'Parent page does not exist',
    conform: validator.parentPageExists
  },
  content: {
    type: 'string',
    required: true,
    default: ''
  },
  tags: {
    type: 'string',
    required: false,
    default: ''
  },
  filePath: {
    type: 'string',
    required: true
  },
  urlExtension: {
    type: 'string',
    required: false,
    default: 'html'
  },
  fileExtension: {
    type: 'string',
    required: false,
    default: 'md'
  }
};

/**
 * Generate the page file path.
 */
PageModel.prototype.getFilePath = function() {

  if (!this.destination)
    throw new Error('destination is not set, unable to generate page model filepath.');

  return path.join(this.destination, '_pages', this.parent || '', this.fileName);
};

/**
 * Generate the page file name.
 */
PageModel.prototype.getFileName = function() {
  return [ this.slug, this.fileExtension ].join('.');
};

/**
 * Generate the page URL.
 */
PageModel.prototype.getUrl = function() {

  var helpers = {
    year: function() {
      return globalize.format(new Date(this.date), 'yyyy');
    }.bind(this),
    month: function() {
      return globalize.format(new Date(this.date), 'MM');
    }.bind(this),
    day: function() {
      return globalize.format(new Date(this.date), 'dd');
    }.bind(this)
  };

  var format = this.config.site.urlFormat || ':slug.:urlExtension';

  return format.replace(/:([a-z]+)/ig, function(match, val) {
    if (helpers[val]) return helpers[val]();
    else return this.getData(val);
  }.bind(this));
};

/**
 * Generate the page slug.
 */
PageModel.prototype.getSlug = function() {
  return getSlug(this.title);
};

/**
 * Returns the file content.
 * @return {string}
 */
PageModel.prototype.getFileContent = function() {
  return [ this.metadata, this.content ].join('\n');
};

/**
 * Returns the metadata section of the file content.
 * @return {string}
 */
PageModel.prototype.getFormattedMetadata = function() {
  var metadata = [];
  metadata.push('---');
  if (this.title) metadata.push(util.format('title: %s', this.title));
  if (this.date)  metadata.push(util.format('date: %s', this.date));
  if (this.tags)  metadata.push(util.format('tags: %s', this.tags));
  metadata.push('---');
  return metadata.join('\n');
};

/*
 * Save page to file.
 * @param  {Function} done Callback function.
 */
PageModel.prototype.save = function(done) {

  // Ensure the model data is valid.
  var validate = this.validate();
  if (!validate.valid)
    return done(
      util.format('Error saving the page. %s: %s',
        validate.errors[0].property,
        validate.errors[0].message
      )
    );

  // Using fs.outputFile, we ensure the directory exists before writing to file.
  fs.outputFile(this.filePath, this.getFileContent(), function(err) {
    done(err, this);
  }.bind(this));
};

/**
 * Delete page from filesystem.
 * @param  {Function} done Callback function.
 */
PageModel.prototype.delete = function(done) {
  fs.unlink(this.filePath, done);
};
<commit_msg>Added compile methods to model<commit_after>/*
 * staticx
 * https://github.com/badsyntax/staticx
 *
 * Copyright (c) 2013 Richard Willis
 * Licensed under the MIT license.
 */

'use strict';

/**
 * Load dependencies.
 */
var path = require('path');
var fs = require('fs-extra');
var util = require('util');
var getSlug = require('speakingurl');
var globalize = require('globalize');
var _ = require('lodash');
var validator = require('../validator');
var BaseModel = require('./Base');
var templateCompiler = require('../compilers/template');
var markdownCompiler = require('../compilers/markdown');

/**
 * Page model.
 * @param  {object} data The page data.
 */
var PageModel = module.exports = function(data) {

  this.setSchema(PageModel.schema);

  this.schema.parent.conform = function(parent) {
    return validator.parentPageExists(parent, this.destination, this.fileExtension);
  }.bind(this);

  this.__defineGetter__('slug', this.getSlug.bind(this));
  this.__defineGetter__('url', this.getUrl.bind(this));
  this.__defineGetter__('metadata', this.getFormattedMetadata.bind(this));

  if (!data || data['filePath'] === undefined)
    this.__defineGetter__('filePath', this.getFilePath.bind(this));

  if (!data || data['fileName'] === undefined)
    this.__defineGetter__('fileName', this.getFileName.bind(this));

  BaseModel.apply(this, arguments);
};

util.inherits(PageModel, BaseModel);

PageModel.schema = {
  date: {
    type: 'string',
    required: true,
    format: 'date-time',
  },
  title: {
    type: 'string',
    required: true
  },
  slug: {
    type: 'string',
    required: false
  },
  url: {
    type: 'string',
    required: false
  },
  destination: {
    type: 'string',
    message: 'Destination path does not exist',
    required: true,
    default: '.',
    conform: validator.fileExists
  },
  parent: {
    type: 'string',
    required: false,
    default: '',
    message: 'Parent page does not exist',
    conform: validator.parentPageExists
  },
  content: {
    type: 'string',
    required: true,
    default: ''
  },
  tags: {
    type: 'string',
    required: false,
    default: ''
  },
  filePath: {
    type: 'string',
    required: true
  },
  urlExtension: {
    type: 'string',
    required: false,
    default: 'html'
  },
  fileExtension: {
    type: 'string',
    required: false,
    default: 'md'
  },
  markdown: {
    type: 'string',
    required: false,
    default: ''
  }
};

/**
 * Generate the page file path.
 */
PageModel.prototype.getFilePath = function() {

  if (!this.destination)
    throw new Error('destination is not set, unable to generate page model filepath.');

  return path.join(this.destination, '_pages', this.parent || '', this.fileName);
};

/**
 * Generate the page file name.
 */
PageModel.prototype.getFileName = function() {
  return [ this.slug, this.fileExtension ].join('.');
};

/**
 * Generate the page URL.
 */
PageModel.prototype.getUrl = function() {

  var helpers = {
    year: function() {
      return globalize.format(new Date(this.date), 'yyyy');
    }.bind(this),
    month: function() {
      return globalize.format(new Date(this.date), 'MM');
    }.bind(this),
    day: function() {
      return globalize.format(new Date(this.date), 'dd');
    }.bind(this)
  };

  var format = this.config.site.urlFormat || ':slug.:urlExtension';

  return format.replace(/:([a-z]+)/ig, function(match, val) {
    if (helpers[val]) return helpers[val]();
    else return this.getData(val);
  }.bind(this));
};

/**
 * Generate the page slug.
 */
PageModel.prototype.getSlug = function() {
  return getSlug(this.title);
};

/**
 * Returns the file content.
 * @return {string}
 */
PageModel.prototype.getFileContent = function() {
  return [ this.metadata, this.content ].join('\n');
};

/**
 * Returns the metadata section of the file content.
 * @return {string}
 */
PageModel.prototype.getFormattedMetadata = function() {
  var metadata = [];
  metadata.push('---');
  if (this.title) metadata.push(util.format('title: %s', this.title));
  if (this.date)  metadata.push(util.format('date: %s', this.date));
  if (this.tags)  metadata.push(util.format('tags: %s', this.tags));
  metadata.push('---');
  return metadata.join('\n');
};

/*
 * Save page to file.
 * @param  {Function} done Callback function.
 */
PageModel.prototype.save = function(done) {

  // Ensure the model data is valid.
  var validate = this.validate();
  if (!validate.valid)
    return done(
      util.format('Error saving the page. %s: %s',
        validate.errors[0].property,
        validate.errors[0].message
      )
    );

  // Using fs.outputFile, we ensure the directory exists before writing to file.
  fs.outputFile(this.filePath, this.getFileContent(), function(err) {
    done(err, this);
  }.bind(this));
};

/**
 * Delete page from filesystem.
 * @param  {Function} done Callback function.
 */
PageModel.prototype.delete = function(done) {
  fs.unlink(this.filePath, done);
};

PageModel.prototype.compileTemplate = function(viewPath, done) {
  templateCompiler.compilePath(viewPath, this, done);
};

PageModel.prototype.compileContent = function(done) {
  markdownCompiler.compile(this.markdown, function(err, content) {
    this.content = content;
    done(err, content);
  }.bind(this));
};
<|endoftext|>


<commit_before>'use strict';

/* unit.js
 * The Unit object to represent CSS units.
 * */

module.exports = exports = Unit;

function Unit(val, type){
  if (!(this instanceof Unit)) return new Unit(val, type);
  this.val = val;
  this.type = type || null;
}

Unit.prototype.compareTypes = function(otherUnit){
  if (!(otherUnit instanceof Unit)) {
    return new TypeError('otherUnit must be a Unit');
  }

  // Used for cases where there is no unit
  // e.g. "100% * 3" or "(10 * 5)px"
  if (otherUnit.type === null) otherUnit.type = this.type;

  return otherUnit.type === this.type;
};

Unit.prototype._operation = function(otherUnit, callback){
  if (typeof otherUnit === 'number') otherUnit = new Unit(otherUnit, this.type);
  let check = this.compareTypes(otherUnit);
  if (this.type === null || otherUnit.type === null) return new Unit(0, this.type || otherUnit.type);
  if (check) return new Unit(callback(otherUnit), this.type || otherUnit.type);
  else
    throw new TypeError('units must be the same type');
};

Unit.prototype.plus =
Unit.prototype.add = function(otherUnit){
  return this._operation(otherUnit, (otherUnit) => this.val + otherUnit.val);
};

Unit.prototype.minus =
Unit.prototype.subtract = function(otherUnit){
  return this._operation(otherUnit, (otherUnit) => this.val - otherUnit.val);
};

Unit.prototype.times =
Unit.prototype.multiply = function(otherUnit) {
  return this._operation(otherUnit, (otherUnit) => this.val * otherUnit.val);
};

Unit.prototype.divide = function(otherUnit){
  return this._operation(otherUnit, (otherUnit) => this.val / otherUnit.val);
};

Unit.prototype.equals =
Unit.prototype.compare = function(otherUnit){
  return this.compareTypes(otherUnit) && (this.val === otherUnit.val);
};

Unit.prototype.convert = function(type, options){
  if (!options) options = {};
  let dpi = options.dpi || 96;

  // Pixels to inches
  if (
    this.type === 'px' &&
    type === 'in'
  ) return new Unit(this.val / dpi, 'in');

  // Inches to Pixels
  else if (
    this.type === 'in' &&
    type === 'px'
  ) return new Unit(this.val * dpi, 'px');

  else {
    throw new TypeError('invalid unit conversion');
  }
};
<commit_msg>Add conversion into operation<commit_after>'use strict';

/* unit.js
 * The Unit object to represent CSS units.
 * */

module.exports = exports = Unit;

function Unit(val, type){
  if (!(this instanceof Unit)) return new Unit(val, type);
  this.val = val;
  this.type = type || null;
}

Unit.prototype.compareTypes = function(otherUnit){
  if (!(otherUnit instanceof Unit)) {
    return new TypeError('otherUnit must be a Unit');
  }

  // Used for cases where there is no unit
  // e.g. "100% * 3" or "(10 * 5)px"
  if (otherUnit.type === null) otherUnit.type = this.type;

  return otherUnit.type === this.type;
};

Unit.prototype._operation = function(otherUnit, callback){
  console.log(this, otherUnit);
  if (typeof otherUnit === 'number') otherUnit = new Unit(otherUnit, this.type);
  let check = this.compareTypes(otherUnit);
  if (this.type === null || otherUnit.type === null) return new Unit(0);
  if (check) return new Unit(callback(otherUnit), this.type);
  else try {
    otherUnit = otherUnit.convert(this.type);
    return new Unit(callback(otherUnit), this.type);
  } catch (e) {
    throw new TypeError('units must be the same or convertable types');
  }
};

Unit.prototype.plus =
Unit.prototype.add = function(otherUnit){
  return this._operation(otherUnit, (otherUnit) => this.val + otherUnit.val);
};

Unit.prototype.minus =
Unit.prototype.subtract = function(otherUnit){
  return this._operation(otherUnit, (otherUnit) => this.val - otherUnit.val);
};

Unit.prototype.times =
Unit.prototype.multiply = function(otherUnit) {
  return this._operation(otherUnit, (otherUnit) => this.val * otherUnit.val);
};

Unit.prototype.divide = function(otherUnit){
  return this._operation(otherUnit, (otherUnit) => this.val / otherUnit.val);
};

Unit.prototype.equals =
Unit.prototype.compare = function(otherUnit){
  return this.compareTypes(otherUnit) && (this.val === otherUnit.val);
};

Unit.prototype.convert = function(type, options){
  if (!options) options = {};
  let dpi = options.dpi || 96;

  // Pixels to inches
  if (
    this.type === 'px' &&
    type === 'in'
  ) return new Unit(this.val / dpi, 'in');

  // Inches to Pixels
  else if (
    this.type === 'in' &&
    type === 'px'
  ) return new Unit(this.val * dpi, 'px');

  else {
    throw new TypeError('invalid unit conversion');
  }
};
<|endoftext|>


<commit_before>'use strict';
var debug    = require('debug')('soundcloud/user');
var filter   = require('lodash.filter');
var is       = require('is_js');
var _request = require('./request');

var getUserByName = function(clientId, name) {
  var regex = new RegExp('/' + name + '$', 'g');
  debug(regex, clientId);

  return _request('users', {
      q: name,
      client_id: clientId
    })
    .then(function(users) {
      if (users.errors) {
        throw new Error(users.errors);
      }

      debug(users.length);

      var user = filter(users, function(user) {
        return regex.test(user.permalink_url);
      });

      debug(user);

      return user[0];
    });
};

var getUserById = function(clientId, id) {
  return _request('users/' + id + '.json', {
    client_id: clientId
  })
  .then(function(results){
    if (results.errors) {
        throw results.errors;
    }
    return results;
  });
};

var SoundCloudUser = function(clientId, name) {
  this.clientId = clientId;

  if (is.number(name)) {
    this.user = getUserById(clientId, name);
  } else {
    this.user = getUserByName(clientId, name);
  }

  this.getUserInfo = function(type, params) {
    var self = this;
    return this.user
      .then(function(user) {
        debug(user);
        var id = user.id;
        params = params || {};
        params.client_id = self.clientId;

        return _request('users/' + id + '/' + type + '.json', params);
      })
      .then(function(results) {
        debug(results);
        return results;
      });
  };
};

SoundCloudUser.prototype.details = function() {
  return this.user
    .then(function(user) {
      return user;
    });
};

SoundCloudUser.prototype.tracks = function(params) {
  return this.getUserInfo('tracks', params);
};

SoundCloudUser.prototype.playlists = function(params) {
  return this.getUserInfo('playlists', params);
};

SoundCloudUser.prototype.followings = function(params) {
  return this.getUserInfo('followings', params);
};

SoundCloudUser.prototype.followers = function(params) {
  return this.getUserInfo('followers', params);
};

SoundCloudUser.prototype.comments = function(params) {
  return this.getUserInfo('comments', params);
};

SoundCloudUser.prototype.favorites = function(params) {
  return this.getUserInfo('favorites', params);
};

SoundCloudUser.prototype.groups = function(params) {
  return this.getUserInfo('groups', params);
};

SoundCloudUser.prototype.webProfiles = function(params) {
  return this.getUserInfo('web-profiles', params);
};

module.exports = SoundCloudUser;
<commit_msg>defensive coding<commit_after>'use strict';
var debug    = require('debug')('soundcloud/user');
var filter   = require('lodash.filter');
var is       = require('is_js');
var _request = require('./request');

var getUserByName = function(clientId, name) {
  var regex = new RegExp('/' + name + '$', 'g');
  debug(regex, clientId);

  return _request('users', {
      q: name,
      client_id: clientId
    })
    .then(function(users) {
      if (users.errors) {
        throw new Error(users.errors);
      }

      debug(users.length);

      var user = filter(users, function(user) {
        return regex.test(user.permalink_url);
      });

      debug(user);

      return user[0];
    });
};

var getUserById = function(clientId, id) {
  return _request('users/' + id + '.json', {
    client_id: clientId
  })
  .then(function(results){
    if (results.errors) {
        throw results.errors;
    }
    return results;
  });
};

var SoundCloudUser = function(clientId, name) {
  this.clientId = clientId;

  if (is.number(name)) {
    this.user = getUserById(clientId, name);
  } else {
    this.user = getUserByName(clientId, name);
  }

  this.getUserInfo = function(type, params) {
    var self = this;
    return this.user
      .then(function(user) {
        debug(user);
        if (!user) throw new Error('user not found');

        var id = user.id;
        params = params || {};
        params.client_id = self.clientId;

        return _request('users/' + id + '/' + type + '.json', params);
      })
      .then(function(results) {
        debug(results);
        return results;
      });
  };
};

SoundCloudUser.prototype.details = function() {
  return this.user
    .then(function(user) {
      return user;
    });
};

SoundCloudUser.prototype.tracks = function(params) {
  return this.getUserInfo('tracks', params);
};

SoundCloudUser.prototype.playlists = function(params) {
  return this.getUserInfo('playlists', params);
};

SoundCloudUser.prototype.followings = function(params) {
  return this.getUserInfo('followings', params);
};

SoundCloudUser.prototype.followers = function(params) {
  return this.getUserInfo('followers', params);
};

SoundCloudUser.prototype.comments = function(params) {
  return this.getUserInfo('comments', params);
};

SoundCloudUser.prototype.favorites = function(params) {
  return this.getUserInfo('favorites', params);
};

SoundCloudUser.prototype.groups = function(params) {
  return this.getUserInfo('groups', params);
};

SoundCloudUser.prototype.webProfiles = function(params) {
  return this.getUserInfo('web-profiles', params);
};

module.exports = SoundCloudUser;
<|endoftext|>