<commit_before>;(function(root,factory){
    'use strict';
    /* amd like aml https://github.com/xudafeng/aml.git */
    if(typeof define === 'function' && define.amd) {
        return define(['exports'], factory);
    }else if(typeof exports !== 'undefined') {
        return factory(exports);
    }else{
    /* browser */
        factory(root['passme'] || (root['passme'] = {}));
    }
})(this,function(exports,undefined){
    var Sytax,
        Regex,
        Token,
        Message;

    /* static */
    var EMPTY = '';

    /* default options */
    var options = {
        ecmascript:5,
        comment:true
    }

    Syntax = {
        AssignmentExpression: 'AssignmentExpression',
        ArrayExpression: 'ArrayExpression',
        ArrayPattern: 'ArrayPattern',
        ArrowFunctionExpression: 'ArrowFunctionExpression',
        BlockStatement: 'BlockStatement',
        BinaryExpression: 'BinaryExpression',
        BreakStatement: 'BreakStatement',
        CallExpression: 'CallExpression',
        CatchClause: 'CatchClause',
        ComprehensionBlock: 'ComprehensionBlock',
        ComprehensionExpression: 'ComprehensionExpression',
        ConditionalExpression: 'ConditionalExpression',
        ContinueStatement: 'ContinueStatement',
        DirectiveStatement: 'DirectiveStatement',
        DoWhileStatement: 'DoWhileStatement',
        DebuggerStatement: 'DebuggerStatement',
        EmptyStatement: 'EmptyStatement',
        ExpressionStatement: 'ExpressionStatement',
        ForStatement: 'ForStatement',
        ForInStatement: 'ForInStatement',
        FunctionDeclaration: 'FunctionDeclaration',
        FunctionExpression: 'FunctionExpression',
        Identifier: 'Identifier',
        IfStatement: 'IfStatement',
        Literal: 'Literal',
        LabeledStatement: 'LabeledStatement',
        LogicalExpression: 'LogicalExpression',
        MemberExpression: 'MemberExpression',
        NewExpression: 'NewExpression',
        ObjectExpression: 'ObjectExpression',
        ObjectPattern: 'ObjectPattern',
        Program: 'Program',
        Property: 'Property',
        ReturnStatement: 'ReturnStatement',
        SequenceExpression: 'SequenceExpression',
        SwitchStatement: 'SwitchStatement',
        SwitchCase: 'SwitchCase',
        ThisExpression: 'ThisExpression',
        ThrowStatement: 'ThrowStatement',
        TryStatement: 'TryStatement',
        UnaryExpression: 'UnaryExpression',
        UpdateExpression: 'UpdateExpression',
        VariableDeclaration: 'VariableDeclaration',
        VariableDeclarator: 'VariableDeclarator',
        WhileStatement: 'WhileStatement',
        WithStatement: 'WithStatement',
        YieldExpression: 'YieldExpression'
    };

    Token = {
        BooleanLiteral: 1,
        Identifier: 2,
        Keyword: 3,
        NullLiteral: 4,
        NumericLiteral: 5,
        Punctuator: 6,
        StringLiteral: 7,
        RegularExpression: 8,
        Comment:9,
        WhiteSpace:10
    };
    /* map for type */

    Token['BooleanLiteral'] = 'BooleanLiteral';
    Token['Identifier'] = 'Identifier';
    Token['Keyword'] = 'Keyword';
    Token['NullLiteral'] = 'NullLiteral';
    Token['NumericLiteral'] = 'NumericLiteral';
    Token['Punctuator'] = 'Punctuator';
    Token['StringLiteral'] = 'StringLiteral';
    Token['RegularExpression'] = 'RegularExpression';
    Token['Comment'] = 'Comment';
    Token['WhiteSpace'] = 'WhiteSpace';

    Message = {};

    /**
     * util
     */

    var _ = function(){

    };
    function __typeof(type){
        return function(obj){
            return Object.prototype.toString.call(obj) === '[object ' + type + ']';
        };
    }
    _.prototype = {
        indexOf:function(item, arr) {
            for (var i = 0, len = arr.length; i < len; ++i) {
                if (arr[i] === item) {
                    return i;
                }
            }
            return -1;
        },
        inArray:function(item, arr) {
            return this.indexOf(item, arr) > -1;
        },
        isIn:function(i,s){
            return !!~s.indexOf(i);
        },
        each:function(object, fn) {
            if(object){
                for(var i in object){
                    if(i !== 'length' && i !== 'item'){
                        fn.call(this,object[i],i);
                    }
                }
            }
            return object;
        },
        isString:function(){
            return __typeof('String');
        },
        isArray:function(){
            return __typeof('Array');
        },
        isObject:function(){
            return __typeof('Object');
        },
        isFunction:function(){
            return __typeof('Function');
        },
        isUndefined:function(){
            return __typeof('Undefined');
        }
    };
    _ = new _();
    exports._ = _;
    /* lexicalParse class */
    function LexAnalyzer(cfg){
        this.source = cfg.code;
        this.init();
        return this.tokens;
    }
    LexAnalyzer.prototype = {
        init:function(){
            var that = this;
            that.initIndex();
            that.initFlags();
            that.scanner();
        },
        initIndex:function(){
            var that = this;
            that.length = that.source.length;
            that.index = 0;
        },
        initFlags:function(){
            var that = this;
            that.tokens = [];
            that.clearFlags();
        },
        scanner:function(){
            var that = this;
            function getChar(){
                return that.source[that.index];
                return that.source.charCodeAt(that.index);
            }
            while (that.index <= that.length -1){
                var curChar = getChar();
                that.getToken(curChar);
                //that.validate();
                that.goToNextToken();
            }
        },
        getToken:function(char){
            var that = this;
            function isKeyWordState(){
                return that.type === Token['Keyword'];
            }
            function expectWord(w){
                if(w.length >1){
                    expectWords(w);
                }else{
                    that.expect = w[0];
                }
            }
            function expectWords(a){
                that.expect = a;
            }
            /**
             * javascript es5 Keywords:
             * break
             * case catch continue
             * default delete do
             * else
             * finally for function
             * if in instanceof
             * new
             * return
             * switch
             * this throw try typeof
             * var void
             * while with
             */

            function parseKeyWord(c){
                if(_.isIn(c,'bcdefinstvw')){

                    that.type = Token['Keyword'];
                    that.token += c;

                    switch(c){
                        case 'b':
                            expectWord(['break']);
                            break;
                        case 'c':
                            expectWord(['case','catch','continue']);
                            break;
                        case 'd':
                            expectWord(['default','delete','do']);
                            break;
                        case 'e':
                            expectWord(['else']);
                            break;
                        case 'f':
                            expectWord(['finally','for','function']);
                            break;
                        case 'i':
                            expectWord(['if','in','instanceof']);
                            break;
                        case 'n':
                            expectWord(['new']);
                            break;
                        case 's':
                            expectWord(['switch']);
                            break;
                        case 't':
                            expectWord(['this','throw','try','typeof']);
                            break;
                        case 'v':
                            expectWord(['var','void']);
                            break;
                        case 'w':
                            expectWord(['while','with']);
                            break;
                    }
                }
            }
            /* break */
            function expectBreak(){

            }
            function error(){

            }

            /* validata keyword for the first */

            if(that.type){

                switch (that.type){
                    case 'Keyword':
                        console.log(that)
                        var _t,_e;
                        if(_.isArray(that.expect)){
                            _.each(that.expect,function(i){
                                i === that.token && (_t = that.token);
                                i.indexOf
                            });
                        }else{

                        }
                        break;
                    default:
                        error();
                        break;
                }
            }else {
                parseKeyWord(char);
            }
        },
        validate:function(){
            var that = this;
            that.tokens.push(that.token);
            that.clearFlags();
        },
        clearFlags:function(){
            var that = this;
            that.token = EMPTY;
            that.expect = null;
            that.type = null;
        },
        goToNextToken:function(){
            this.index ++;
        }
    };

    function throwError(){

    }

    /* build tree class */
    function Parser(){
        this.init();
    }
    Parser.prototype = {
        init:function(){

        }
    };
    /* set options */
    function setOptions(o){

    }
    /* exports */
    function parse(code,options){
    }
    function tokenize(code,options){
        setOptions(options);
        var cfg = {
            code:code
        };
        return new LexAnalyzer(cfg);
    }
    exports.version = '1.0.0';
    exports.parse = parse;
    exports.tokenize = tokenize;
});
/* vim: set sw=4 ts=4 et tw=80 : */
<commit_msg>add grunt<commit_after>;(function(root,factory){
    'use strict';
    /* amd like aml https://github.com/xudafeng/aml.git */
    if(typeof define === 'function' && define.amd) {
        return define(['exports'], factory);
    }else if(typeof exports !== 'undefined') {
        return factory(exports);
    }else{
    /* browser */
        factory(root['passme'] || (root['passme'] = {}));
    }
})(this,function(exports,undefined){
    var Sytax,
        Regex,
        Token,
        Message;

    /* static */
    var EMPTY = '';

    /* default options */
    var options = {
        ecmascript:5,
        comment:true
    }

    Syntax = {
        AssignmentExpression: 'AssignmentExpression',
        ArrayExpression: 'ArrayExpression',
        ArrayPattern: 'ArrayPattern',
        ArrowFunctionExpression: 'ArrowFunctionExpression',
        BlockStatement: 'BlockStatement',
        BinaryExpression: 'BinaryExpression',
        BreakStatement: 'BreakStatement',
        CallExpression: 'CallExpression',
        CatchClause: 'CatchClause',
        ComprehensionBlock: 'ComprehensionBlock',
        ComprehensionExpression: 'ComprehensionExpression',
        ConditionalExpression: 'ConditionalExpression',
        ContinueStatement: 'ContinueStatement',
        DirectiveStatement: 'DirectiveStatement',
        DoWhileStatement: 'DoWhileStatement',
        DebuggerStatement: 'DebuggerStatement',
        EmptyStatement: 'EmptyStatement',
        ExpressionStatement: 'ExpressionStatement',
        ForStatement: 'ForStatement',
        ForInStatement: 'ForInStatement',
        FunctionDeclaration: 'FunctionDeclaration',
        FunctionExpression: 'FunctionExpression',
        Identifier: 'Identifier',
        IfStatement: 'IfStatement',
        Literal: 'Literal',
        LabeledStatement: 'LabeledStatement',
        LogicalExpression: 'LogicalExpression',
        MemberExpression: 'MemberExpression',
        NewExpression: 'NewExpression',
        ObjectExpression: 'ObjectExpression',
        ObjectPattern: 'ObjectPattern',
        Program: 'Program',
        Property: 'Property',
        ReturnStatement: 'ReturnStatement',
        SequenceExpression: 'SequenceExpression',
        SwitchStatement: 'SwitchStatement',
        SwitchCase: 'SwitchCase',
        ThisExpression: 'ThisExpression',
        ThrowStatement: 'ThrowStatement',
        TryStatement: 'TryStatement',
        UnaryExpression: 'UnaryExpression',
        UpdateExpression: 'UpdateExpression',
        VariableDeclaration: 'VariableDeclaration',
        VariableDeclarator: 'VariableDeclarator',
        WhileStatement: 'WhileStatement',
        WithStatement: 'WithStatement',
        YieldExpression: 'YieldExpression'
    };

    Token = {
        BooleanLiteral: 1,
        Identifier: 2,
        Keyword: 3,
        NullLiteral: 4,
        NumericLiteral: 5,
        Punctuator: 6,
        StringLiteral: 7,
        RegularExpression: 8,
        Comment:9,
        WhiteSpace:10
    };
    /* map for type */

    Token['BooleanLiteral'] = 'BooleanLiteral';
    Token['Identifier'] = 'Identifier';
    Token['Keyword'] = 'Keyword';
    Token['NullLiteral'] = 'NullLiteral';
    Token['NumericLiteral'] = 'NumericLiteral';
    Token['Punctuator'] = 'Punctuator';
    Token['StringLiteral'] = 'StringLiteral';
    Token['RegularExpression'] = 'RegularExpression';
    Token['Comment'] = 'Comment';
    Token['WhiteSpace'] = 'WhiteSpace';

    Message = {};

    /**
     * util
     */

    var _ = function(){

    };
    function __typeof(type){
        return function(obj){
            return Object.prototype.toString.call(obj) === '[object ' + type + ']';
        };
    }
    _.prototype = {
        indexOf:function(item, arr) {
            for (var i = 0, len = arr.length; i < len; ++i) {
                if (arr[i] === item) {
                    return i;
                }
            }
            return -1;
        },
        inArray:function(item, arr) {
            return this.indexOf(item, arr) > -1;
        },
        isIn:function(i,s){
            return !!~s.indexOf(i);
        },
        each:function(object, fn) {
            if(object){
                for(var i in object){
                    if(i !== 'length' && i !== 'item'){
                        fn.call(this,object[i],i);
                    }
                }
            }
            return object;
        },
        isString:function(){
            return __typeof('String');
        },
        isArray:function(){
            return __typeof('Array');
        },
        isObject:function(){
            return __typeof('Object');
        },
        isFunction:function(){
            return __typeof('Function');
        },
        isUndefined:function(){
            return __typeof('Undefined');
        }
    };
    _ = new _();
    exports._ = _;
    /* lexicalParse class */
    function LexAnalyzer(cfg){
        this.source = cfg.code;
        this.init();
        return this.tokens;
    }
    LexAnalyzer.prototype = {
        init:function(){
            var that = this;
            that.initIndex();
            that.initFlags();
            that.scanner();
        },
        initIndex:function(){
            var that = this;
            that.length = that.source.length;
            that.index = 0;
        },
        initFlags:function(){
            var that = this;
            that.tokens = [];
            that.clearFlags();
        },
        scanner:function(){
            var that = this;
            function getChar(){
                return that.source[that.index];
                return that.source.charCodeAt(that.index);
            }
            while (that.index <= that.length -1){
                var curChar = getChar();
                that.getToken(curChar);
                that.validate();
                that.goToNextToken();
            }
        },
        getToken:function(char){
            var that = this;
            function isKeyWordState(){
                return that.type === Token['Keyword'];
            }
            function expectWord(w){
                if(w.length >1){
                    expectWords(w);
                }else{
                    that.expect = w[0];
                }
            }
            function expectWords(a){
                that.expect = a;
            }
            /**
             * javascript es5 Keywords:
             * break
             * case catch continue
             * default delete do
             * else
             * finally for function
             * if in instanceof
             * new
             * return
             * switch
             * this throw try typeof
             * var void
             * while with
             */

            function parseKeyWord(c){
                if(_.isIn(c,'bcdefinstvw')){

                    that.type = Token['Keyword'];
                    that.token += c;

                    switch(c){
                        case 'b':
                            expectWord(['break']);
                            break;
                        case 'c':
                            expectWord(['case','catch','continue']);
                            break;
                        case 'd':
                            expectWord(['default','delete','do']);
                            break;
                        case 'e':
                            expectWord(['else']);
                            break;
                        case 'f':
                            expectWord(['finally','for','function']);
                            break;
                        case 'i':
                            expectWord(['if','in','instanceof']);
                            break;
                        case 'n':
                            expectWord(['new']);
                            break;
                        case 's':
                            expectWord(['switch']);
                            break;
                        case 't':
                            expectWord(['this','throw','try','typeof']);
                            break;
                        case 'v':
                            expectWord(['var','void']);
                            break;
                        case 'w':
                            expectWord(['while','with']);
                            break;
                    }
                }
            }
            /* break */
            function expectBreak(){

            }
            function error(){

            }

            /* validata keyword for the first */

            function checkKeyWordExpect(c){
                var _t ,_e = false;
                that.token += char;
                if(_.isArray(that.expect)){
                    _.each(that.expect,function(i){
                        if(i===that.token){
                            _t = that.token;
                        }else{
                            if(_.isIn(that.token,i)){
                                _e = true;
                            }
                        }
                    });
                }else{
                    if(that.token === that.expect){
                        _t = that.expect;
                    }else{
                        if(_.isIn(that.token,that.expect)){
                            _e = true;
                        }
                    }
                }
                return {
                    token:_t,
                    isExpect:_e
                };
            }

            if(that.type){

                switch (that.type){
                    case 'Keyword':
                        var r = checkKeyWordExpect(char);
                        if(r['token']){
                            that.token = r['token'];
                            that.expect = null;
                        }else{
                            if(!r['isExpect']){
                                that.type = Token['Identifier'];
                                that.expect = null;
                            }
                        }
                        break;
                    case 'Identifier':

                        break;
                    default:
                        error();
                        break;
                }
            }else {
                parseKeyWord(char);
            }
        },
        validate:function(){
            var that = this;
            if(that.token && that.type && !that.expect){
                that.tokens.push({
                    type:that.type,
                    value:that.token
                });
                that.clearFlags();
            }
        },
        clearFlags:function(){
            var that = this;
            that.token = EMPTY;
            that.expect = null;
            that.type = null;
        },
        goToNextToken:function(){
            this.index ++;
        }
    };

    function throwError(){

    }

    /* build tree class */
    function Parser(){
        this.init();
    }
    Parser.prototype = {
        init:function(){

        }
    };
    /* set options */
    function setOptions(o){

    }
    /* exports */
    function parse(code,options){
    }
    function tokenize(code,options){
        setOptions(options);
        var cfg = {
            code:code
        };
        return new LexAnalyzer(cfg);
    }
    exports.version = '1.0.0';
    exports.parse = parse;
    exports.tokenize = tokenize;
});
/* vim: set sw=4 ts=4 et tw=80 : */
<|endoftext|>


<commit_before>const functions = require('firebase-functions');
const admin = require('firebase-admin');

admin.initializeApp(functions.config().firebase);

exports.createPlayer = functions.auth.user().onCreate(event => {
  return admin.database()
    .ref('/players')
    .child(event.data.uid)
    .set({
      email: event.data.email,
      displayName: event.data.displayName,
      photoURL: event.data.photoURL,
      rating: 0
    })
});

exports.createMatch = functions.database.ref('/users/{userUid}/matches/{matchUid}')
  .onWrite(event => {
    if (event.auth.admin || event.data.previous.exists() || !event.data.exists())
      return;

    let match = event.data.val();
    if(match.final || match.player1Uid === match.player2Uid)
      return;

    match.createdDate = new Date().toISOString();
    match.final = false;

    return Promise.all([
      admin.database()
        .ref(`/users/${match.player1Uid}/matches`)
        .child(event.params.matchUid)
        .set(match),
      admin.database()
        .ref(`/users/${match.player2Uid}/matches`)
        .child(event.params.matchUid)
        .set(match)
    ]);

  });

exports.rejectMatch = functions.database.ref('/users/{userUid}/matches/{matchUid}')
  .onWrite(event => {
    if (event.data.exists())
      return;

    let deletedMatch = event.data.previous.val();

    return Promise.all([
      admin.database()
        .ref(`/users/${deletedMatch.player1Uid}/matches`)
        .child(event.params.matchUid)
        .set(null),
      admin.database()
        .ref(`/users/${deletedMatch.player2Uid}/matches`)
        .child(event.params.matchUid)
        .set(null)
    ]);
  });

let syncScores = (event, propertyName) => {
  if (event.auth.admin || !event.data.previous.exists() || !event.data.exists())
    return;

  let score = event.data.val();
  let previousScore = event.data.previous.val();

  if(score === previousScore)
    return;

  return admin.database().ref(`/users/${event.params.userUid}/matches/${event.params.matchUid}`)
    .once('value')
    .then((snap) => {
      let match = snap.val();
      let playerToUpdate = event.params.userUid === match.player1Uid ? match.player2Uid : match.player1Uid;
      return  Promise.all([
        admin.database()
          .ref(`/users/${playerToUpdate}/matches/${event.params.matchUid}`)
          .child(propertyName)
          .set(score),
        admin.database()
          .ref(`/users/${playerToUpdate}/matches/${event.params.matchUid}/player1Accepted`)
          .set(false),
        admin.database()
          .ref(`/users/${playerToUpdate}/matches/${event.params.matchUid}/player2Accepted`)
          .set(false),
      ]);
    });
}
exports.syncPlayer1Score = functions.database.ref('/users/{userUid}/matches/{matchUid}/player1Score')
  .onWrite((e) => syncScores(e, 'player1Score'));
exports.syncPlayer2Score = functions.database.ref('/users/{userUid}/matches/{matchUid}/player2Score')
  .onWrite((e) => syncScores(e, 'player2Score'));

let syncAcceptances = (event, propertyName) => {
  if (event.auth.admin || !event.data.previous.exists() || !event.data.exists())
    return;

  let accepted = event.data.val();
  let previousAccepted = event.data.previous.val();
  if(accepted === previousAccepted)
    return;

  return admin.database().ref(`/users/${event.params.userUid}/matches/${event.params.matchUid}`)
    .once('value')
    .then((snap) => {
      let match = snap.val();

      if(match.player1Accepted && match.player2Accepted) {
        match.final = true;
        match.finalizedDate = new Date().toISOString();
        delete match.player1Accepted;
        delete match.player2Accepted;
      }
      let playerToUpdate = event.params.userUid === match.player1Uid ? match.player2Uid : match.player1Uid;

      return Promise.all([
        match.final ? admin.database().ref(`/matches/${event.params.matchUid}`).set(match) : Promise.resolve(),
        admin.database()
          .ref(`/users/${playerToUpdate}/matches/${event.params.matchUid}`)
          .child(propertyName)
          .set(accepted)
      ]);
    });
};
exports.syncPlayer1Accepted = functions.database.ref('/users/{userUid}/matches/{matchUid}/player1Accepted')
  .onWrite((e) => syncAcceptances(e, 'player1Accepted'));
exports.syncPlayer2Accepted = functions.database.ref('/users/{userUid}/matches/{matchUid}/player2Accepted')
  .onWrite((e) => syncAcceptances(e, 'player2Accepted'));

exports.updateRating = functions.database.ref('/matches/{matchUid}')
  .onWrite(event => {
    if (event.data.previous.exists() || !event.data.exists())
      return;

    let match = event.data.val();
    return Promise.all([
      admin.database().ref(`/players/${match.player1Uid}`).once('value'),
      admin.database().ref(`/players/${match.player2Uid}`).once('value')
    ]).then((playerRefs)=>{
      let updateRating = (old, exp, score, k) => Math.round(old+k*(score-exp));
      let getExpected = (a, b) => 1/(1+Math.pow(10,((b-a)/400)));;

      let player1Rating = playerRefs[0].val().rating || 750;
      let player2Rating = playerRefs[1].val().rating || 750;
      let player1Result = Number(match.player1Score) || 0;
      let player2Result = Number(match.player2Score) || 0;
      let totalResult = player1Result + player2Result;

      let player1ExpectedScore = getExpected(player1Rating, player2Rating) * totalResult;
      let player2ExpectedScore = getExpected(player2Rating, player1Rating) * totalResult;

      let player1NewRating = updateRating(
        player1Rating,
        player1ExpectedScore,
        player1Result,
        totalResult/2
      );
      let player2NewRating = updateRating(
        player2Rating,
        player2ExpectedScore,
        player2Result,
        totalResult/2
      );

      return Promise.all([
        admin.database().ref(`/players/${match.player1Uid}/rating`)
          .set(player1NewRating),
        admin.database().ref(`/players/${match.player2Uid}/rating`)
          .set(player2NewRating)
      ]);
    });
  });
<commit_msg>Moved unranked rating to player creation<commit_after>const functions = require('firebase-functions');
const admin = require('firebase-admin');

admin.initializeApp(functions.config().firebase);

exports.createPlayer = functions.auth.user().onCreate(event => {
  return admin.database()
    .ref('/players')
    .child(event.data.uid)
    .set({
      email: event.data.email,
      displayName: event.data.displayName,
      photoURL: event.data.photoURL,
      rating: 750
    })
});

exports.createMatch = functions.database.ref('/users/{userUid}/matches/{matchUid}')
  .onWrite(event => {
    if (event.auth.admin || event.data.previous.exists() || !event.data.exists())
      return;

    let match = event.data.val();
    if(match.final || match.player1Uid === match.player2Uid)
      return;

    match.createdDate = new Date().toISOString();
    match.final = false;

    return Promise.all([
      admin.database()
        .ref(`/users/${match.player1Uid}/matches`)
        .child(event.params.matchUid)
        .set(match),
      admin.database()
        .ref(`/users/${match.player2Uid}/matches`)
        .child(event.params.matchUid)
        .set(match)
    ]);

  });

exports.rejectMatch = functions.database.ref('/users/{userUid}/matches/{matchUid}')
  .onWrite(event => {
    if (event.data.exists())
      return;

    let deletedMatch = event.data.previous.val();

    return Promise.all([
      admin.database()
        .ref(`/users/${deletedMatch.player1Uid}/matches`)
        .child(event.params.matchUid)
        .set(null),
      admin.database()
        .ref(`/users/${deletedMatch.player2Uid}/matches`)
        .child(event.params.matchUid)
        .set(null)
    ]);
  });

let syncScores = (event, propertyName) => {
  if (event.auth.admin || !event.data.previous.exists() || !event.data.exists())
    return;

  let score = event.data.val();
  let previousScore = event.data.previous.val();

  if(score === previousScore)
    return;

  return admin.database().ref(`/users/${event.params.userUid}/matches/${event.params.matchUid}`)
    .once('value')
    .then((snap) => {
      let match = snap.val();
      let playerToUpdate = event.params.userUid === match.player1Uid ? match.player2Uid : match.player1Uid;
      return  Promise.all([
        admin.database()
          .ref(`/users/${playerToUpdate}/matches/${event.params.matchUid}`)
          .child(propertyName)
          .set(score),
        admin.database()
          .ref(`/users/${playerToUpdate}/matches/${event.params.matchUid}/player1Accepted`)
          .set(false),
        admin.database()
          .ref(`/users/${playerToUpdate}/matches/${event.params.matchUid}/player2Accepted`)
          .set(false),
      ]);
    });
}
exports.syncPlayer1Score = functions.database.ref('/users/{userUid}/matches/{matchUid}/player1Score')
  .onWrite((e) => syncScores(e, 'player1Score'));
exports.syncPlayer2Score = functions.database.ref('/users/{userUid}/matches/{matchUid}/player2Score')
  .onWrite((e) => syncScores(e, 'player2Score'));

let syncAcceptances = (event, propertyName) => {
  if (event.auth.admin || !event.data.previous.exists() || !event.data.exists())
    return;

  let accepted = event.data.val();
  let previousAccepted = event.data.previous.val();
  if(accepted === previousAccepted)
    return;

  return admin.database().ref(`/users/${event.params.userUid}/matches/${event.params.matchUid}`)
    .once('value')
    .then((snap) => {
      let match = snap.val();

      if(match.player1Accepted && match.player2Accepted) {
        match.final = true;
        match.finalizedDate = new Date().toISOString();
        delete match.player1Accepted;
        delete match.player2Accepted;
      }
      let playerToUpdate = event.params.userUid === match.player1Uid ? match.player2Uid : match.player1Uid;

      return Promise.all([
        match.final ? admin.database().ref(`/matches/${event.params.matchUid}`).set(match) : Promise.resolve(),
        admin.database()
          .ref(`/users/${playerToUpdate}/matches/${event.params.matchUid}`)
          .child(propertyName)
          .set(accepted)
      ]);
    });
};
exports.syncPlayer1Accepted = functions.database.ref('/users/{userUid}/matches/{matchUid}/player1Accepted')
  .onWrite((e) => syncAcceptances(e, 'player1Accepted'));
exports.syncPlayer2Accepted = functions.database.ref('/users/{userUid}/matches/{matchUid}/player2Accepted')
  .onWrite((e) => syncAcceptances(e, 'player2Accepted'));

exports.updateRating = functions.database.ref('/matches/{matchUid}')
  .onWrite(event => {
    if (event.data.previous.exists() || !event.data.exists())
      return;

    let match = event.data.val();
    return Promise.all([
      admin.database().ref(`/players/${match.player1Uid}`).once('value'),
      admin.database().ref(`/players/${match.player2Uid}`).once('value')
    ]).then((playerRefs)=>{
      let updateRating = (old, exp, score, k) => Math.round(old+k*(score-exp));
      let getExpected = (a, b) => 1/(1+Math.pow(10,((b-a)/400)));;

      let player1Rating = playerRefs[0].val().rating;
      let player2Rating = playerRefs[1].val().rating;
      let player1Result = Number(match.player1Score) || 0;
      let player2Result = Number(match.player2Score) || 0;
      let totalResult = player1Result + player2Result;

      let player1ExpectedScore = getExpected(player1Rating, player2Rating) * totalResult;
      let player2ExpectedScore = getExpected(player2Rating, player1Rating) * totalResult;

      let player1NewRating = updateRating(
        player1Rating,
        player1ExpectedScore,
        player1Result,
        totalResult/2
      );
      let player2NewRating = updateRating(
        player2Rating,
        player2ExpectedScore,
        player2Result,
        totalResult/2
      );

      return Promise.all([
        admin.database().ref(`/players/${match.player1Uid}/rating`)
          .set(player1NewRating),
        admin.database().ref(`/players/${match.player2Uid}/rating`)
          .set(player2NewRating)
      ]);
    });
  });
<|endoftext|>


<commit_before>
var assert = require("assert");
var parser = require("../lib/urban-parser.js");
var fs = require("fs");

var obj = JSON.parse(fs.readFileSync('mocha_testing/sampledata.js', 'utf8'));

describe("Internal testing", function() {
  describe("urban-parser", function() {
    it("parses correct json result", function() {
      var api_result = JSON.stringify(obj.urbanparser.apiresponse);

      var expected_output = JSON.stringify(obj.urbanparser.correctoutput);
      var parse_result = JSON.stringify(parser.parse(api_result, 'ephemeral'));

      assert.equal(parse_result, expected_output);
    });
  });
});
<commit_msg>#39 - fixed.<commit_after>
var assert = require("assert");
var parser = require("../lib/urban-parser.js");
var fs = require("fs");

var obj = JSON.parse(fs.readFileSync('mocha_testing/sampledata.js', 'utf8'));

describe("Internal testing", function() {
  describe("urban-parser", function() {
    it("parses correct json result", function() {
      var api_result = JSON.stringify(obj.urbanparser.apiresponse);

      var expected_output = JSON.stringify(obj.urbanparser.correctoutput);
      var parse_result = JSON.stringify(parser.parse(api_result, JSON.parse('{"responseType":"ephemeral","rating":"nsfw","random":false}')));

      assert.equal(parse_result, expected_output);
    });
  });
});
<|endoftext|>


<commit_before>var puppy = {
  x: 550,
  y: 490,
  alive: true,
  won: false,
  canMove: true,
};

var bone1 = {
  x: 750,
  y: 200,
  alive: true,
};

var bone2 = {
  x: 1100,
  y: 400,
  alive: true,
};

var bacon = {
  x: 1150,
  y: 190,
  alive: true,
};

document.getElementById("up").onclick = function() {move(38);};
document.getElementById("down").onclick = function() {move(40);};
document.getElementById("right").onclick = function() {move(39);};
document.getElementById("left").onclick = function() {move(37);};

var puppyImg = document.getElementById("puppy");
var boneImg1 = document.getElementById("bone1");
var boneImg2 = document.getElementById("bone2");
var baconImg = document.getElementById("bacon");

var foodCount = 3;

function move(direction){
  if (puppy.canMove){
    food_move(bone1, boneImg1);
    food_move(bone2, boneImg2);
    food_move(bacon, baconImg);
  if (puppy.canMove){
    if (direction.keyCode === 38 || direction === 38){ // move up
      if (puppy.y > 50){
        puppy.y = (puppy.y - 10);
        puppyImg.style.top = (puppy.y + "px");
      }
    }else if (direction.keyCode === 40 || direction === 40){ // move down
      if (puppy.y < 490){
        puppy.y = (puppy.y + 10);
        puppyImg.style.top = (puppy.y + "px");
      }
    }else if (direction.keyCode === 39 || direction == 39){ // move right
      if (puppy.x < 1160){
        puppy.x = (puppy.x + 10);
        puppyImg.style.left = (puppy.x + "px");
      }

    }else if (direction.keyCode === 37 || direction == 37){ // move left
      if (puppy.x > 550){
        puppy.x = (puppy.x - 10);
        puppyImg.style.left = (puppy.x + "px");
      }
    }
    eat(bone1, boneImg1);
    eat(bone2, boneImg2);
    eat(bacon, baconImg);
    setTimeout(function(){
      puppy.canMove = true;
    }, 200)
    puppy.canMove = false;
}
}
}

function food_move(food, foodImg){
  var random = Math.floor((Math.random() * 4) + 1);
  if (random === 1){
    if (food.y > 50){
      food.y = (food.y - 20);
      foodImg.style.top = (food.y + "px");
    }
  }else if (random === 2){
    if (food.y < 490){
      food.y = (food.y + 20);
      foodImg.style.top = (food.y + "px");
    }
  }else if (random === 3){
    if (food.x < 1200){
      food.x = (food.x + 20);
      foodImg.style.left = (food.x + "px");
    }
  }else{
    if (food.x > 550){
      food.x = (food.x - 20);
      foodImg.style.left = (food.x + "px");
    }
 }
}

function eat(food, foodImg){
  if (puppy.x === food.x && puppy.y === food.y && food.alive){
    foodCount -= 1;
    food.alive = false;
    setTimeout(function(){
      foodImg.style.opacity = "0";
      foodImg.style.transform = 'rotate(360deg) scale(5)';
      if (foodCount < 1){
        alert("Pepper is full! Thanks for feeding her!! YOU WIN!!!");
      } else {
        alert("Yummy!");
      }
    }, 400);
  }
}

document.onkeydown = move;<commit_msg>Test eat function<commit_after>var puppy = {
  x: 550,
  y: 490,
  hungry: true,
  won: false,
  canMove: true,
};

var bone1 = {
  x: 750,
  y: 200,
  hungry: true,
};

var bone2 = {
  x: 1100,
  y: 400,
  hungry: true,
};

var bacon = {
  x: 1150,
  y: 190,
  hungry: true,
};

document.getElementById("up").onclick = function() {move(38);};
document.getElementById("down").onclick = function() {move(40);};
document.getElementById("right").onclick = function() {move(39);};
document.getElementById("left").onclick = function() {move(37);};

var puppyImg = document.getElementById("puppy");
var boneImg1 = document.getElementById("bone1");
var boneImg2 = document.getElementById("bone2");
var baconImg = document.getElementById("bacon");

var foodCount = 3;

function move(direction){
  if (puppy.canMove){
    food_move(bone1, boneImg1);
    food_move(bone2, boneImg2);
    food_move(bacon, baconImg);
  if (puppy.canMove){
    if (direction.keyCode === 38 || direction === 38){ // move up
      if (puppy.y > 50){
        puppy.y = (puppy.y - 20);
        puppyImg.style.top = (puppy.y + "px");
      }
    }else if (direction.keyCode === 40 || direction === 40){ // move down
      if (puppy.y < 490){
        puppy.y = (puppy.y + 20);
        puppyImg.style.top = (puppy.y + "px");
      }
    }else if (direction.keyCode === 39 || direction == 39){ // move right
      if (puppy.x < 1160){
        puppy.x = (puppy.x + 20);
        puppyImg.style.left = (puppy.x + "px");
      }

    }else if (direction.keyCode === 37 || direction == 37){ // move left
      if (puppy.x > 550){
        puppy.x = (puppy.x - 20);
        puppyImg.style.left = (puppy.x + "px");
      }
    }
    eat(bone1, boneImg1);
    eat(bone2, boneImg2);
    eat(bacon, baconImg);
    setTimeout(function(){
      puppy.canMove = true;
    }, 200)
    puppy.canMove = false;
}
}
}

function food_move(food, foodImg){
  var random = Math.floor((Math.random() * 4) + 1);
  if (random === 1){
    if (food.y > 50){
      food.y = (food.y - 20);
      foodImg.style.top = (food.y + "px");
    }
  }else if (random === 2){
    if (food.y < 490){
      food.y = (food.y + 20);
      foodImg.style.top = (food.y + "px");
    }
  }else if (random === 3){
    if (food.x < 1160){
      food.x = (food.x + 20);
      foodImg.style.left = (food.x + "px");
    }
  }else{
    if (food.x > 550){
      food.x = (food.x - 20);
      foodImg.style.left = (food.x + "px");
    }
 }
}

function eat(food, foodImg){
  if (puppy.x === food.x && puppy.y === food.y && food.hungry){
    foodCount -= 1;
    food.hungry = false;
    setTimeout(function(){
      foodImg.style.opacity = "0";
      foodImg.style.transform = 'rotate(360deg) scale(5)';
      if (foodCount < 1){
        alert("Pepper is full! Thanks for feeding her!! YOU WIN!!!");
      } else {
        alert("Yummy!");
      }
    }, 400);
  }
}

document.onkeydown = move;<|endoftext|>


<commit_before>// I18N constants
// LANG: "fr", ENCODING: UTF-8
{
  "Bold": "Gras",
  "Italic": "Italique",
  "Underline": "Souligné",
  "Strikethrough": "Barré",
  "Subscript": "Indice",
  "Superscript": "Exposant",
  "Justify Left": "Aligner à gauche",
  "Justify Center": "Centrer",
  "Justify Right": "Aligner à droite",
  "Justify Full": "Justifier",
  "Ordered List": "Liste numérotée",
  "Bulleted List": "Liste à puces",
  "Decrease Indent": "Diminuer le retrait",
  "Increase Indent": "Augmenter le retrait",
  "Font Color": "Couleur de police",
  "Background Color": "Surlignage",
  "Horizontal Rule": "Ligne horizontale",
  "Insert Web Link": "Insérer un lien",
  "Insert/Modify Image": "Insérer / Modifier une image",
  "Insert Table": "Insérer un tableau",
  "Toggle HTML Source": "Afficher / Masquer code source",
  "Enlarge Editor": "Agrandir l'éditeur",
  "About this editor": "A propos",
  "Help using editor": "Aide",
  "Current style": "Style courant",
  "Undoes your last action": "Annuler la dernière action",
  "Redoes your last action": "Répéter la dernière action",
  "Cut selection": "Couper la sélection",
  "Copy selection": "Copier la sélection",
  "Paste from clipboard": "Coller depuis le presse-papier",
  "Direction left to right": "Direction de gauche à droite",
  "Direction right to left": "Direction de droite à gauche",
  "Remove formatting": "Supprimer mise en forme",
  "Select all": "Tout sélectionner",
  "Print document": "Imprimer document",
  "Clear MSOffice tags": "Supprimer tags MSOffice",
  "Clear Inline Font Specifications": "Supprimer paramètres inline de la police",
  "Would you like to clear font typefaces?": "Voulez-vous supprimer les types ?",
  "Would you like to clear font sizes?": "Voulez-vous supprimer les tailles ?",
  "Would you like to clear font colours?": "Voulez-vous supprimer les couleurs ?",
  "Split Block": "Séparer les blocs",
  "Toggle Borders": "Afficher / Masquer les bordures",
  "Save as": "Enregistrer sous",
  "Insert/Overwrite": "Insertion / Remplacement",
  "— format —": "— Format —",
  "Heading 1": "Titre 1",
  "Heading 2": "Titre 2",
  "Heading 3": "Titre 3",
  "Heading 4": "Titre 4",
  "Heading 5": "Titre 5",
  "Heading 6": "Titre 6",
  "Normal": "Normal",
  "Address": "Adresse",
  "Formatted": "Formaté",

  //dialogs
  "OK": "OK",
  "Cancel": "Annuler",
  "Path": "Chemin",
  "You are in TEXT MODE.  Use the [<>] button to switch back to WYSIWYG.": "Vous êtes en MODE TEXTE.  Appuyez sur le bouton [<>] pour retourner au mode WYSIWYG.",
  "The Paste button does not work in Mozilla based web browsers (technical security reasons). Press CTRL-V on your keyboard to paste directly.": "Le bouton Coller ne fonctionne pas sur les navigateurs basés sur Mozilla (pour des raisons de sécurité). Pressez CTRL-V au clavier pour coller directement.",
  "Your Document is not well formed. Check JavaScript console for details.": "Le document est mal formé. Vérifiez la console JavaScript pour plus de détails.",

  "Alignment:": "Alignement",
  "Not set": "Indéfini",
  "Left": "Gauche",
  "Right": "Droite",
  "Texttop": "Texttop",
  "Absmiddle": "Absmiddle",
  "Baseline": "Baseline",
  "Absbottom": "Absbottom",
  "Bottom": "Bas",
  "Middle": "Milieu",
  "Top": "Haut",

  "Layout": "Mise en page",
  "Spacing": "Espacement",
  "Horizontal:": "Horizontal",
  "Horizontal padding": "Marge horizontale interne",
  "Vertical:": "Vertical",
  "Vertical padding": "Marge verticale interne",
  "Border thickness:": "Epaisseur de bordure",
  "Leave empty for no border": "Laisser vide pour pas de bordure",

  //Insert Link
  "Insert/Modify Link": "Insérer / Modifier un lien",
  "None (use implicit)": "Aucune (implicite)",
  "New window (_blank)": "Nouvelle fenêtre (_blank)",
  "Same frame (_self)": "Même frame (_self)",
  "Top frame (_top)": "Frame principale (_top)",
  "Other": "Autre",
  "Target:": "Cible",
  "Title (tooltip):": "Texte alternatif",
  "URL:": "URL:",
  "You must enter the URL where this link points to": "Vous devez entrer l'URL de ce lien",
  "You need to select some text before creating a link": "Vous devez sélectionner du texte avant de créer un lien",

  // Insert Table
  "Insert Table": "Insérer un tableau",
  "Rows:": "Lignes",
  "Number of rows": "Nombre de lignes",
  "Cols:": "Colonnes",
  "Number of columns": "Nombre de colonnes",
  "Width:": "Largeur",
  "Width of the table": "Largeur du tableau",
  "Percent": "Pourcent",
  "Pixels": "Pixels",
  "Em": "Em",
  "Width unit": "Unités de largeur",
  "Fixed width columns": "Colonnes à taille fixe",
  "Positioning of this table": "Position du tableau",
  "Cell spacing:": "Espacement",
  "Space between adjacent cells": "Espace entre les cellules adjacentes",
  "Cell padding:": "Marge interne",
  "Space between content and border in cell": "Espace entre le contenu et la bordure d'une cellule",
  "You must enter a number of rows": "Vous devez entrer le nombre de lignes",
  "You must enter a number of columns": "Vous devez entrer le nombre de colonnes",

  // Insert Image
  "Insert Image": "Insérer une image",
  "Image URL:": "URL image",
  "Enter the image URL here": "Entrer l'URL de l'image ici",
  "Preview": "Prévisualiser",
  "Preview the image in a new window": "Prévisualiser l'image dans une nouvelle fenêtre",
  "Alternate text:": "Texte alternatif",
  "For browsers that don't support images": "Pour les navigateurs qui ne supportent pas les images",
  "Positioning of this image": "Position de l'image",
  "Image Preview:": "Prévisualisation",
  "You must enter the URL": "Vous devez entrer l'URL",

  // toolbar
  "button_bold": "fr/bold.gif",
  "button_underline": "fr/underline.gif",
  "button_strikethrough": "fr/strikethrough.gif",

  // Editor Help
  "Xinha Help": "Aide Xinha",
  "Editor Help": "Aide de l'éditeur",
  "Keyboard shortcuts": "Raccourcis clavier",
  "The editor provides the following key combinations:": "L'éditeur fournit les combinaisons de touches suivantes :",
  "ENTER": "ENTREE",
  "new paragraph": "Nouveau paragraphe",
  "SHIFT-ENTER": "SHIFT+ENTREE",
  "insert linebreak": "Insère un saut de ligne",
  "Set format to paragraph": "Applique le format paragraphe",
  "Clean content pasted from Word": "Nettoyage du contenu copié depuis Word",
  "Headings": "Titres",
  "Close": "Fermer",

  // Loading messages
  "Loading in progress. Please wait!": "Chargement en cours. Veuillez patienter!",
  "Finishing" : "Chargement bientôt terminé",
  "Constructing object": "Construction de l'objet",
  "Create Toolbar": "Construction de la barre d'icones",
  "Create Statusbar": "Construction de la barre de status",
  "Register right panel" : "Enregistrement du panneau droit",
  "Register left panel" : "Enregistrement du panneau gauche",
  "Register bottom panel" : "Enregistrement du panneau supérieur",
  "Register top panel" : "Enregistrement du panneau inférieur",
  "Generate Xinha framework": "Génération de Xinha",
  "Init editor size": "Initialisation de la taille d'édition",
  "Init IFrame": "Initialisation de l'iframe",
  "Register plugin $plugin": "Enregistrement du plugin $plugin"
  "Loading plugin $plugin" : "Chargement du plugin $plugin"

};<commit_msg>last comma missing<commit_after>// I18N constants
// LANG: "fr", ENCODING: UTF-8
{
  "Bold": "Gras",
  "Italic": "Italique",
  "Underline": "Souligné",
  "Strikethrough": "Barré",
  "Subscript": "Indice",
  "Superscript": "Exposant",
  "Justify Left": "Aligner à gauche",
  "Justify Center": "Centrer",
  "Justify Right": "Aligner à droite",
  "Justify Full": "Justifier",
  "Ordered List": "Liste numérotée",
  "Bulleted List": "Liste à puces",
  "Decrease Indent": "Diminuer le retrait",
  "Increase Indent": "Augmenter le retrait",
  "Font Color": "Couleur de police",
  "Background Color": "Surlignage",
  "Horizontal Rule": "Ligne horizontale",
  "Insert Web Link": "Insérer un lien",
  "Insert/Modify Image": "Insérer / Modifier une image",
  "Insert Table": "Insérer un tableau",
  "Toggle HTML Source": "Afficher / Masquer code source",
  "Enlarge Editor": "Agrandir l'éditeur",
  "About this editor": "A propos",
  "Help using editor": "Aide",
  "Current style": "Style courant",
  "Undoes your last action": "Annuler la dernière action",
  "Redoes your last action": "Répéter la dernière action",
  "Cut selection": "Couper la sélection",
  "Copy selection": "Copier la sélection",
  "Paste from clipboard": "Coller depuis le presse-papier",
  "Direction left to right": "Direction de gauche à droite",
  "Direction right to left": "Direction de droite à gauche",
  "Remove formatting": "Supprimer mise en forme",
  "Select all": "Tout sélectionner",
  "Print document": "Imprimer document",
  "Clear MSOffice tags": "Supprimer tags MSOffice",
  "Clear Inline Font Specifications": "Supprimer paramètres inline de la police",
  "Would you like to clear font typefaces?": "Voulez-vous supprimer les types ?",
  "Would you like to clear font sizes?": "Voulez-vous supprimer les tailles ?",
  "Would you like to clear font colours?": "Voulez-vous supprimer les couleurs ?",
  "Split Block": "Séparer les blocs",
  "Toggle Borders": "Afficher / Masquer les bordures",
  "Save as": "Enregistrer sous",
  "Insert/Overwrite": "Insertion / Remplacement",
  "— format —": "— Format —",
  "Heading 1": "Titre 1",
  "Heading 2": "Titre 2",
  "Heading 3": "Titre 3",
  "Heading 4": "Titre 4",
  "Heading 5": "Titre 5",
  "Heading 6": "Titre 6",
  "Normal": "Normal",
  "Address": "Adresse",
  "Formatted": "Formaté",

  //dialogs
  "OK": "OK",
  "Cancel": "Annuler",
  "Path": "Chemin",
  "You are in TEXT MODE.  Use the [<>] button to switch back to WYSIWYG.": "Vous êtes en MODE TEXTE.  Appuyez sur le bouton [<>] pour retourner au mode WYSIWYG.",
  "The Paste button does not work in Mozilla based web browsers (technical security reasons). Press CTRL-V on your keyboard to paste directly.": "Le bouton Coller ne fonctionne pas sur les navigateurs basés sur Mozilla (pour des raisons de sécurité). Pressez CTRL-V au clavier pour coller directement.",
  "Your Document is not well formed. Check JavaScript console for details.": "Le document est mal formé. Vérifiez la console JavaScript pour plus de détails.",

  "Alignment:": "Alignement",
  "Not set": "Indéfini",
  "Left": "Gauche",
  "Right": "Droite",
  "Texttop": "Texttop",
  "Absmiddle": "Absmiddle",
  "Baseline": "Baseline",
  "Absbottom": "Absbottom",
  "Bottom": "Bas",
  "Middle": "Milieu",
  "Top": "Haut",

  "Layout": "Mise en page",
  "Spacing": "Espacement",
  "Horizontal:": "Horizontal",
  "Horizontal padding": "Marge horizontale interne",
  "Vertical:": "Vertical",
  "Vertical padding": "Marge verticale interne",
  "Border thickness:": "Epaisseur de bordure",
  "Leave empty for no border": "Laisser vide pour pas de bordure",

  //Insert Link
  "Insert/Modify Link": "Insérer / Modifier un lien",
  "None (use implicit)": "Aucune (implicite)",
  "New window (_blank)": "Nouvelle fenêtre (_blank)",
  "Same frame (_self)": "Même frame (_self)",
  "Top frame (_top)": "Frame principale (_top)",
  "Other": "Autre",
  "Target:": "Cible",
  "Title (tooltip):": "Texte alternatif",
  "URL:": "URL:",
  "You must enter the URL where this link points to": "Vous devez entrer l'URL de ce lien",
  "You need to select some text before creating a link": "Vous devez sélectionner du texte avant de créer un lien",

  // Insert Table
  "Insert Table": "Insérer un tableau",
  "Rows:": "Lignes",
  "Number of rows": "Nombre de lignes",
  "Cols:": "Colonnes",
  "Number of columns": "Nombre de colonnes",
  "Width:": "Largeur",
  "Width of the table": "Largeur du tableau",
  "Percent": "Pourcent",
  "Pixels": "Pixels",
  "Em": "Em",
  "Width unit": "Unités de largeur",
  "Fixed width columns": "Colonnes à taille fixe",
  "Positioning of this table": "Position du tableau",
  "Cell spacing:": "Espacement",
  "Space between adjacent cells": "Espace entre les cellules adjacentes",
  "Cell padding:": "Marge interne",
  "Space between content and border in cell": "Espace entre le contenu et la bordure d'une cellule",
  "You must enter a number of rows": "Vous devez entrer le nombre de lignes",
  "You must enter a number of columns": "Vous devez entrer le nombre de colonnes",

  // Insert Image
  "Insert Image": "Insérer une image",
  "Image URL:": "URL image",
  "Enter the image URL here": "Entrer l'URL de l'image ici",
  "Preview": "Prévisualiser",
  "Preview the image in a new window": "Prévisualiser l'image dans une nouvelle fenêtre",
  "Alternate text:": "Texte alternatif",
  "For browsers that don't support images": "Pour les navigateurs qui ne supportent pas les images",
  "Positioning of this image": "Position de l'image",
  "Image Preview:": "Prévisualisation",
  "You must enter the URL": "Vous devez entrer l'URL",

  // toolbar
  "button_bold": "fr/bold.gif",
  "button_underline": "fr/underline.gif",
  "button_strikethrough": "fr/strikethrough.gif",

  // Editor Help
  "Xinha Help": "Aide Xinha",
  "Editor Help": "Aide de l'éditeur",
  "Keyboard shortcuts": "Raccourcis clavier",
  "The editor provides the following key combinations:": "L'éditeur fournit les combinaisons de touches suivantes :",
  "ENTER": "ENTREE",
  "new paragraph": "Nouveau paragraphe",
  "SHIFT-ENTER": "SHIFT+ENTREE",
  "insert linebreak": "Insère un saut de ligne",
  "Set format to paragraph": "Applique le format paragraphe",
  "Clean content pasted from Word": "Nettoyage du contenu copié depuis Word",
  "Headings": "Titres",
  "Close": "Fermer",

  // Loading messages
  "Loading in progress. Please wait!": "Chargement en cours. Veuillez patienter!",
  "Finishing" : "Chargement bientôt terminé",
  "Constructing object": "Construction de l'objet",
  "Create Toolbar": "Construction de la barre d'icones",
  "Create Statusbar": "Construction de la barre de status",
  "Register right panel" : "Enregistrement du panneau droit",
  "Register left panel" : "Enregistrement du panneau gauche",
  "Register bottom panel" : "Enregistrement du panneau supérieur",
  "Register top panel" : "Enregistrement du panneau inférieur",
  "Generate Xinha framework": "Génération de Xinha",
  "Init editor size": "Initialisation de la taille d'édition",
  "Init IFrame": "Initialisation de l'iframe",
  "Register plugin $plugin": "Enregistrement du plugin $plugin",
  "Loading plugin $plugin" : "Chargement du plugin $plugin"

};<|endoftext|>


<commit_before>(function () {
    var lang = {
            months : "januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december".split("_"),
            monthsShort : "jan._feb._mar._apr._mei._jun._jul._aug._sep._okt._nov._dec.".split("_"),
            weekdays : "zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag".split("_"),
            weekdaysShort : "zo._ma._di._wo._do._vr._za.".split("_"),
            longDateFormat : {
                L : "DD-MM-YYYY",
                LL : "MMMM D YYYY",
                LLL : "MMMM D YYYY HH:mm",
                LLLL : "dddd, D MMMM YYYY HH:mm"
            },
            meridiem : {
                AM : 'AM',
                am : 'am',
                PM : 'PM',
                pm : 'pm'
            },
            relativeTime : {
                future : "over %s",
                past : "%s geleden",
                s : "een paar seconden",
                m : "één minuutje",
                mm : "%d minuten",
                h : "één uur",
                hh : "%d uren",
                d : "één dag",
                dd : "%d dagen",
                M : "één maand",
                MM : "%d maanden",
                y : "één jaar",
                yy : "%d jaren"
            },
            ordinal : function (number) {
                return (number === 1 || number === 8 || number >= 20) ? 'ste' : 'de';
            }
        };

    // Node
    if (typeof module !== 'undefined') {
        module.exports = lang;
    }
    // Browser
    if (typeof window !== 'undefined' && this.moment && this.moment.lang) {
        this.moment.lang('nl', lang);
    }
}());
<commit_msg>improvements for Dutch localization:  - no plural forms for 'uur' and 'jaar'  - 'een minuutje' is informal language<commit_after>(function () {
    var lang = {
            months : "januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december".split("_"),
            monthsShort : "jan._feb._mar._apr._mei._jun._jul._aug._sep._okt._nov._dec.".split("_"),
            weekdays : "zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag".split("_"),
            weekdaysShort : "zo._ma._di._wo._do._vr._za.".split("_"),
            longDateFormat : {
                L : "DD-MM-YYYY",
                LL : "D MMMM YYYY",
                LLL : "D MMMM YYYY HH:mm",
                LLLL : "dddd D MMMM YYYY HH:mm"
            },
            meridiem : {
                AM : 'AM',
                am : 'am',
                PM : 'PM',
                pm : 'pm'
            },
            relativeTime : {
                future : "over %s",
                past : "%s geleden",
                s : "een paar seconden",
                m : "één minuut",
                mm : "%d minuten",
                h : "één uur",
                hh : "%d uur",
                d : "één dag",
                dd : "%d dagen",
                M : "één maand",
                MM : "%d maanden",
                y : "één jaar",
                yy : "%d jaar"
            },
            ordinal : function (number) {
                return (number === 1 || number === 8 || number >= 20) ? 'ste' : 'de';
            }
        };

    // Node
    if (typeof module !== 'undefined') {
        module.exports = lang;
    }
    // Browser
    if (typeof window !== 'undefined' && this.moment && this.moment.lang) {
        this.moment.lang('nl', lang);
    }
}());
<|endoftext|>


<commit_before>!function($, _) {
	if (_.isUndefined(APP) || !APP.config) return false;
	APP.config = $.extend(true, APP.config, {
		L10n: {
			"%%c%% SMS": "",
			"%%r%% symbols": "",
			"%%type%% are available now": "",
			"%%type%% are not available": "No connection",
			"Address": "address",
			"All messages": "",
			"Chat": "",
			"Drag to change
Double click to send": "Drag to relocate.
Double-click to send.",
			"Drivers": "",
			"Execution time: %%title%%": "",
			"Export to .xml": "",
			"Forever": "",
			"Geofences": "",
			"History is not available": "",
			"Incoming": "",
			"Latest": "",
			"Latest message: %%d%% %%t%%": "",
			"Loading messages": "",
			"Message is not delivered": "Not delivered.",
			"Message log": "",
			"Month": "",
			"Not enought rights or something else bad": "No connection",
			"Not found": "",
			"Not necessary to load module": "",
			"Oh! %%module%% didn't load!": "Error loading the app.",
			"Oh! Unfortunately, we can't load SDK": "Error loading the app.",
			"Oh! Unfortunately, we can't send coordinates": "Unable to send coordinates",
			"Oh! Unfortunately, you can't login": "Incorrect login data.",
			"Oh! We can't create command": "Unable to create command",
			"Oh! We can't fetch information": "Unable to retrieve information.",
			"Oh! We can't remove this message": "Unable to remove this message.",
			"Outgoing": "",
			"POIs": "",
			"Please, fill the correct data in configuration": "Incorrect login data.",
			"Points": "coordinates",
			"Possibility change (%%o%%)": "",
			"Press Enter to send": "",
			"Remaining": "",
			"SMS": "",
			"Save": "",
			"Send coordinates": "Position as",
			"Sent coordinates": "Coordinates",
			"Session has been lost": "Session lost.",
			"Show in folder": "",
			"Show messages": "",
			"Show on map": "",
			"Something wrong": "Error loading the app.",
			"Speed: %%c%% %%measure%%": "",
			"The message was removed": "Message deleted.",
			"There are no message to export": "No messages to export.",
			"Today": "",
			"Translation": "",
			"Units": "",
			"Unknown": "",
			"Week": "",
			"Window resized": "",
			"XML comments": "Attributes msgset: *name: unit or driver name; *type: type (unit, driver); *phones: available phone numbers. Attributes msg: *ts: message time (UTC); *type: message type (out - outgoing, in - incoming); *link: communication type (tcp ot sms); *flag: flags (1 - text, 2 - image, 3 - coordinates, 4 - alert); *text - message body.",
			"Yesterday": "",
			"You didn't choose anything": "",
			"You didn't choose phone number or something else": "",
			"[%%time%%] %%title%% started": "",
			"km/h": "",
			"lang": "en",
			"locale": "en_GB",
			"mph": ""
		},
		localization: {
			"days": ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
			"days_short": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
			"months": ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
			"months_short": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
		}
	});
}(jQuery, _);
<commit_msg>Update sk.js<commit_after>!function($, _) {
	if (_.isUndefined(APP) || !APP.config) return false;
	APP.config = $.extend(true, APP.config, {
		L10n: {
			"%%c%% SMS": "",
			"%%r%% symbols": "symboly",
			"%%type%% are available now": "%%type%% je práve k dispozícii",
			"%%type%% are not available": "Bez pripojenia",
			"Address": "Adresa",
			"All messages": "Všetky správy",
			"Chat": "",
			"Drag to change
Double click to send": "Ťahaním presunúť.
Dvojklikom odoslať.",
			"Drivers": "Vodiči",
			"Execution time: %%title%%": "Čas vykonania: %%title%%",
			"Export to .xml": "Export do .xml",
			"Forever": "Navždy",
			"Geofences": "Zóny ohraničenia",
			"History is not available": "História nie je dostupná",
			"Incoming": "Prichadzajúce",
			"Latest": "Posledné",
			"Latest message: %%d%% %%t%%": "Posledné správy: %%d%% %%t%%",
			"Loading messages": "Načítanie správ",
			"Message is not delivered": "Správa nebola doručená.",
			"Message log": "Denník správ",
			"Month": "Mesiac",
			"Not enought rights or something else bad": "Bez pripojenia",
			"Not found": "Nenájdené",
			"Not necessary to load module": "Nie je nutné načítať modul",
			"Oh! %%module%% didn't load!": "Chyba načítania aplikácie.",
			"Oh! Unfortunately, we can't load SDK": "Chyba pri načítaní aplikácie.",
			"Oh! Unfortunately, we can't send coordinates": "Nie je možné odoslať súradnice",
			"Oh! Unfortunately, you can't login": "Nesprávne prihlasovacie údaje.",
			"Oh! We can't create command": "Nie je možné vytvoriť príkaz",
			"Oh! We can't fetch information": "Nie je možné načítať informácie.",
			"Oh! We can't remove this message": "Nie je možné odstrániť túto správu.",
			"Outgoing": "Odoslané",
			"POIs": "Body záujmu",
			"Please, fill the correct data in configuration": "Nesprávne prihlasovacie údaje.",
			"Points": "súradnice",
			"Possibility change (%%o%%)": "Zmena možností (%%o%%)",
			"Press Enter to send": "Pre odoslanie stlačte Enter",
			"Remaining": "Zostávajúce",
			"SMS": "SMS",
			"Save": "Uložiť",
			"Send coordinates": "Pozícia ako",
			"Sent coordinates": "Súradnice",
			"Session has been lost": "Relácia stratená.",
			"Show in folder": "Pozri v priečinku",
			"Show messages": "Pozri správu",
			"Show on map": "Pozri na mape",
			"Something wrong": "Chyba pri načítaní aplikácie.",
			"Speed: %%c%% %%measure%%": "Rýchlosť: %%c%% %%measure%%",
			"The message was removed": "Správa bola vymazaná.",
			"There are no message to export": "Žiadna správa pre export.",
			"Today": "Dnes",
			"Translation": "Preklad",
			"Units": "Vozidlá",
			"Unknown": "Neznámy",
			"Week": "Týždeň",
			"Window resized": "Zmena veľkosti okna",
			"XML comments": "Attributes msgset: *name: Názov vozidla alebo vodiča; *type: typ (vozidlo, vodič); *phones: dostupné telefónne čísla. Attributes msg: *ts: čas správy (UTC); *type: typ správy (out - odoslané, in - doručené); *link: typ komunikácie (tcp alebo sms); *flag: vlajky (1 - text, 2 - obrázok, 3 - súradnice, 4 - poplach); *text - tvar správy.",
			"Yesterday": "Včera",
			"You didn't choose anything": "Nič ste nevybrali",
			"You didn't choose phone number or something else": "Nevybrali ste telefónne číslo, alebo niečo iné",
			"[%%time%%] %%title%% started": "",
			"km/h": "",
			"lang": "sk",
			"locale": "sk_SK",
			"mph": ""
		},
		localization: {
			"days": ["Nedeľa", "Pondelok", "Utorok", "Streda", "Štvrtok", "Piatok", "Sobota"],
			"days_short": ["Ne", "Po", "Ut", "St", "Št", "Pi", "So"],
			"months": ["Január", "Február", "Marec", "Apríl", "Máj", "Jún", "Júl", "August", "September", "Október", "November", "December"],
			"months_short": ["Jan", "Feb", "Mar", "Apr", "Máj", "Jún", "Júl", "Aug", "Sep", "Okt", "Nov", "Dec"]
		}
	});
}(jQuery, _);
<|endoftext|>


<commit_before>import React, { PropTypes } from 'react';
import Radium from 'radium';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';

import * as authActions from '../actions/authActions';
import Navbar from './Navbar';

const css = {
  base: {
    marginTop: 56
  }
};

@Radium
@connect(
  state => ({ user: state.auth.user }),
  dispatch => ({
    actions: bindActionCreators(authActions, dispatch)
  })
)
export default class Application extends React.Component {

  static propTypes = {
    children: PropTypes.any,
    user: PropTypes.object,
    actions: PropTypes.object,
    location: PropTypes.object
  };

  static contextTypes = {
    router: PropTypes.object.isRequired
  }

  constructor(props, context) {
    super(props, context);
  }

  componentWillReceiveProps(nextProps) {
    if (!this.props.user && nextProps.user && this.props.location.pathname.includes('login')) {
      // login
      this.context.router.replaceWith('/profile');
    } else if (this.props.user && !nextProps.user) {
      // logout
      this.context.router.transitionTo('/');
    }
  }

  render() {
    const {user, actions} = this.props;

    return (

        <Navbar user={user} logout={actions.logout}/>

          {/* this will render the child routes */}
          {this.props.children}

    );
  };
}
<commit_msg>Fix redirect on signup<commit_after>import React, { PropTypes } from 'react';
import Radium from 'radium';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';

import * as authActions from '../actions/authActions';
import Navbar from './Navbar';

const css = {
  base: {
    marginTop: 56
  }
};

@Radium
@connect(
  state => ({ user: state.auth.user }),
  dispatch => ({
    actions: bindActionCreators(authActions, dispatch)
  })
)
export default class Application extends React.Component {

  static propTypes = {
    children: PropTypes.any,
    user: PropTypes.object,
    actions: PropTypes.object,
    location: PropTypes.object
  };

  static contextTypes = {
    router: PropTypes.object.isRequired
  }

  constructor(props, context) {
    super(props, context);
  }

  componentWillReceiveProps(nextProps) {
    if (!this.props.user && nextProps.user && /login|signup/.test(this.props.location.pathname)) {
      // login
      this.context.router.replaceWith('/profile');
    } else if (this.props.user && !nextProps.user) {
      // logout
      this.context.router.transitionTo('/');
    }
  }

  render() {
    const {user, actions} = this.props;

    return (

        <Navbar user={user} logout={actions.logout}/>

          {/* this will render the child routes */}
          {this.props.children}

    );
  };
}
<|endoftext|>


<commit_before>"use strict";

const HOUR = 3600;
const DAY = HOUR * 24;
const WEEK = DAY * 7;

const PERIOD_UNITS = {
    "h": HOUR,
    "d": DAY,
    "w": WEEK,
};

const PERIOD_UNIT_KEYS = Object.keys(PERIOD_UNITS);

/**
 * A small helper object that counts into buckets the number of calls to its
 * bump that fall into the given age categories.
 * Counts are maintained within the object, and can be fetched to set
 * into a gauge metric object.
 *
 * This class is useful when exporting metrics that count the number of
 * hourly/daily/weekly active instances of various types of object within the
 * bridge.
 */

class AgeCounters {
    /***
     * @param {String[]} counterPeriods A set of strings denoting the bucket periods
     * used by the gauge. It is in the format of '#X' where # is the integer period and
     * X is the unit of time. A unit can be one of 'h, d, w' for hours, days and weeks.
     * 7d would be 7 days. If not given, the periods are 1h, 1d and 7d.
     */
    constructor(counterPeriods) {
        counterPeriods = counterPeriods || ["1h", "1d", "7d"];
        this.counters = new Map();
        this.counterPeriods = counterPeriods;
        counterPeriods.forEach((periodKey) => {
            if (periodKey.length < 2) {
                throw Error("A period must contain a unit.");
            }
            const unit = periodKey[periodKey.length-1];
            if (!PERIOD_UNIT_KEYS.includes(unit)) {
                throw Error(`The unit period must be one of '${PERIOD_UNIT_KEYS.join(",")}'`);
            }
            const number = parseInt(periodKey.substr(0,periodKey.length-1));
            if (isNaN(number)) {
                throw Error("The period duration is invalid.");
            }
            this.counters.set(number * PERIOD_UNITS[unit], 0);
        });
        this.counterPeriods.push("all");
        this.counters.set("all", 0);
    }

    /**
     * Increment the values of the internal counters depending on the given age,
     * in seconds.
     *
     * @param {Number} age The age in seconds.
     */
    bump(age) {
        this.counters.forEach((value, key) => {
            if (key === "all") {
                this.counters.set("all", value + 1);
            }
            else if (age < key) {
                this.counters.set(key, value + 1);
            }
        });
    };

    /**
     * Fetch the counts in the age buckets and set them as labeled observations in
     * the given gauge metric instance.
     *
     * @param {Gauge} gauge The gauge metric instance.
     * @param {Object} morelabels An object containing more labels to add to the
     * gauge when setting values.
     */
    setGauge(gauge, morelabels) {
        const counters = this.counters;
        let i = 0;
        counters.forEach((value) => {
            const labels = Object.assign(
                {
                    age: this.counterPeriods[i]
                },
                morelabels
            );
            gauge.set(labels, value);
            i++;
        });
    };
}

module.exports = AgeCounters;
<commit_msg>Must be a positive integer<commit_after>"use strict";

const HOUR = 3600;
const DAY = HOUR * 24;
const WEEK = DAY * 7;

const PERIOD_UNITS = {
    "h": HOUR,
    "d": DAY,
    "w": WEEK,
};

const PERIOD_UNIT_KEYS = Object.keys(PERIOD_UNITS);

/**
 * A small helper object that counts into buckets the number of calls to its
 * bump that fall into the given age categories.
 * Counts are maintained within the object, and can be fetched to set
 * into a gauge metric object.
 *
 * This class is useful when exporting metrics that count the number of
 * hourly/daily/weekly active instances of various types of object within the
 * bridge.
 */

class AgeCounters {
    /***
     * @param {String[]} counterPeriods A set of strings denoting the bucket periods
     * used by the gauge. It is in the format of '#X' where # is the integer period and
     * X is the unit of time. A unit can be one of 'h, d, w' for hours, days and weeks.
     * 7d would be 7 days. If not given, the periods are 1h, 1d and 7d.
     */
    constructor(counterPeriods) {
        counterPeriods = counterPeriods || ["1h", "1d", "7d"];
        this.counters = new Map();
        this.counterPeriods = counterPeriods;
        counterPeriods.forEach((periodKey) => {
            if (periodKey.length < 2) {
                throw Error("A period must contain a unit.");
            }
            const unit = periodKey[periodKey.length-1];
            if (!PERIOD_UNIT_KEYS.includes(unit)) {
                throw Error(`The unit period must be one of '${PERIOD_UNIT_KEYS.join(",")}'`);
            }
            const number = parseInt(periodKey.substr(0,periodKey.length-1));
            if (isNaN(number) || number <= 0) {
                throw Error("The period duration must be a positive integer.");
            }
            this.counters.set(number * PERIOD_UNITS[unit], 0);
        });
        this.counterPeriods.push("all");
        this.counters.set("all", 0);
    }

    /**
     * Increment the values of the internal counters depending on the given age,
     * in seconds.
     *
     * @param {Number} age The age in seconds.
     */
    bump(age) {
        this.counters.forEach((value, key) => {
            if (key === "all") {
                this.counters.set("all", value + 1);
            }
            else if (age < key) {
                this.counters.set(key, value + 1);
            }
        });
    };

    /**
     * Fetch the counts in the age buckets and set them as labeled observations in
     * the given gauge metric instance.
     *
     * @param {Gauge} gauge The gauge metric instance.
     * @param {Object} morelabels An object containing more labels to add to the
     * gauge when setting values.
     */
    setGauge(gauge, morelabels) {
        const counters = this.counters;
        let i = 0;
        counters.forEach((value) => {
            const labels = Object.assign(
                {
                    age: this.counterPeriods[i]
                },
                morelabels
            );
            gauge.set(labels, value);
            i++;
        });
    };
}

module.exports = AgeCounters;
<|endoftext|>


<commit_before>// Unit test for a.console

module('core/console.js', {
    setup: function() {
        a.console.clear();
    },
    teardown: function() {
        a.console.clear();
    }
});

// Testing console 'log' mode
test('a.console.log', function() {
    a.console.log('one log', null, false);
    a.console.log('second log', null, false);
    a.console.log('third log', null, false);

    var trace = a.console.trace();

    strictEqual(trace['log'].length, 3, 'Testing log size');
    strictEqual(trace['log'][0], 'one log', 'Testing log trace');
    strictEqual(trace['log'][1], 'second log', 'Testing log trace');
    strictEqual(trace['log'][2], 'third log', 'Testing log trace');
});

// Testing console 'info' mode
test('a.console.info', function() {
    a.console.info('one information', null, false);
    a.console.info('second information', null, false);
    a.console.info('third information', null, false);

    var trace = a.console.trace();

    strictEqual(trace['info'].length, 3, 'Testing information size');
    strictEqual(trace['info'][0], 'one information',
                                    'Testing information trace');
    strictEqual(trace['info'][1], 'second information',
                                    'Testing information trace');
    strictEqual(trace['info'][2], 'third information',
                                    'Testing information trace');
});

// Testing console 'warning' mode
test('a.console.warn', function() {
    a.console.warn('one warning', null, false);
    a.console.warn('second warning', null, false);
    a.console.warn('third warning', null, false);

    var trace = a.console.trace();

    strictEqual(trace['warn'].length, 3, 'Testing warning size');
    strictEqual(trace['warn'][0], 'one warning', 'Testing warning trace');
    strictEqual(trace['warn'][1], 'second warning', 'Testing warning trace');
    strictEqual(trace['warn'][2], 'third warning', 'Testing warning trace');
});

// Testing console 'error' mode
test('a.console.error', function() {
    a.console.error('one error', null, false);
    a.console.error('second error', null, false);
    a.console.error('third error', null, false);

    var trace = a.console.trace();

    strictEqual(trace['error'].length, 3, 'Testing error size');
    strictEqual(trace['error'][0], 'one error', 'Testing error trace');
    strictEqual(trace['error'][1], 'second error', 'Testing error trace');
    strictEqual(trace['error'][2], 'third error', 'Testing error trace');
});

// Testing trace (console keep data...)
test('a.console.trace', function() {
    a.console.log('ok', null, false);
    a.console.log('ok2', null, false);
    a.console.log('ok3', null, false);
    a.console.warn('ok', null, false);

    var trace = a.console.trace();
    var log = trace['log'],
        warn = trace['warn'];

    strictEqual(log[0], 'ok', 'Testing trace content');
    strictEqual(log[1], 'ok2', 'Testing trace content');
    strictEqual(log[2], 'ok3', 'Testing trace content');
    strictEqual(warn[0], 'ok', 'Testing trace content');

    // Now we send more than 2000 request on log,
    // we check the trace remove too old data
    for(var i=0; i<2100; ++i) {
        a.console.log('ok', null, false);
    }

    var fullTrace = a.console.trace();
    strictEqual(fullTrace['log'].length, 2000, 'Testing full stack');
});

// Testing trace (console keep data...)
test('a.console.trace-type', function() {
    a.console.log('ok', null, false);
    a.console.log('ok2', null, false);
    a.console.log('ok3', null, false);
    a.console.warn('ok', null, false);

    var log = a.console.trace('log');

    strictEqual(log[0], 'ok', 'Testing trace content');
    strictEqual(log[1], 'ok2', 'Testing trace content');
    strictEqual(log[2], 'ok3', 'Testing trace content');

    // Now we send more than 2000 request on log,
    // we check the trace remove too old data
    for(var i=0; i<2100; ++i) {
        a.console.log('ok', null, false);
    }

    var fullLog = a.console.trace('log');
    strictEqual(fullLog.length, 2000, 'Testing full stack');
});

// Testing console clearing trace system
test('a.console.clear', function() {
    a.console.log('ok', null, false);
    a.console.warn('ok', null, false);

    var trace = a.console.trace();

    strictEqual(trace['log'].length, 1, 'Testing log before clear');
    strictEqual(trace['warn'].length, 1, 'Testing warning before clear');

    a.console.clear();
    var newTrace = a.console.trace();

    strictEqual(newTrace['log'].length, 0, 'Testing log after clear');
    strictEqual(newTrace['warn'].length, 0, 'Testing warning after clear');
});<commit_msg>Unit test console.js is now compatible with new QUnit rules.<commit_after>// Unit test for a.console

QUnit.module('core/console.js', {
    setup: function() {
        a.console.clear();
    },
    teardown: function() {
        a.console.clear();
    }
});

// Testing console 'log' mode
QUnit.test('a.console.log', function(assert) {
    expect(4);

    a.console.log('one log', null, false);
    a.console.log('second log', null, false);
    a.console.log('third log', null, false);

    var trace = a.console.trace();

    assert.strictEqual(trace['log'].length, 3, 'Testing log size');
    assert.strictEqual(trace['log'][0], 'one log', 'Testing log trace');
    assert.strictEqual(trace['log'][1], 'second log', 'Testing log trace');
    assert.strictEqual(trace['log'][2], 'third log', 'Testing log trace');
});

// Testing console 'info' mode
QUnit.test('a.console.info', function(assert) {
    expect(4);

    a.console.info('one information', null, false);
    a.console.info('second information', null, false);
    a.console.info('third information', null, false);

    var trace = a.console.trace();

    assert.strictEqual(trace['info'].length, 3, 'Testing information size');
    assert.strictEqual(trace['info'][0], 'one information',
                                    'Testing information trace');
    assert.strictEqual(trace['info'][1], 'second information',
                                    'Testing information trace');
    assert.strictEqual(trace['info'][2], 'third information',
                                    'Testing information trace');
});

// Testing console 'warning' mode
QUnit.test('a.console.warn', function(assert) {
    expect(4);

    a.console.warn('one warning', null, false);
    a.console.warn('second warning', null, false);
    a.console.warn('third warning', null, false);

    var trace = a.console.trace();

    assert.strictEqual(trace['warn'].length, 3, 'Testing warning size');
    assert.strictEqual(trace['warn'][0], 'one warning', 'Testing warning trace');
    assert.strictEqual(trace['warn'][1], 'second warning', 'Testing warning trace');
    assert.strictEqual(trace['warn'][2], 'third warning', 'Testing warning trace');
});

// Testing console 'error' mode
QUnit.test('a.console.error', function(assert) {
    expect(4);

    a.console.error('one error', null, false);
    a.console.error('second error', null, false);
    a.console.error('third error', null, false);

    var trace = a.console.trace();

    assert.strictEqual(trace['error'].length, 3, 'Testing error size');
    assert.strictEqual(trace['error'][0], 'one error', 'Testing error trace');
    assert.strictEqual(trace['error'][1], 'second error', 'Testing error trace');
    assert.strictEqual(trace['error'][2], 'third error', 'Testing error trace');
});

// Testing trace (console keep data...)
QUnit.test('a.console.trace', function(assert) {
    expect(5);

    a.console.log('ok', null, false);
    a.console.log('ok2', null, false);
    a.console.log('ok3', null, false);
    a.console.warn('ok', null, false);

    var trace = a.console.trace();
    var log = trace['log'],
        warn = trace['warn'];

    assert.strictEqual(log[0], 'ok', 'Testing trace content');
    assert.strictEqual(log[1], 'ok2', 'Testing trace content');
    assert.strictEqual(log[2], 'ok3', 'Testing trace content');
    assert.strictEqual(warn[0], 'ok', 'Testing trace content');

    // Now we send more than 2000 request on log,
    // we check the trace remove too old data
    for(var i=0; i<2100; ++i) {
        a.console.log('ok', null, false);
    }

    var fullTrace = a.console.trace();
    assert.strictEqual(fullTrace['log'].length, 2000, 'Testing full stack');
});

// Testing trace (console keep data...)
QUnit.test('a.console.trace-type', function(assert) {
    expect(4);

    a.console.log('ok', null, false);
    a.console.log('ok2', null, false);
    a.console.log('ok3', null, false);
    a.console.warn('ok', null, false);

    var log = a.console.trace('log');

    assert.strictEqual(log[0], 'ok', 'Testing trace content');
    assert.strictEqual(log[1], 'ok2', 'Testing trace content');
    assert.strictEqual(log[2], 'ok3', 'Testing trace content');

    // Now we send more than 2000 request on log,
    // we check the trace remove too old data
    for(var i=0; i<2100; ++i) {
        a.console.log('ok', null, false);
    }

    var fullLog = a.console.trace('log');
    assert.strictEqual(fullLog.length, 2000, 'Testing full stack');
});

// Testing console clearing trace system
QUnit.test('a.console.clear', function(assert) {
    expect(4);

    a.console.log('ok', null, false);
    a.console.warn('ok', null, false);

    var trace = a.console.trace();

    assert.strictEqual(trace['log'].length, 1, 'Testing log before clear');
    assert.strictEqual(trace['warn'].length, 1, 'Testing warning before clear');

    a.console.clear();
    var newTrace = a.console.trace();

    assert.strictEqual(newTrace['log'].length, 0, 'Testing log after clear');
    assert.strictEqual(newTrace['warn'].length, 0, 'Testing warning after clear');
});<|endoftext|>


<commit_before>var util = require('util'),
    log = require('czagenda-log').from(__filename),
    Node = require('czagenda-cluster').containers.Node,
    Container = require('czagenda-cluster').Container,
    settings = require('../../settings');

var CzagendaApi = function CzagendaApi() {
  Node.apply(this,Array.prototype.slice.call(arguments));
  this.network = Container.NETWORK.VETH;
};
util.inherits(CzagendaApi, Node);

CzagendaApi.type = 'czagendaapi';

CzagendaApi.prototype.getSetupTasks = function () {
	return Node.prototype.getSetupTasks.call(this).concat([this.installServer.bind(this), this.restartServer.bind(this)]);
}

CzagendaApi.prototype.installServer = function(callback) {

	log.info('Install czagenda-api');

  this.exec( [
      'mkdir -p /home/czagenda-api',
      'cd /home/czagenda-api',
      'git clone git://git.oxys.net/czagenda-api.git .',
      'cat settings.sample.js|sed "s/%IP%/'+this.getIp()+'/g" | sed "s/%ES_IP%/'+ settings.ELASTICSEARCH_FAILOVER +'/g" | sed "s/%REDIS_IP%/'+ settings.REDIS_FAILOVER +'/g" > settings.js',
    	'mkdir pids',
      'mkdir logs',
      'npm update',
      'chmod +x /home/czagenda-api/startup_scripts/startup-debian',
					'ln -s /home/czagenda-api/startup_scripts/startup-debian /etc/init.d/czagenda-api',
					'insserv czagenda-api'
    ].join(' && '), null, function(err,res) {
      if(err) {
            log.warning('czagenda-api install failed',err);
            callback(err);
            return;
          }
          log.info('czagenda-api install done');

          callback();
    }.bind(this));
}

CzagendaApi.prototype.restartServer= function(callback) {
  this.exec( [
    '/etc/init.d/czagenda-api restart'
  ].join(' && '), null, callback);
}

CzagendaApi.prototype.updateServer = function(callback) {
  this.exec( [
    'cd /home/czagenda-api',
    'git pull',
    'cat settings.sample.js|sed "s/%IP%/'+this.getIp()+'/g" | sed "s/%ES_IP%/'+ settings.ELASTICSEARCH_FAILOVER +'/g" | sed "s/%REDIS_IP%/'+ settings.REDIS_FAILOVER +'/g" > settings.js',
    'npm update'
  ].join(' && '), null, function(err,res) {
    if(err) {
      callback(err);
      return;
    }
    this.restartServer(callback);
  }.bind(this));
}
exports.Container = CzagendaApi<commit_msg>configure API with elasticsearch index from settings<commit_after>var util = require('util'),
    log = require('czagenda-log').from(__filename),
    Node = require('czagenda-cluster').containers.Node,
    Container = require('czagenda-cluster').Container,
    settings = require('../../settings');

var CzagendaApi = function CzagendaApi() {
  Node.apply(this,Array.prototype.slice.call(arguments));
  this.network = Container.NETWORK.VETH;
};
util.inherits(CzagendaApi, Node);

CzagendaApi.type = 'czagendaapi';

CzagendaApi.prototype.getSetupTasks = function () {
	return Node.prototype.getSetupTasks.call(this).concat([this.installServer.bind(this), this.restartServer.bind(this)]);
}

CzagendaApi.prototype.installServer = function(callback) {

	log.info('Install czagenda-api');

  this.exec( [
      'mkdir -p /home/czagenda-api',
      'cd /home/czagenda-api',
      'git clone git://git.oxys.net/czagenda-api.git .',
      'cat settings.sample.js|sed "s/%IP%/'+this.getIp()+'/g" | sed "s/%ES_IP%/'+ settings.ELASTICSEARCH_FAILOVER +'/g" | sed "s/%REDIS_IP%/'+ settings.REDIS_FAILOVER +'/g" | sed "s/%ES_INDEX%/'+ settings.ELASTICSEARCH_INDEX_NAME +'/g" > settings.js',
    	'mkdir pids',
      'mkdir logs',
      'npm update',
      'chmod +x /home/czagenda-api/startup_scripts/startup-debian',
					'ln -s /home/czagenda-api/startup_scripts/startup-debian /etc/init.d/czagenda-api',
					'insserv czagenda-api'
    ].join(' && '), null, function(err,res) {
      if(err) {
            log.warning('czagenda-api install failed',err);
            callback(err);
            return;
          }
          log.info('czagenda-api install done');

          callback();
    }.bind(this));
}

CzagendaApi.prototype.restartServer= function(callback) {
  this.exec( [
    '/etc/init.d/czagenda-api restart'
  ].join(' && '), null, callback);
}

CzagendaApi.prototype.updateServer = function(callback) {
  this.exec( [
    'cd /home/czagenda-api',
    'git pull',
    'cat settings.sample.js|sed "s/%IP%/'+this.getIp()+'/g" | sed "s/%ES_IP%/'+ settings.ELASTICSEARCH_FAILOVER +'/g" | sed "s/%REDIS_IP%/'+ settings.REDIS_FAILOVER +'/g" > settings.js',
    'npm update'
  ].join(' && '), null, function(err,res) {
    if(err) {
      callback(err);
      return;
    }
    this.restartServer(callback);
  }.bind(this));
}
exports.Container = CzagendaApi<|endoftext|>