<commit_before>/**
 * Created by long on 14-2-14.
 */

var flax = flax || {};

flax.FrameData = cc.Class.extend({
    x:0,
    y:0,
    rotation:0,
    scaleX:1,
    scaleY:1,
    opacity:255,
    zIndex:-1,
    skewX:0,
    skewY:0,
    _data:null,
    _hasSkew:false,

    ctor:function(data){
        this._data = data;
        this.x = parseFloat(data[0]);
        this.y = parseFloat(data[1]);
        this.rotation = parseFloat(data[2]);
        this.scaleX = parseFloat(data[3]);
        this.scaleY = parseFloat(data[4]);
        this.opacity = Math.round(255*parseFloat(data[5]));
        if(data.length > 6) this.zIndex = parseInt(data[6]);
        if(data.length > 7) this.skewX = parseFloat(data[7]);
        if(data.length > 8) this.skewY = parseFloat(data[8]);
        this._hasSkew = (data.length > 7);
    },
    setForNode:function(child, offsetX, offsetY)
    {
        var x = this.x + offsetX;
        var y = this.y + offsetY;

        if(x != child.x) child.x = x;
        if(y != child.y) child.y = y;

        if(!this._hasSkew && this.rotation != child.rotation) child.rotation = this.rotation;
        if(this.scaleX != child.scaleX) child.scaleX = this.scaleX;
        if(this.scaleY != child.scaleY) child.scaleY = this.scaleY;

        if(this._hasSkew){
            child.rotationX = this.skewX;
            child.rotationY = -this.skewY;
        }

        if(child.setOpacity && this.opacity != child.opacity) child.opacity = this.opacity;
    },
    clone:function(){
        return new flax.FrameData(this._data);
    }
});

flax.FrameData_mat = cc.Class.extend({
    a:1,
    b:0,
    c:0,
    d:1,
    tx:0,
    ty:0,
    opacity:255,
    zIndex:-1,
    _data:null,

    ctor:function(data){
        this._data = data;
        this.a = parseFloat(data[0]);
        this.b = parseFloat(data[1]);
        this.c = parseFloat(data[2]);
        this.d = parseFloat(data[3]);
        this.tx = parseFloat(data[4]);
        this.ty = parseFloat(data[5]);
        this.opacity = Math.round(255*parseFloat(data[6]));
        this.zIndex = parseInt(data[7]);
    },
    setForNode:function(child, offsetX, offsetY)
    {
        this.tx += offsetX;
        this.ty += offsetY;

        ccs.TransformHelp.matrixToNode(this, child);

        this.tx -= offsetX;
        this.ty -= offsetY;

        if(child.setOpacity && this.opacity != child.opacity) child.opacity = this.opacity;
    },
    clone:function(){
        return new flax.FrameData_mat(this._data);
    }
});

flax.MovieClip = flax.FlaxSprite.extend({
    clsName:"flax.MovieClip",
    autoPlayChildren:false,//auto play children when play
    sameFpsForChildren:true,//all children use the same fps with this
    _namedChildren:null,
    _theRect:null,
    _frameDatas:null,
    __isMovieClip:true,

    replaceChild:function(childName, assetID)
    {
        var childDefine = this.define.children[childName];
        if(childDefine == null){
            cc.log("There is no child with named: "+childName +"  in MovieClip: "+this.assetID);
            return;
        }
        var child = this._namedChildren[childName];
        if(child)
        {
            child.setSource(this.assetsFile, assetID);
        }else{
            childDefine["class"] = assetID;
        }
    },
    onNewSource:function()
    {
        for(var childName in this._namedChildren){
            this._namedChildren[childName].destroy();
            delete  this[childName];
        }
        this._namedChildren = {};
        this.totalFrames = this.define.totalFrames;
        this._theRect = this._strToRect(this.define.rect);
        this.setContentSize(this._theRect.width, this._theRect.height);
        this._initFrameDatas();
    },
    _initFrameDatas:function()
    {
        this._frameDatas = {};
        for(var childName in this.define.children)
        {
            var frames = [];
            var fs = this.define.children[childName].frames;
            var i = -1;
            while(++i < fs.length){
                var fd = fs[i];
                if(fd){
                    fd = fd.split(",");
                    //mat format
                    if(fd.length == 8) frames[i] = new flax.FrameData_mat(fd);
                    //common format
                    else frames[i] = new flax.FrameData(fd);
                }
            }
            this._frameDatas[childName] = frames;
        }
    },
    onEnter:function()
    {
        this._super();
        this.setContentSize(this._theRect.width, this._theRect.height);
    },
    doRenderFrame:function(frame)
    {
        var child;
        var childDefine;
        var frameData;
        for(var childName in this.define.children)
        {
            childDefine = this.define.children[childName];
            frameData = this._frameDatas[childName][frame];
            child = this._namedChildren[childName];
            if(frameData) {
                var offsetX = 0;
                var offsetY = 0;
                if(child == null){
                    //hadle the label text
                    if(childDefine.text != null){
                        child = flax.Label.create(this.assetsFile, childDefine);
                        if(child instanceof cc.LabelTTF){
                            offsetX = childDefine.width/2;
                            offsetY = -childDefine.height/2;
                        }
                    }else{
                        child = flax.assetsManager.createDisplay(this.assetsFile, childDefine["class"], null, true);
                    }

                    child.name = childName;
                    this._namedChildren[childName] = child;
                    if(this.autoPlayChildren) {
                        this.playing ? child.gotoAndPlay(0) : child.gotoAndStop(0);
                    }
                    this[childName] = child;
                    this.onNewChild(child);
                }
                frameData.setForNode(child, offsetX, offsetY);
                //all children use the same fps with this
                if(this.sameFpsForChildren) child.fps = this.fps;
                child.visible = true;
                child.autoPlayChildren = this.autoPlayChildren;
                if(this.autoPlayChildren) {
                    this.playing ? child.play() : child.stop();
                }
                //To fix the zIndex bug when use the old version tool
                var zIndex = (frameData.zIndex == -1) ? childDefine.zIndex : frameData.zIndex;
                if(child.parent != this){
                    child.removeFromParent(false);
                    this.addChild(child, zIndex);
                }else if(child.zIndex != zIndex){
                    child.zIndex = zIndex;
                }
            }else if(child) {
                if(child.destroy) child.destroy();
                else child.removeFromParent(true);
                delete this._namedChildren[childName];
            }
        }
    },
    stop:function()
    {
        this._super();
        if(this.autoPlayChildren) {
            for(var key in this._namedChildren) {
                var child = this._namedChildren[key];
                if(child instanceof flax.FlaxSprite) {
                    child.stop();
                }
            }
        }
    },
    play:function()
    {
        this._super();
        if(this.autoPlayChildren) {
            for(var key in this._namedChildren) {
                var child = this._namedChildren[key];
                if(child instanceof flax.FlaxSprite) {
                    child.play();
                }
            }
        }
    },
    onNewChild:function(child)
    {

    },
    getDefine:function()
    {
        var define = flax.assetsManager.getMc(this.assetsFile, this.assetID);
        if(define == null) throw "There is no MovieClip named: " + this.assetID + " in assets: " + this.assetsFile+", make sure you are a pro user!";
        return define;
    },
    getChildOfName:function(name, nest)
    {
        if(nest === undefined) nest = true;
        var child = this._namedChildren[name];
        if(child) return child;
        if(!nest) return null;
        for(var key in this._namedChildren) {
            child = this._namedChildren[key];
            if(child.getChildOfName) {
                child = child.getChildOfName(name, nest);
                if(child) return child;
            }
        }
    },
    getChildByAssetID:function(id)
    {
        var child = null;
        for(var key in this._namedChildren) {
            child = this._namedChildren[key];
            if(child.assetID == id){
                return child;
            }
        }
        return null;
    },
    getLabelText:function(labelName, ifNest)
    {
        var label = this.getChildOfName(labelName, ifNest === undefined ? true : ifNest);
        if(label && (label instanceof flax.Label)) return label.getString();
        return null;
    },
    setLabelText:function(labelName, text, ifNest)
    {
        var label = this.getChildOfName(labelName, ifNest === undefined ? true : ifNest);
        if(label && (label instanceof flax.Label)) {
            label.setString(text);
            return label;
        }
        return null;
    },
    addChildrenPhysics:function(name, type, density, friction,restitution, isSensor, fixedRotation, catBits, maskBits, bullet){
        var child = null;
        for(var key in this._namedChildren) {
            child = this._namedChildren[key];
            child.addPhysics(name, type, density, friction, restitution, isSensor, fixedRotation, catBits, maskBits, bullet);
        }
    },
    removeChildrenPhysics:function(name){
        var child = null;
        for(var key in this._namedChildren) {
            child = this._namedChildren[key];
            child.removePhysics(name);
        }
    },
    setFPS:function(f)
    {
        if(this._fps == f)  return;
        this._fps = f;
        this.updateSchedule();
        if(!this.sameFpsForChildren) return;
        var child = null;
        for(var key in this._namedChildren) {
            child = this._namedChildren[key];
            child.fps = this._fps;
        }
    },
    onRecycle:function()
    {
        this._super();
        this.autoPlayChildren = false;
        for(var key in this._namedChildren) {
            var child = this._namedChildren[key];
            if(child instanceof flax.FlaxSprite) {
                child.gotoAndStop(0);
            }
        }

    },
    _strToRect:function(str)
    {
        var arr = str.split(",");
        return cc.rect(parseFloat(arr[0]), parseFloat(arr[1]), parseFloat(arr[2]), parseFloat(arr[3]));
    }
});
flax.MovieClip.create = function(assetsFile, assetID)
{
    var mc = new flax.MovieClip(assetsFile, assetID);
    mc.clsName = "flax.MovieClip";
    return mc;
};<commit_msg>Removed the - sign of the skewY<commit_after>/**
 * Created by long on 14-2-14.
 */

var flax = flax || {};

flax.FrameData = cc.Class.extend({
    x:0,
    y:0,
    rotation:0,
    scaleX:1,
    scaleY:1,
    opacity:255,
    zIndex:-1,
    skewX:0,
    skewY:0,
    _data:null,
    _hasSkew:false,

    ctor:function(data){
        this._data = data;
        this.x = parseFloat(data[0]);
        this.y = parseFloat(data[1]);
        this.rotation = parseFloat(data[2]);
        this.scaleX = parseFloat(data[3]);
        this.scaleY = parseFloat(data[4]);
        this.opacity = Math.round(255*parseFloat(data[5]));
        if(data.length > 6) this.zIndex = parseInt(data[6]);
        if(data.length > 7) this.skewX = parseFloat(data[7]);
        if(data.length > 8) this.skewY = parseFloat(data[8]);
        this._hasSkew = (data.length > 7);
    },
    setForNode:function(child, offsetX, offsetY)
    {
        var x = this.x + offsetX;
        var y = this.y + offsetY;

        if(x != child.x) child.x = x;
        if(y != child.y) child.y = y;

        if(!this._hasSkew && this.rotation != child.rotation) child.rotation = this.rotation;
        if(this.scaleX != child.scaleX) child.scaleX = this.scaleX;
        if(this.scaleY != child.scaleY) child.scaleY = this.scaleY;

        if(this._hasSkew){
            child.rotationX = this.skewX;
            child.rotationY = this.skewY;
        }

        if(child.setOpacity && this.opacity != child.opacity) child.opacity = this.opacity;
    },
    clone:function(){
        return new flax.FrameData(this._data);
    }
});

flax.FrameData_mat = cc.Class.extend({
    a:1,
    b:0,
    c:0,
    d:1,
    tx:0,
    ty:0,
    opacity:255,
    zIndex:-1,
    _data:null,

    ctor:function(data){
        this._data = data;
        this.a = parseFloat(data[0]);
        this.b = parseFloat(data[1]);
        this.c = parseFloat(data[2]);
        this.d = parseFloat(data[3]);
        this.tx = parseFloat(data[4]);
        this.ty = parseFloat(data[5]);
        this.opacity = Math.round(255*parseFloat(data[6]));
        this.zIndex = parseInt(data[7]);
    },
    setForNode:function(child, offsetX, offsetY)
    {
        this.tx += offsetX;
        this.ty += offsetY;

        ccs.TransformHelp.matrixToNode(this, child);

        this.tx -= offsetX;
        this.ty -= offsetY;

        if(child.setOpacity && this.opacity != child.opacity) child.opacity = this.opacity;
    },
    clone:function(){
        return new flax.FrameData_mat(this._data);
    }
});

flax.MovieClip = flax.FlaxSprite.extend({
    clsName:"flax.MovieClip",
    autoPlayChildren:false,//auto play children when play
    sameFpsForChildren:true,//all children use the same fps with this
    _namedChildren:null,
    _theRect:null,
    _frameDatas:null,
    __isMovieClip:true,

    replaceChild:function(childName, assetID)
    {
        var childDefine = this.define.children[childName];
        if(childDefine == null){
            cc.log("There is no child with named: "+childName +"  in MovieClip: "+this.assetID);
            return;
        }
        var child = this._namedChildren[childName];
        if(child)
        {
            child.setSource(this.assetsFile, assetID);
        }else{
            childDefine["class"] = assetID;
        }
    },
    onNewSource:function()
    {
        for(var childName in this._namedChildren){
            this._namedChildren[childName].destroy();
            delete  this[childName];
        }
        this._namedChildren = {};
        this.totalFrames = this.define.totalFrames;
        this._theRect = this._strToRect(this.define.rect);
        this.setContentSize(this._theRect.width, this._theRect.height);
        this._initFrameDatas();
    },
    _initFrameDatas:function()
    {
        this._frameDatas = {};
        for(var childName in this.define.children)
        {
            var frames = [];
            var fs = this.define.children[childName].frames;
            var i = -1;
            while(++i < fs.length){
                var fd = fs[i];
                if(fd){
                    fd = fd.split(",");
                    //mat format
                    if(fd.length == 8) frames[i] = new flax.FrameData_mat(fd);
                    //common format
                    else frames[i] = new flax.FrameData(fd);
                }
            }
            this._frameDatas[childName] = frames;
        }
    },
    onEnter:function()
    {
        this._super();
        this.setContentSize(this._theRect.width, this._theRect.height);
    },
    doRenderFrame:function(frame)
    {
        var child;
        var childDefine;
        var frameData;
        for(var childName in this.define.children)
        {
            childDefine = this.define.children[childName];
            frameData = this._frameDatas[childName][frame];
            child = this._namedChildren[childName];
            if(frameData) {
                var offsetX = 0;
                var offsetY = 0;
                if(child == null){
                    //hadle the label text
                    if(childDefine.text != null){
                        child = flax.Label.create(this.assetsFile, childDefine);
                        if(child instanceof cc.LabelTTF){
                            offsetX = childDefine.width/2;
                            offsetY = -childDefine.height/2;
                        }
                    }else{
                        child = flax.assetsManager.createDisplay(this.assetsFile, childDefine["class"], null, true);
                    }

                    child.name = childName;
                    this._namedChildren[childName] = child;
                    if(this.autoPlayChildren) {
                        this.playing ? child.gotoAndPlay(0) : child.gotoAndStop(0);
                    }
                    this[childName] = child;
                    this.onNewChild(child);
                }
                frameData.setForNode(child, offsetX, offsetY);
                //all children use the same fps with this
                if(this.sameFpsForChildren) child.fps = this.fps;
                child.visible = true;
                child.autoPlayChildren = this.autoPlayChildren;
                if(this.autoPlayChildren) {
                    this.playing ? child.play() : child.stop();
                }
                //To fix the zIndex bug when use the old version tool
                var zIndex = (frameData.zIndex == -1) ? childDefine.zIndex : frameData.zIndex;
                if(child.parent != this){
                    child.removeFromParent(false);
                    this.addChild(child, zIndex);
                }else if(child.zIndex != zIndex){
                    child.zIndex = zIndex;
                }
            }else if(child) {
                if(child.destroy) child.destroy();
                else child.removeFromParent(true);
                delete this._namedChildren[childName];
            }
        }
    },
    stop:function()
    {
        this._super();
        if(this.autoPlayChildren) {
            for(var key in this._namedChildren) {
                var child = this._namedChildren[key];
                if(child instanceof flax.FlaxSprite) {
                    child.stop();
                }
            }
        }
    },
    play:function()
    {
        this._super();
        if(this.autoPlayChildren) {
            for(var key in this._namedChildren) {
                var child = this._namedChildren[key];
                if(child instanceof flax.FlaxSprite) {
                    child.play();
                }
            }
        }
    },
    onNewChild:function(child)
    {

    },
    getDefine:function()
    {
        var define = flax.assetsManager.getMc(this.assetsFile, this.assetID);
        if(define == null) throw "There is no MovieClip named: " + this.assetID + " in assets: " + this.assetsFile+", make sure you are a pro user!";
        return define;
    },
    getChildOfName:function(name, nest)
    {
        if(nest === undefined) nest = true;
        var child = this._namedChildren[name];
        if(child) return child;
        if(!nest) return null;
        for(var key in this._namedChildren) {
            child = this._namedChildren[key];
            if(child.getChildOfName) {
                child = child.getChildOfName(name, nest);
                if(child) return child;
            }
        }
    },
    getChildByAssetID:function(id)
    {
        var child = null;
        for(var key in this._namedChildren) {
            child = this._namedChildren[key];
            if(child.assetID == id){
                return child;
            }
        }
        return null;
    },
    getLabelText:function(labelName, ifNest)
    {
        var label = this.getChildOfName(labelName, ifNest === undefined ? true : ifNest);
        if(label && (label instanceof flax.Label)) return label.getString();
        return null;
    },
    setLabelText:function(labelName, text, ifNest)
    {
        var label = this.getChildOfName(labelName, ifNest === undefined ? true : ifNest);
        if(label && (label instanceof flax.Label)) {
            label.setString(text);
            return label;
        }
        return null;
    },
    addChildrenPhysics:function(name, type, density, friction,restitution, isSensor, fixedRotation, catBits, maskBits, bullet){
        var child = null;
        for(var key in this._namedChildren) {
            child = this._namedChildren[key];
            child.addPhysics(name, type, density, friction, restitution, isSensor, fixedRotation, catBits, maskBits, bullet);
        }
    },
    removeChildrenPhysics:function(name){
        var child = null;
        for(var key in this._namedChildren) {
            child = this._namedChildren[key];
            child.removePhysics(name);
        }
    },
    setFPS:function(f)
    {
        if(this._fps == f)  return;
        this._fps = f;
        this.updateSchedule();
        if(!this.sameFpsForChildren) return;
        var child = null;
        for(var key in this._namedChildren) {
            child = this._namedChildren[key];
            child.fps = this._fps;
        }
    },
    onRecycle:function()
    {
        this._super();
        this.autoPlayChildren = false;
        for(var key in this._namedChildren) {
            var child = this._namedChildren[key];
            if(child instanceof flax.FlaxSprite) {
                child.gotoAndStop(0);
            }
        }

    },
    _strToRect:function(str)
    {
        var arr = str.split(",");
        return cc.rect(parseFloat(arr[0]), parseFloat(arr[1]), parseFloat(arr[2]), parseFloat(arr[3]));
    }
});
flax.MovieClip.create = function(assetsFile, assetID)
{
    var mc = new flax.MovieClip(assetsFile, assetID);
    mc.clsName = "flax.MovieClip";
    return mc;
};<|endoftext|>


<commit_before>l = console.log;

function toNum(c) {
    switch(c) {
        case 'J':
            return 11;
            break;
        case 'Q':
            return 12;
            break;
        case 'K':
            return 13;
            break;
        case 'A':
            return 14;
            break;

        default:
            return card
    }
}

function compute_avg_stack(players) {
    var sum = 0;
    for (var i in players) {
        sum += players[i].stack;
    }
    return sum / players.length;
}

function compute_chip_factor(g) {
    var average_stack = compute_avg_stack(g.players);
    var myself = g.players[g.in_action];

    var strength = (myself.stack > average_stack) ? (myself.stack / average_stack) : 0.5;

    if (g.current_buy_in < g.pot) {
        return strength;
    }
    else {
        return strength * g.pot / g.current_buy_in;
    }
}

function lameCards(cards) {
    // return TRUE if the cards are LAME
    if (
        toNum(cards[0].rank) < 9 &&
        toNum(cards[1].rank) < 9 &&
        cards[0].rank != cards[1].rank
       ) {
        return true
    } else {
        return false
    }
}

module.exports = {

    VERSION: "Jofogas's Zsozsobot v4",

  bet_request: function(g) {
    l("----", VERSION);
    l(new Date());
    var myself = g.players[g.in_action];
    var call = g.current_buy_in - myself["bet"];
    var min_raise = call + g.minimum_raise;

    // just in case!!!
    if (myself.status != "active") {
        return "OK";
    }

    // don't bet before flop if our hand is crap
    if (g.community_cards.length < 1) {
        // we're before flop
        if (lameCards(myself.hole_cards)) {
            // fold
            return 0;
        } else {
            // call
            return call;
        }
    }

    if (myself.hole_cards[0].rank == myself.hole_cards[1].rank) {
        l("Go all in");
        return myself.stack;
    }
    var average_stack = compute_avg_stack(g.players);
    l("Average stack is: ", average_stack);
    l("My stack is : ", myself.stack);
    l("chip_factor returns: ", compute_chip_factor(g));

    if (myself.stack > average_stack * 0.7) {
        /* brave */
        var bet = min_raise * 2;
        l("fearlessly raising: ", bet);
        return bet;
    }
    else {
        /* tight */
        l("fearfully not raising: ", 0);
        return 0;
    }
  },

    showdown: function(g) {
        return 'what is this for?';
    }
};
<commit_msg>Logging for pre-flop logic<commit_after>l = console.log;

function toNum(c) {
    switch(c) {
        case 'J':
            return 11;
            break;
        case 'Q':
            return 12;
            break;
        case 'K':
            return 13;
            break;
        case 'A':
            return 14;
            break;

        default:
            return card
    }
}

function compute_avg_stack(players) {
    var sum = 0;
    for (var i in players) {
        sum += players[i].stack;
    }
    return sum / players.length;
}

function compute_chip_factor(g) {
    var average_stack = compute_avg_stack(g.players);
    var myself = g.players[g.in_action];

    var strength = (myself.stack > average_stack) ? (myself.stack / average_stack) : 0.5;

    if (g.current_buy_in < g.pot) {
        return strength;
    }
    else {
        return strength * g.pot / g.current_buy_in;
    }
}

function lameCards(cards) {
    // return TRUE if the cards are LAME
    l(
        "my cards: ",
        cards[0].rank,
        cards[0].suit,
        " ",
        cards[1].rank,
        cards[1].suit
     )

    if (
        toNum(cards[0].rank) < 9 &&
        toNum(cards[1].rank) < 9 &&
        cards[0].rank != cards[1].rank
       ) {
        return true
    } else {
        return false
    }
}

module.exports = {

    VERSION: "Jofogas's Zsozsobot v4",

  bet_request: function(g) {
    l("----", VERSION);
    l(new Date());
    var myself = g.players[g.in_action];
    var call = g.current_buy_in - myself["bet"];
    var min_raise = call + g.minimum_raise;

    // just in case!!!
    if (myself.status != "active") {
        return "OK";
    }

    // don't bet before flop if our hand is crap
    if (g.community_cards.length < 1) {
        // we're before flop
        if (lameCards(myself.hole_cards)) {
            l("folding because cards too lame");
            return 0;
        } else {
            l("calling because cards seem OK");
            return call;
        }
    }

    if (myself.hole_cards[0].rank == myself.hole_cards[1].rank) {
        l("Go all in");
        return myself.stack;
    }
    var average_stack = compute_avg_stack(g.players);
    l("Average stack is: ", average_stack);
    l("My stack is : ", myself.stack);
    l("chip_factor returns: ", compute_chip_factor(g));

    if (myself.stack > average_stack * 0.7) {
        /* brave */
        var bet = min_raise * 2;
        l("fearlessly raising: ", bet);
        return bet;
    }
    else {
        /* tight */
        l("fearfully not raising: ", 0);
        return 0;
    }
  },

    showdown: function(g) {
        return 'what is this for?';
    }
};
<|endoftext|>


<commit_before>module.exports = '2018-01-05';
<commit_msg>bump version<commit_after>module.exports = '2018-01-12';
<|endoftext|>


<commit_before>'use strict';

// external deps
var ObjectId = require('mongodb').ObjectId;

// internal deps
require('mongodb-toolkit');
var BateeqModels = require('bateeq-models');
var map = BateeqModels.map;
var generateCode = require('../../utils/code-generator');

var TransferInDoc = BateeqModels.inventory.TransferInDoc;
var TransferInItem = BateeqModels.inventory.TransferInItem;

const moduleId = "EFR-TB/BAT";

module.exports = class TokoTerimaAksesorisManager {
    constructor(db, user) {
        this.db = db;
        this.user = user;
        this.transferInDocCollection = this.db.use(map.inventory.TransferInDoc);
        this.spkDocCollection = this.db.use(map.merchandiser.SPKDoc);

        var StorageManager = require('../master/storage-manager');
        this.storageManager = new StorageManager(db, user);

        var ItemManager = require('../master/item-manager');
        this.itemManager = new ItemManager(db, user);

        var InventoryManager = require('./inventory-manager');
        this.inventoryManager = new InventoryManager(db, user);

        var TransferInDocManager = require('./transfer-in-doc-manager');
        this.transferInDocManager = new TransferInDocManager(db, user);

        var ModuleManager = require('../master/module-manager');
        this.moduleManager = new ModuleManager(db, user);

        var SPKManager = require('../merchandiser/efr-pk-manager');
        this.spkManager = new SPKManager(db, user);
    }

    read(paging) {
        var _paging = Object.assign({
            page: 1,
            size: 20,
            order: '_id',
            asc: true
        }, paging);

        return new Promise((resolve, reject) => {
            // var batRegex = { 'code': {
            //             '$regex': new RegExp("^[0-9]+\/[A-Z\-]+\/BAT\/[0-9]{2}\/[0-9]{4}$","i")}};

            var deleted = {
                _deleted: false,
                code: {
                    '$regex': new RegExp("^[A-Z0-9]+\/" + moduleId + "\/[0-9]{2}\/[0-9]{4}$", "i")
                }
            };
            var query = _paging.keyword ? {
                '$and': [deleted]
            } : deleted;

            if (_paging.keyword) {
                var regex = new RegExp(_paging.keyword, "i");
                var filterCode = {
                    'code': {
                        '$regex': regex
                    }
                };
                var $or = {
                    '$or': [filterCode]
                };
                query['$and'].push($or);
            }

            this.transferInDocCollection
                .where(query)
                .page(_paging.page, _paging.size)
                .orderBy(_paging.order, _paging.asc)
                .execute()
                .then(transferInDocs => {
                    resolve(transferInDocs);
                })
                .catch(e => {
                    reject(e);
                });
        });
    }

    readPendingSPK(paging) {
        var _paging = Object.assign({
            page: 1,
            size: 20,
            order: '_id',
            asc: true
        }, paging);

        return new Promise((resolve, reject) => {
            var deleted = {
                _deleted: false
            };

            var regex = new RegExp("EFR\-PK/\PBA", "i");
            var filterCode = {
                'code': {
                    '$regex': regex
                },
                'expeditionDocumentId': { "$ne": {} }
            };

            var isReceived = {
                isReceived: false
            };

            var query = {
                $and: [
                    deleted,
                    filterCode,
                    isReceived
                ]
            }

            this.spkDocCollection
                .where(query)
                .page(_paging.page, _paging.size)
                .orderBy(_paging.order, _paging.asc)
                .execute()
                .then(spkDocs => {
                    resolve(spkDocs);
                })
                .catch(e => {
                    reject(e);
                });
        });
    }

    getSingleById(id) {
        return new Promise((resolve, reject) => {
            var query = {
                _id: new ObjectId(id),
                _deleted: false
            };
            this.getSingleByQuery(query)
                .then(transferInDoc => {
                    resolve(transferInDoc);
                })
                .catch(e => {
                    reject(e);
                });
        });
    }

    getSingleByIdOrDefault(id) {
        return new Promise((resolve, reject) => {
            var query = {
                _id: new ObjectId(id),
                _deleted: false
            };
            this.getSingleByQueryOrDefault(query)
                .then(transferInDoc => {
                    resolve(transferInDoc);
                })
                .catch(e => {
                    reject(e);
                });
        });
    }

    getSingleByQuery(query) {
        return new Promise((resolve, reject) => {
            this.transferInDocCollection
                .single(query)
                .then(transferInDoc => {
                    resolve(transferInDoc);
                })
                .catch(e => {
                    reject(e);
                });
        })
    }

    getSingleByQueryOrDefault(query) {
        return new Promise((resolve, reject) => {
            this.transferInDocCollection
                .singleOrDefault(query)
                .then(transferInDoc => {
                    resolve(transferInDoc);
                })
                .catch(e => {
                    reject(e);
                });
        })
    }

    getPendingSPKById(id) {
        return new Promise((resolve, reject) => {
            var query = {
                _id: new ObjectId(id),
                _deleted: false,
                isReceived: false
            };
            this.spkDocCollection.singleOrDefault(query)
                .then(SPKDoc => {
                    SPKDoc.password = '';
                    SPKDoc._id = undefined;
                    resolve(SPKDoc);
                })
                .catch(e => {
                    reject(e);
                });
        });
    }

    create(transferInDoc) {
        return new Promise((resolve, reject) => {
            this._validate(transferInDoc)
                .then(validTransferInDoc => {
                    validTransferInDoc.code = generateCode(moduleId)
                    this.transferInDocManager.create(validTransferInDoc)
                        .then(id => {
                            var reference = transferInDoc.reference;
                            this.spkManager.updateReceivedByRef(reference)
                                .then(result => {
                                    resolve(id);
                                }).catch(e => {
                                    reject(e);
                                })
                        })
                        .catch(e => {
                            reject(e);
                        })
                })
                .catch(e => {
                    reject(e);
                })
        });
    }

    update(transferInDoc) {
        return new Promise((resolve, reject) => {
            this._validate(transferInDoc)
                .then(validTransferInDoc => {
                    this.transferInDocManager.update(validTransferInDoc)
                        .then(id => {
                            resolve(id);
                        })
                        .catch(e => {
                            reject(e);
                        })
                })
                .catch(e => {
                    reject(e);
                })
        });
    }

    delete(transferInDoc) {
        return new Promise((resolve, reject) => {
            this._validate(transferInDoc)
                .then(validTransferInDoc => {
                    validTransferInDoc._deleted = true;
                    this.transferInDocManager.update(validTransferInDoc)
                        .then(id => {
                            resolve(id);
                        })
                        .catch(e => {
                            reject(e);
                        })
                })
                .catch(e => {
                    reject(e);
                })
        });
    }

    _validate(transferInDoc) {
        var errors = {};
        return new Promise((resolve, reject) => {
            this.spkManager.getByReference(transferInDoc.reference).
                then(spkDoc => {
                    if (spkDoc) {
                        if (transferInDoc.password != spkDoc.password) {
                            errors["password"] = "invalid password";
                        }
                        if (transferInDoc.reference == "") {
                            errors["reference"] = "reference is required";
                        }
                        if (transferInDoc.items.length <= 0) {
                            errors["items"] = "no item(s) to transfer in";
                        }
                        if (spkDoc.sourceId.toString() != transferInDoc.sourceId.toString()) {
                            errors["sourceId"] = "invalid sourceId";
                        }
                        if (spkDoc.destinationId.toString() != transferInDoc.destinationId.toString()) {
                            errors["destinationId"] = "invalid destinationId";
                        }
                        if (spkDoc.isReceived) {
                            errors["isReceived"] = "this reference already received";
                        }
                        var index = 0;
                        var itemErrors = [];
                        for (var item of transferInDoc.items) {
                            var itemError = {};
                            if (item.quantity <= 0)
                                itemError["quantity"] = "items should not contains 0 quantity";
                            else
                                if (item.quantity != spkDoc.items[index].quantity)
                                    if (item.remark == "")
                                        itemError["remark"] = "Masukkan no referensi berita acara";
                            index++;
                            itemErrors.push(itemError);
                        }
                        for (var itemError of itemErrors) {
                            for (var prop in itemError) {
                                errors.items = itemErrors;
                                break;
                            }
                            if (errors.items)
                                break;
                        }
                        for (var prop in errors) {
                            var ValidationError = require('../../validation-error');
                            reject(new ValidationError('data does not pass validation', errors));
                        }
                    }
                    else {
                        errors["reference"] = "reference not found";
                        var ValidationError = require('../../validation-error');
                        reject(new ValidationError('data does not pass validation', errors));
                    }
                    resolve(transferInDoc);
                })
                .catch(e => {
                    reject(e);
                })
        });
    }
};<commit_msg>comment validation expeditionDocumentId in efr-bat-manager<commit_after>'use strict';

// external deps
var ObjectId = require('mongodb').ObjectId;

// internal deps
require('mongodb-toolkit');
var BateeqModels = require('bateeq-models');
var map = BateeqModels.map;
var generateCode = require('../../utils/code-generator');

var TransferInDoc = BateeqModels.inventory.TransferInDoc;
var TransferInItem = BateeqModels.inventory.TransferInItem;

const moduleId = "EFR-TB/BAT";

module.exports = class TokoTerimaAksesorisManager {
    constructor(db, user) {
        this.db = db;
        this.user = user;
        this.transferInDocCollection = this.db.use(map.inventory.TransferInDoc);
        this.spkDocCollection = this.db.use(map.merchandiser.SPKDoc);

        var StorageManager = require('../master/storage-manager');
        this.storageManager = new StorageManager(db, user);

        var ItemManager = require('../master/item-manager');
        this.itemManager = new ItemManager(db, user);

        var InventoryManager = require('./inventory-manager');
        this.inventoryManager = new InventoryManager(db, user);

        var TransferInDocManager = require('./transfer-in-doc-manager');
        this.transferInDocManager = new TransferInDocManager(db, user);

        var ModuleManager = require('../master/module-manager');
        this.moduleManager = new ModuleManager(db, user);

        var SPKManager = require('../merchandiser/efr-pk-manager');
        this.spkManager = new SPKManager(db, user);
    }

    read(paging) {
        var _paging = Object.assign({
            page: 1,
            size: 20,
            order: '_id',
            asc: true
        }, paging);

        return new Promise((resolve, reject) => {
            // var batRegex = { 'code': {
            //             '$regex': new RegExp("^[0-9]+\/[A-Z\-]+\/BAT\/[0-9]{2}\/[0-9]{4}$","i")}};

            var deleted = {
                _deleted: false,
                code: {
                    '$regex': new RegExp("^[A-Z0-9]+\/" + moduleId + "\/[0-9]{2}\/[0-9]{4}$", "i")
                }
            };
            var query = _paging.keyword ? {
                '$and': [deleted]
            } : deleted;

            if (_paging.keyword) {
                var regex = new RegExp(_paging.keyword, "i");
                var filterCode = {
                    'code': {
                        '$regex': regex
                    }
                };
                var $or = {
                    '$or': [filterCode]
                };
                query['$and'].push($or);
            }

            this.transferInDocCollection
                .where(query)
                .page(_paging.page, _paging.size)
                .orderBy(_paging.order, _paging.asc)
                .execute()
                .then(transferInDocs => {
                    resolve(transferInDocs);
                })
                .catch(e => {
                    reject(e);
                });
        });
    }

    readPendingSPK(paging) {
        var _paging = Object.assign({
            page: 1,
            size: 20,
            order: '_id',
            asc: true
        }, paging);

        return new Promise((resolve, reject) => {
            var deleted = {
                _deleted: false
            };

            var regex = new RegExp("EFR\-PK/\PBA", "i");
            var filterCode = {
                'code': {
                    '$regex': regex
                },
                // 'expeditionDocumentId': { "$ne": {} }
            };

            var isReceived = {
                isReceived: false
            };

            var query = {
                $and: [
                    deleted,
                    filterCode,
                    isReceived
                ]
            }

            this.spkDocCollection
                .where(query)
                .page(_paging.page, _paging.size)
                .orderBy(_paging.order, _paging.asc)
                .execute()
                .then(spkDocs => {
                    resolve(spkDocs);
                })
                .catch(e => {
                    reject(e);
                });
        });
    }

    getSingleById(id) {
        return new Promise((resolve, reject) => {
            var query = {
                _id: new ObjectId(id),
                _deleted: false
            };
            this.getSingleByQuery(query)
                .then(transferInDoc => {
                    resolve(transferInDoc);
                })
                .catch(e => {
                    reject(e);
                });
        });
    }

    getSingleByIdOrDefault(id) {
        return new Promise((resolve, reject) => {
            var query = {
                _id: new ObjectId(id),
                _deleted: false
            };
            this.getSingleByQueryOrDefault(query)
                .then(transferInDoc => {
                    resolve(transferInDoc);
                })
                .catch(e => {
                    reject(e);
                });
        });
    }

    getSingleByQuery(query) {
        return new Promise((resolve, reject) => {
            this.transferInDocCollection
                .single(query)
                .then(transferInDoc => {
                    resolve(transferInDoc);
                })
                .catch(e => {
                    reject(e);
                });
        })
    }

    getSingleByQueryOrDefault(query) {
        return new Promise((resolve, reject) => {
            this.transferInDocCollection
                .singleOrDefault(query)
                .then(transferInDoc => {
                    resolve(transferInDoc);
                })
                .catch(e => {
                    reject(e);
                });
        })
    }

    getPendingSPKById(id) {
        return new Promise((resolve, reject) => {
            var query = {
                _id: new ObjectId(id),
                _deleted: false,
                isReceived: false
            };
            this.spkDocCollection.singleOrDefault(query)
                .then(SPKDoc => {
                    SPKDoc.password = '';
                    SPKDoc._id = undefined;
                    resolve(SPKDoc);
                })
                .catch(e => {
                    reject(e);
                });
        });
    }

    create(transferInDoc) {
        return new Promise((resolve, reject) => {
            this._validate(transferInDoc)
                .then(validTransferInDoc => {
                    validTransferInDoc.code = generateCode(moduleId)
                    this.transferInDocManager.create(validTransferInDoc)
                        .then(id => {
                            var reference = transferInDoc.reference;
                            this.spkManager.updateReceivedByRef(reference)
                                .then(result => {
                                    resolve(id);
                                }).catch(e => {
                                    reject(e);
                                })
                        })
                        .catch(e => {
                            reject(e);
                        })
                })
                .catch(e => {
                    reject(e);
                })
        });
    }

    update(transferInDoc) {
        return new Promise((resolve, reject) => {
            this._validate(transferInDoc)
                .then(validTransferInDoc => {
                    this.transferInDocManager.update(validTransferInDoc)
                        .then(id => {
                            resolve(id);
                        })
                        .catch(e => {
                            reject(e);
                        })
                })
                .catch(e => {
                    reject(e);
                })
        });
    }

    delete(transferInDoc) {
        return new Promise((resolve, reject) => {
            this._validate(transferInDoc)
                .then(validTransferInDoc => {
                    validTransferInDoc._deleted = true;
                    this.transferInDocManager.update(validTransferInDoc)
                        .then(id => {
                            resolve(id);
                        })
                        .catch(e => {
                            reject(e);
                        })
                })
                .catch(e => {
                    reject(e);
                })
        });
    }

    _validate(transferInDoc) {
        var errors = {};
        return new Promise((resolve, reject) => {
            this.spkManager.getByReference(transferInDoc.reference).
                then(spkDoc => {
                    if (spkDoc) {
                        if (transferInDoc.password != spkDoc.password) {
                            errors["password"] = "invalid password";
                        }
                        if (transferInDoc.reference == "") {
                            errors["reference"] = "reference is required";
                        }
                        if (transferInDoc.items.length <= 0) {
                            errors["items"] = "no item(s) to transfer in";
                        }
                        if (spkDoc.sourceId.toString() != transferInDoc.sourceId.toString()) {
                            errors["sourceId"] = "invalid sourceId";
                        }
                        if (spkDoc.destinationId.toString() != transferInDoc.destinationId.toString()) {
                            errors["destinationId"] = "invalid destinationId";
                        }
                        if (spkDoc.isReceived) {
                            errors["isReceived"] = "this reference already received";
                        }
                        var index = 0;
                        var itemErrors = [];
                        for (var item of transferInDoc.items) {
                            var itemError = {};
                            if (item.quantity <= 0)
                                itemError["quantity"] = "items should not contains 0 quantity";
                            else
                                if (item.quantity != spkDoc.items[index].quantity)
                                    if (item.remark == "")
                                        itemError["remark"] = "Masukkan no referensi berita acara";
                            index++;
                            itemErrors.push(itemError);
                        }
                        for (var itemError of itemErrors) {
                            for (var prop in itemError) {
                                errors.items = itemErrors;
                                break;
                            }
                            if (errors.items)
                                break;
                        }
                        for (var prop in errors) {
                            var ValidationError = require('../../validation-error');
                            reject(new ValidationError('data does not pass validation', errors));
                        }
                    }
                    else {
                        errors["reference"] = "reference not found";
                        var ValidationError = require('../../validation-error');
                        reject(new ValidationError('data does not pass validation', errors));
                    }
                    resolve(transferInDoc);
                })
                .catch(e => {
                    reject(e);
                })
        });
    }
};<|endoftext|>


<commit_before>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var setTimeout = require('timers').setTimeout;
var coreAssert = require('assert');

var allocCluster = require('../lib/test-cluster.js');
var parallel = require('run-parallel');

allocCluster.test('request circuit state from endpoint', {
    size: 2,
    kValue: 1,
    remoteConfig: {
        'rateLimiting.enabled': false,
        'circuits.enabled': true,
        'partialAffinity.enabled': true
    },
    seedConfig: {
        'hyperbahn.circuits': {
            period: 10,
            maxErrorRate: 0.5,
            minRequests: 0,
            probation: 5,
            enabled: true
        }
    }
}, function t(cluster, assert) {
    cluster.logger.whitelist('warn', 'forwarding error frame');

    installServer(cluster);
    warmupAndRequests(cluster, whenTheSmokeClears);

    function whenTheSmokeClears(err) {
        if (err) {
            return assert.ifError(err);
        }

        sendRequest(cluster, false, requestCircuitsState);
    }

    function requestCircuitsState(_, err) {
        assert.equal(err.type, 'tchannel.declined');

        getCircuitState(cluster, onCircuitsResponse);
    }

    function onCircuitsResponse(err, res) {
        if (err) {
            return assert.end(err);
        }

        assert.equals(res.ok, true);
        var circuits = res.body;

        assert.ok(circuits.length >= 1, 'expected at least one circuit');

        var circuit;
        for (var i = 0; i < circuits.length; i++) {
            if (circuits[i].sn === 'bob') {
                circuit = circuits[i];
                break;
            }
        }

        assert.equals(circuit.cn, 'steve', 'caller name');
        assert.equals(circuit.sn, 'bob', 'service name');
        assert.equals(circuit.en, 'ifyousayso', 'endpoint name');
        assert.equals(circuit.healthy, false, 'unhealthy');
        assert.equals(circuit.shorted, false, 'not shorted');

        assert.end();
    }
});

function getCircuitState(cluster, onCircuitsResponse) {
    var exitNodes = cluster.getExitNodes('bob');
    var hostPort = exitNodes[0].hostPort;

    // Using bob, because steve's peer is unhealthy.
    var channel = cluster.remotes.bob.clientChannel;
    channel.waitForIdentified({
        host: hostPort
    }, function onConnect(err) {
        if (err) {
            return onCircuitsResponse(err);
        }

        var request = channel.request({
            serviceName: 'autobahn',
            timeout: 1000,
            host: hostPort,
            hasNoParent: true,
            headers: {
                as: 'json'
            }
        });
        cluster.tchannelJSON.send(
            request, 'circuits_v1', null, null, onCircuitsResponse
        );
    });
}

function warmupAndRequests(cluster, whenTheSmokeClears) {
    var count = 100;

    sendRequest(cluster, true, afterPreparation);

    function afterPreparation(err) {
        if (err) {
            return whenTheSmokeClears(err);
        }

        sendRequests();
    }

    function sendRequests() {
        var tasks = [];
        for (var i = 0; i < count; i++) {
            // 0.5 is the error rate threshold. There is some variance.
            // Test seems to pass with a success rate of 0.4, flipping the
            // circuit breaker.
            tasks.push(sendRequest.bind(null, cluster, Math.random() < 0.2));
        }

        parallel(tasks, afterBarrage);
    }

    function afterBarrage(err) {
        if (err) {
            return whenTheSmokeClears(err);
        }

        setTimeout(whenTheSmokeClears, 500);
    }
}

function sendRequest(cluster, yes, callback) {
    var request = cluster.remotes.steve.clientChannel.request({
        serviceName: 'bob',
        timeout: 1000,
        hasNoParent: true
    });

    if (yes) {
        request.send('ifyousayso', 'yes', 'Said so', callback);
    } else {
        request.send('ifyousayso', 'no', 'UnexpectedError', onErr);
    }

    // Ignore the error responses; they are expected.
    function onErr(err) {
        callback(null, err);
    }
}

function installServer(cluster) {
    cluster.remotes.bob.serverChannel.register('ifyousayso', respond);

    function respond(req, res, head, body) {
        head = head.toString();
        body = body.toString();
        res.headers.as = 'raw';

        if (head === 'no') {
            res.sendError(body, 'error');
        } else if (head === 'yes') {
            res.sendOk(body);
        } else {
            coreAssert(false, 'request should be yes or no');
        }
    }
}
<commit_msg>add test for unhealthy flipr<commit_after>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var setTimeout = require('timers').setTimeout;
var coreAssert = require('assert');

var allocCluster = require('../lib/test-cluster.js');
var parallel = require('run-parallel');

allocCluster.test('request circuit state from endpoint', {
    size: 2,
    kValue: 1,
    remoteConfig: {
        'rateLimiting.enabled': false,
        'circuits.enabled': true,
        'partialAffinity.enabled': true
    },
    seedConfig: {
        'hyperbahn.circuits': {
            period: 10,
            maxErrorRate: 0.5,
            minRequests: 0,
            probation: 5,
            enabled: true
        }
    }
}, function t(cluster, assert) {
    cluster.logger.whitelist('warn', 'forwarding error frame');

    installServer(cluster);
    warmupAndRequests(cluster, whenTheSmokeClears);

    function whenTheSmokeClears(err) {
        if (err) {
            return assert.ifError(err);
        }

        sendRequest(cluster, false, requestCircuitsState);
    }

    function requestCircuitsState(_, err) {
        assert.equal(err.type, 'tchannel.declined');

        getCircuitState(cluster, onCircuitsResponse);
    }

    function onCircuitsResponse(err, res) {
        if (err) {
            return assert.end(err);
        }

        assert.equals(res.ok, true);
        var circuits = res.body;

        assert.ok(circuits.length >= 1, 'expected at least one circuit');

        var circuit;
        for (var i = 0; i < circuits.length; i++) {
            if (circuits[i].sn === 'bob') {
                circuit = circuits[i];
                break;
            }
        }

        assert.equals(circuit.cn, 'steve', 'caller name');
        assert.equals(circuit.sn, 'bob', 'service name');
        assert.equals(circuit.en, 'ifyousayso', 'endpoint name');
        assert.equals(circuit.healthy, false, 'unhealthy');
        assert.equals(circuit.shorted, false, 'not shorted');

        assert.end();
    }
});

allocCluster.test('request circuit state from endpoint', {
    size: 2,
    kValue: 1,
    remoteConfig: {
        'rateLimiting.enabled': false,
        'circuits.enabled': true,
        'circuits.codeName': 'Unhealthy',
        'partialAffinity.enabled': true
    },
    seedConfig: {
        'hyperbahn.circuits': {
            period: 10,
            maxErrorRate: 0.5,
            minRequests: 0,
            probation: 5,
            enabled: true
        }
    }
}, function t(cluster, assert) {
    cluster.logger.whitelist('warn', 'forwarding error frame');

    installServer(cluster);
    warmupAndRequests(cluster, whenTheSmokeClears);

    function whenTheSmokeClears(err) {
        if (err) {
            return assert.ifError(err);
        }

        sendRequest(cluster, false, requestCircuitsState);
    }

    function requestCircuitsState(_, err) {
        assert.equal(err.type, 'tchannel.unhealthy');

        getCircuitState(cluster, onCircuitsResponse);
    }

    function onCircuitsResponse(err, res) {
        if (err) {
            return assert.end(err);
        }

        assert.equals(res.ok, true);
        var circuits = res.body;

        assert.ok(circuits.length >= 1, 'expected at least one circuit');

        var circuit;
        for (var i = 0; i < circuits.length; i++) {
            if (circuits[i].sn === 'bob') {
                circuit = circuits[i];
                break;
            }
        }

        assert.equals(circuit.cn, 'steve', 'caller name');
        assert.equals(circuit.sn, 'bob', 'service name');
        assert.equals(circuit.en, 'ifyousayso', 'endpoint name');
        assert.equals(circuit.healthy, false, 'unhealthy');
        assert.equals(circuit.shorted, false, 'not shorted');

        assert.end();
    }
});

function getCircuitState(cluster, onCircuitsResponse) {
    var exitNodes = cluster.getExitNodes('bob');
    var hostPort = exitNodes[0].hostPort;

    // Using bob, because steve's peer is unhealthy.
    var channel = cluster.remotes.bob.clientChannel;
    channel.waitForIdentified({
        host: hostPort
    }, function onConnect(err) {
        if (err) {
            return onCircuitsResponse(err);
        }

        var request = channel.request({
            serviceName: 'autobahn',
            timeout: 1000,
            host: hostPort,
            hasNoParent: true,
            headers: {
                as: 'json'
            }
        });
        cluster.tchannelJSON.send(
            request, 'circuits_v1', null, null, onCircuitsResponse
        );
    });
}

function warmupAndRequests(cluster, whenTheSmokeClears) {
    var count = 100;

    sendRequest(cluster, true, afterPreparation);

    function afterPreparation(err) {
        if (err) {
            return whenTheSmokeClears(err);
        }

        sendRequests();
    }

    function sendRequests() {
        var tasks = [];
        for (var i = 0; i < count; i++) {
            // 0.5 is the error rate threshold. There is some variance.
            // Test seems to pass with a success rate of 0.4, flipping the
            // circuit breaker.
            tasks.push(sendRequest.bind(null, cluster, Math.random() < 0.2));
        }

        parallel(tasks, afterBarrage);
    }

    function afterBarrage(err) {
        if (err) {
            return whenTheSmokeClears(err);
        }

        setTimeout(whenTheSmokeClears, 500);
    }
}

function sendRequest(cluster, yes, callback) {
    var request = cluster.remotes.steve.clientChannel.request({
        serviceName: 'bob',
        timeout: 1000,
        hasNoParent: true
    });

    if (yes) {
        request.send('ifyousayso', 'yes', 'Said so', callback);
    } else {
        request.send('ifyousayso', 'no', 'UnexpectedError', onErr);
    }

    // Ignore the error responses; they are expected.
    function onErr(err) {
        callback(null, err);
    }
}

function installServer(cluster) {
    cluster.remotes.bob.serverChannel.register('ifyousayso', respond);

    function respond(req, res, head, body) {
        head = head.toString();
        body = body.toString();
        res.headers.as = 'raw';

        if (head === 'no') {
            res.sendError(body, 'error');
        } else if (head === 'yes') {
            res.sendOk(body);
        } else {
            coreAssert(false, 'request should be yes or no');
        }
    }
}
<|endoftext|>


<commit_before>/*! uppie | (c) 2015 silverwind | BSD license */
/* eslint-disable strict */

self.Uppie = function (opts) {
  return function (node, cb) {
    node.addEventListener("change", function (event) {
      if (!event.target.files || !event.target.files.length) return;
      if ("getFilesAndDirectories" in event.target) {
        newDirectoryApi(event, opts, cb);
      } else if ("webkitRelativePath" in event.target.files[0]) {
        oldDirectoryApi(event, opts, cb);
      } else {
        multipleApi(event, cb);
      }
    });
  };
};

// API implemented in Firefox 42+ and Edge
function newDirectoryApi(event, opts, cb) {
  var fd = new FormData(), files = [];
  var iterate = function (entries, path, resolve) {
    var promises = [];
    [].slice.call(entries).forEach(function (entry) {
      var promise = new Promise(function (resolve) {
        if ("getFilesAndDirectories" in entry) { // it's a directory
          entry.getFilesAndDirectories().then(function (entries) {
            if (opts.includeEmptyDirectories && !entries.length) {
              fd.append(entry.name + "/", new Blob(), path + entry.name + "/");
              files.push(path + entry.name + "/");
            }
            iterate(entries, entry.path + entry.name + "/", resolve);
          });
        } else { // it's a file
          if (entry.name) {
            fd.append(entry.name, entry, path + entry.name);
            files.push(path + entry.name);
          }
          resolve();
        }
      });
      promises.push(promise);
    });
    Promise.all(promises).then(resolve.bind());
  };
  event.target.getFilesAndDirectories().then(function (entries) {
    new Promise(function (resolve) {
      iterate(entries, "/", resolve);
    }).then(cb.bind(null, fd, files));
  });
}

// Old prefixed API implemented in Chrome
function oldDirectoryApi(event, opts, cb) {
  var fd = new FormData(), files = [];
  [].slice.call(event.target.files).forEach(function (file) {
    var path = file.webkitRelativePath + "/" + file.name;
    fd.append(file.name, file, path);
    files.push(path);
  });
  cb(fd, files);
}

// Fallback for just multiple files without directories
function multipleApi(event, cb) {
  var fd = new FormData(), files = [];
  [].slice.call(event.target.files).forEach(function (file) {
    fd.append(file.name, file, file.name);
    files.push(file.name);
  });
  cb(fd, files);
}
<commit_msg>no need to slice the array on the new API<commit_after>/*! uppie | (c) 2015 silverwind | BSD license */
/* eslint-disable strict */

self.Uppie = function (opts) {
  return function (node, cb) {
    node.addEventListener("change", function (event) {
      if (!event.target.files || !event.target.files.length) return;
      if ("getFilesAndDirectories" in event.target) {
        newDirectoryApi(event, opts, cb);
      } else if ("webkitRelativePath" in event.target.files[0]) {
        oldDirectoryApi(event, opts, cb);
      } else {
        multipleApi(event, cb);
      }
    });
  };
};

// API implemented in Firefox 42+ and Edge
function newDirectoryApi(event, opts, cb) {
  var fd = new FormData(), files = [];
  var iterate = function (entries, path, resolve) {
    var promises = [];
    entries.forEach(function (entry) {
      var promise = new Promise(function (resolve) {
        if ("getFilesAndDirectories" in entry) { // it's a directory
          entry.getFilesAndDirectories().then(function (entries) {
            if (opts.includeEmptyDirectories && !entries.length) {
              fd.append(entry.name + "/", new Blob(), path + entry.name + "/");
              files.push(path + entry.name + "/");
            }
            iterate(entries, entry.path + entry.name + "/", resolve);
          });
        } else { // it's a file
          if (entry.name) {
            fd.append(entry.name, entry, path + entry.name);
            files.push(path + entry.name);
          }
          resolve();
        }
      });
      promises.push(promise);
    });
    Promise.all(promises).then(resolve.bind());
  };
  event.target.getFilesAndDirectories().then(function (entries) {
    new Promise(function (resolve) {
      iterate(entries, "/", resolve);
    }).then(cb.bind(null, fd, files));
  });
}

// Old prefixed API implemented in Chrome
function oldDirectoryApi(event, opts, cb) {
  var fd = new FormData(), files = [];
  [].slice.call(event.target.files).forEach(function (file) {
    var path = file.webkitRelativePath + "/" + file.name;
    fd.append(file.name, file, path);
    files.push(path);
  });
  cb(fd, files);
}

// Fallback for just multiple files without directories
function multipleApi(event, cb) {
  var fd = new FormData(), files = [];
  [].slice.call(event.target.files).forEach(function (file) {
    fd.append(file.name, file, file.name);
    files.push(file.name);
  });
  cb(fd, files);
}
<|endoftext|>


<commit_before>/* global fetch */

import React from "react-native";
import FileUpload from "../../modules/file-upload";
import controller from "./controller";
import generate from "../../lib/generate.browser";

const IDLE = "idle";
const LOADING = "loading";
const FINISHED = "finished";
const ERROR = "error";

@controller
export default class ImageUploadController extends React.Component {
	constructor(props) {
		super(props);

		this.state = {
			status: IDLE,
			uploadId: null
		};
	}

	componentWillMount() {
		if (this.props.autoStart) {
			this._startUpload();
		}
	}

	componentWillUnmount() {
		this._closeUpload();
	}

	_pollThumbnail(opts) {
		return new Promise((resolve, reject) => {
			const startTime = Date.now();

			let thumbTimer;

			const checkThumb = () => {
				if (thumbTimer) {
					clearTimeout(thumbTimer);
				}

				fetch(opts.thumbnailUrl)
					.then(() => resolve(opts))
					.catch(() => {
						if (Date.now() - startTime > 30000) {
							reject(new Error("Thumbnail generation timed out!"));
						} else {
							thumbTimer = setTimeout(checkThumb, 1500);
						}
					});
			};

			setTimeout(checkThumb, 3000);
		});
	}

	_startUpload() {
		if (this.state.status !== IDLE && this.state.status !== ERROR) {
			return;
		}

		this.setState({
			status: LOADING
		});

		if (this.props.onUploadStart) {
			this.props.onUploadStart();
		}

		const textId = generate.uid();

		this.query("upload/getPolicy", {
			uploadType: this.props.uploadType,
			userId: this.store.get("user"),
			textId
		})
		.then(res => {
			const policy = res.response;

			const formData = {};
			const fields = [
				"acl", "policy", "x-amz-algorithm", "x-amz-credential",
				"x-amz-date", "x-amz-signature"
			];

			for (let i = 0, l = fields.length; i < l; i++) {
				formData[fields[i]] = policy[fields[i]];
			}

			const baseurl = "https://" + policy.bucket + ".s3.amazonaws.com/";
			const filename = this.props.imageData.name.replace(/\s+/g, " ");

			let key = policy.keyPrefix,
				url, thumbpath;

			switch (this.props.uploadType) {
			case "avatar":
			case "banner":
				thumbpath = "256x256.jpg";
				key += "original." + filename.split(".").pop();
				url = baseurl + key;
				break;
			case "content":
				thumbpath = "1/480x960.jpg";
				key += "1/" + filename;
				url = baseurl + policy.keyPrefix + "1/" + encodeURIComponent(filename);
				break;
			}

			formData.key = key;
			formData.success_action_status = "201";

			return new Promise((resolve, reject) => {
				const uploadId = FileUpload.uploadFile(baseurl, this.props.imageData.uri, filename, formData, result => {
					if (result.type === "success") {
						resolve({
							textId,
							responseBody: result.responseBody,
							thumbnailUrl: baseurl + policy.keyPrefix.replace(/^uploaded/, "generated") + thumbpath,
							originalUrl: url
						});
					} else {
						reject(new Error(result.message));
					}
				});

				this.setState({
					uploadId
				});
			});
		})
		.then(opts => {
			if (this.props.generateThumb) {
				return this._pollThumbnail(opts);
			} else {
				return opts;
			}
		})
		.then(result => {
			if (this.props.onUploadFinish) {
				this.props.onUploadFinish(result);
			}

			this.setState({
				status: FINISHED,
				uploadId: null
			});
		})
		.catch(err => {
			this.setState({
				status: ERROR,
				uploadId: null
			});

			if (this.props.onUploadError) {
				this.props.onUploadError(err);
			}
		});
	}

	_cancelUpload() {
		if (this.state.status === LOADING) {
			if (typeof this.state.uploadId === "number") {
				FileUpload.cancelUpload(this.state.uploadId);
			}

			this.setState({
				status: IDLE,
				uploadId: null
			});
		}
	}

	_closeUpload() {
		this._cancelUpload();

		if (this.props.onUploadClose) {
			this.props.onUploadClose();
		}
	}

	render() {
		return (
			<this.props.component
				imageData={this.props.imageData}
				status={this.state.status}
				startUpload={this._startUpload.bind(this)}
				cancelUpload={this._cancelUpload.bind(this)}
				closeUpload={this._closeUpload.bind(this)}
			/>
		);
	}
}

ImageUploadController.propTypes = {
	component: React.PropTypes.any.isRequired,
	imageData: React.PropTypes.shape({
		name: React.PropTypes.string.isRequired,
		uri: React.PropTypes.string.isRequired,
		height: React.PropTypes.number.isRequired,
		width: React.PropTypes.number.isRequired,
		size: React.PropTypes.number.isRequired
	}).isRequired,
	generateThumb: React.PropTypes.bool,
	uploadType: React.PropTypes.string,
	onUploadStart: React.PropTypes.func,
	onUploadCancel: React.PropTypes.func,
	onUploadClose: React.PropTypes.func,
	onUploadError: React.PropTypes.func,
	onUploadFinish: React.PropTypes.func,
	autoStart: React.PropTypes.bool
};

ImageUploadController.defaultProps = {
	generateThumb: true,
	uploadType: "content"
};
<commit_msg>Upload image using fetch<commit_after>/* eslint-env browser */

import React from "react-native";
import controller from "./controller";
import generate from "../../lib/generate.browser";

const IDLE = "idle";
const LOADING = "loading";
const FINISHED = "finished";
const ERROR = "error";

@controller
export default class ImageUploadController extends React.Component {
	constructor(props) {
		super(props);

		this.state = {
			status: IDLE,
			request: null
		};
	}

	componentWillMount() {
		if (this.props.autoStart) {
			this._startUpload();
		}
	}

	componentWillUnmount() {
		this._closeUpload();
	}

	_pollThumbnail(opts) {
		return new Promise((resolve, reject) => {
			const startTime = Date.now();

			let thumbTimer;

			const checkThumb = () => {
				if (thumbTimer) {
					clearTimeout(thumbTimer);
				}

				fetch(opts.thumbnailUrl)
					.then(() => resolve(opts))
					.catch(() => {
						if (Date.now() - startTime > 30000) {
							reject(new Error("Thumbnail generation timed out!"));
						} else {
							thumbTimer = setTimeout(checkThumb, 1500);
						}
					});
			};

			setTimeout(checkThumb, 3000);
		});
	}

	_startUpload() {
		if (this.state.status !== IDLE && this.state.status !== ERROR) {
			return;
		}

		this.setState({
			status: LOADING
		});

		if (this.props.onUploadStart) {
			this.props.onUploadStart();
		}

		const textId = generate.uid();

		this.query("upload/getPolicy", {
			uploadType: this.props.uploadType,
			userId: this.store.get("user"),
			textId
		})
		.then(res => {
			const policy = res.response;

			const baseurl = "https://" + policy.bucket + ".s3.amazonaws.com/";
			const filename = this.props.imageData.name.replace(/\s+/g, " ");

			let key = policy.keyPrefix,
				url, thumbpath;

			switch (this.props.uploadType) {
			case "avatar":
			case "banner":
				thumbpath = "256x256.jpg";
				key += "original." + filename.split(".").pop();
				url = baseurl + key;
				break;
			case "content":
				thumbpath = "1/480x960.jpg";
				key += "1/" + filename;
				url = baseurl + policy.keyPrefix + "1/" + encodeURIComponent(filename);
				break;
			}

			const formData = new FormData();

			const fields = [
				"acl", "policy", "x-amz-algorithm", "x-amz-credential",
				"x-amz-date", "x-amz-signature"
			];

			for (let i = 0, l = fields.length; i < l; i++) {
				formData.append(fields[i], policy[fields[i]]);
			}

			formData.append("key", key);
			formData.append("success_action_status", "201");

			const { uri, name } = this.props.imageData;
			const type = "image/" + (name.split(".").pop() || "jpg");

			formData.append("file", { uri, type });

			return fetch(baseurl, {
				method: "POST",
				body: formData
			}).then(() => ({
				textId,
				thumbnailUrl: baseurl + policy.keyPrefix.replace(/^uploaded/, "generated") + thumbpath,
				originalUrl: url
			}));
		})
		.then(opts => {
			if (this.props.generateThumb) {
				return this._pollThumbnail(opts);
			} else {
				return opts;
			}
		})
		.then(result => {
			if (this.props.onUploadFinish) {
				this.props.onUploadFinish(result);
			}

			this.setState({
				status: FINISHED,
				request: null
			});
		})
		.catch(err => {
			this.setState({
				status: ERROR,
				request: null
			});

			if (this.props.onUploadError) {
				this.props.onUploadError(err);
			}
		});
	}

	_cancelUpload() {
		if (this.state.status === LOADING) {
			if (this.state.request) {
				this.state.request.abort();
			}

			this.setState({
				status: IDLE,
				request: null
			});
		}
	}

	_closeUpload() {
		this._cancelUpload();

		if (this.props.onUploadClose) {
			this.props.onUploadClose();
		}
	}

	render() {
		return (
			<this.props.component
				imageData={this.props.imageData}
				status={this.state.status}
				startUpload={this._startUpload.bind(this)}
				cancelUpload={this._cancelUpload.bind(this)}
				closeUpload={this._closeUpload.bind(this)}
			/>
		);
	}
}

ImageUploadController.propTypes = {
	component: React.PropTypes.any.isRequired,
	imageData: React.PropTypes.shape({
		name: React.PropTypes.string.isRequired,
		uri: React.PropTypes.string.isRequired,
		height: React.PropTypes.number.isRequired,
		width: React.PropTypes.number.isRequired,
		size: React.PropTypes.number.isRequired
	}).isRequired,
	generateThumb: React.PropTypes.bool,
	uploadType: React.PropTypes.string,
	onUploadStart: React.PropTypes.func,
	onUploadCancel: React.PropTypes.func,
	onUploadClose: React.PropTypes.func,
	onUploadError: React.PropTypes.func,
	onUploadFinish: React.PropTypes.func,
	autoStart: React.PropTypes.bool
};

ImageUploadController.defaultProps = {
	generateThumb: true,
	uploadType: "content"
};
<|endoftext|>


<commit_before>window.dsbversion = '2.3';
<commit_msg>Bump version as a test.<commit_after>window.dsbversion = '2.3.1';
<|endoftext|>


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

foam.CLASS({
  package: 'foam.templates',
  name: 'TemplateOutput',

  documentation:
      'An object which can be output() to to create a concatenated string.',

  properties: [
    {
      name: 'buf',
      factory: function() { return []; }
    }
  ],

  methods: [
    function output() {
      for ( var i = 0 ; i < arguments.length ; i++ ) {
        var o = arguments[i];

        if ( typeof o === 'object' ) {
          this.buf.push(o.toString());
        } else {
          this.buf.push(o);
        }
      }
    },

    function toString() {
      return this.buf.length == 0 ? '' :
        this.buf.length == 1 ? this.buf[0] :
        this.buf.join('');
    }
  ]
});

foam.CLASS({
  package: 'foam.templates',
  name: 'TemplateUtil',

  axioms: [ foam.pattern.Singleton.create() ],

  requires: [
    'foam.parse.ImperativeGrammar as Grammar'
  ],

  constants: {
    HEADER: 'var self = this, ctx = this.__context__, Y = this.__subContext__;\n' +
      'var output = opt_outputter ? opt_outputter : TOC(this);\n' +
      'var out = output.output.bind(output);\n' +
      "out('",
    FOOTER: "');\nreturn opt_outputter ? output : output.toString();\n"
  },

  properties: [
    {
      name: 'grammar',
      factory: function() {
        var g = this.Grammar.create({
          symbols: function(repeat0, simpleAlt, sym, seq1, seq, repeat, notChars, anyChar, not, optional, literal) {
            return {
              START: sym('markup'),

              markup: repeat0(simpleAlt(
                sym('comment'),
                sym('simple value'),
                sym('raw values tag'),
                sym('code tag'),
                sym('ignored newline'),
                sym('newline'),
                sym('single quote'),
                sym('text')
              )),

              'comment': seq1(1, '<!--', repeat0(not('-->', anyChar())), '-->'),

              'simple value': seq('%%', repeat(notChars(' ()-"\r\n><:;,')), optional('()')),

              'raw values tag': simpleAlt(
                seq('<%=', repeat(not('%>', anyChar())), '%>')
              ),

              'code tag': seq('<%', repeat(not('%>', anyChar())), '%>'),
              'ignored newline': simpleAlt(
                literal('\\\r\\\n'),
                literal('\\\n')
              ),
              newline: simpleAlt(
                literal('\r\n'),
                literal('\n')
              ),
              'single quote': literal("'"),
              text: anyChar()
            }
          }
        });

        var self = this;

        g.addActions({
          markup: function(v) {
            var wasSimple = self.simple;
            var ret = wasSimple ? null : self.out.join('');
            self.out = [];
            self.simple = true;
            return [wasSimple, ret];
          },
          'simple value': function(v) {
            self.push("',\n self.",
                v[1].join(''),
                v[2],
                ",\n'");
          },
          'raw values tag': function (v) {
            self.push("',\n",
                v[1].join(''),
                ",\n'");
          },
          'code tag': function (v) {
            self.push("');\n",
                v[1].join(''),
                ";out('");
          },
          'single quote': function() {
            self.push("\\'");
          },
          newline: function() {
            self.push('\\n');
          },
          text: function(v) {
            self.pushSimple(v);
          }
        });
        return g;
      }
    },
    {
      name: 'out',
      factory: function() { return []; }
    },
    {
      name: 'simple',
      value: true
    }
  ],

  methods: [
    function push() {
      this.simple = false;
      this.pushSimple.apply(this, arguments);
    },

    function pushSimple() {
      this.out.push.apply(this.out, arguments);
    },

    function compile(t, name, args) {
      var result = this.grammar.parseString(t);
      if ( ! result ) throw "Error parsing template " + name;

      var code = this.HEADER +
          ( result[0] ? t : result[1] ) +
          this.FOOTER;

      var newArgs = ['opt_outputter'].concat(args);
      var f = eval(
        '(function() { ' +
          'var TOC = function(o) { return foam.templates.TemplateOutput.create(); };' +
          'var f = function(' + newArgs.join(',') + '){' + code + '};' +
          'return function() { '+
          'if ( arguments.length && arguments[0] && ! arguments[0].output ) return f.apply(this, [undefined].concat(Array.from(arguments)));' +
          'return f.apply(this, arguments);};})()');

      return f;
    },

    function lazyCompile(t, name, args) {
      return (function(util) {
        var delegate;
        return function() {
          if ( ! delegate ) delegate = util.compile(t, name, args)
          return delegate.apply(this, arguments);
        };
      })(this);
    }
  ]
});

foam.CLASS({
  package: 'foam.templates',
  name: 'TemplateAxiom',
  extends: 'Method',

  properties: [
    {
      name: 'template',
      class: 'String'
    },
    { name: 'code', required: false },
    'args'
  ],

  methods: [
    function installInProto(proto) {
      proto[this.name] =
          foam.templates.TemplateUtil.create().lazyCompile(
              this.template, this.name, this.args || []);
    }
  ]
});

foam.CLASS({
  package: 'foam.templates',
  name: 'TemplateExtension',
  refines: 'foam.core.Model',

  properties: [
    {
      name: 'templates',
      class: 'AxiomArray',
      of: 'foam.templates.TemplateAxiom',
      adaptArrayElement: function(o, prop) {
        return foam.lookup(prop.of).create(o);
      }
    }
  ]
});
<commit_msg>Improved docs.<commit_after>/**
 * @license
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

foam.CLASS({
  package: 'foam.templates',
  name: 'TemplateOutput',

  documentation: 'A buffer for storing Template output.',

  properties: [
    {
      name: 'buf',
      factory: function() { return []; }
    }
  ],

  methods: [
    function output() {
      for ( var i = 0 ; i < arguments.length ; i++ ) {
        var o = arguments[i];

        if ( typeof o === 'object' ) {
          this.buf.push(o.toString());
        } else {
          this.buf.push(o);
        }
      }
    },

    function toString() {
      return this.buf.length == 0 ? '' :
        this.buf.length == 1 ? this.buf[0] :
        this.buf.join('');
    }
  ]
});

foam.CLASS({
  package: 'foam.templates',
  name: 'TemplateUtil',

  documentation: 'Utility methods for working with Templates. Mostly just for internal use.',

  axioms: [ foam.pattern.Singleton.create() ],

  requires: [
    'foam.parse.ImperativeGrammar as Grammar'
  ],

  constants: {
    HEADER: 'var self = this, ctx = this.__context__, Y = this.__subContext__;\n' +
      'var output = opt_outputter ? opt_outputter : TOC(this);\n' +
      'var out = output.output.bind(output);\n' +
      "out('",
    FOOTER: "');\nreturn opt_outputter ? output : output.toString();\n"
  },

  properties: [
    {
      name: 'grammar',
      factory: function() {
        var g = this.Grammar.create({
          symbols: function(repeat0, simpleAlt, sym, seq1, seq, repeat, notChars, anyChar, not, optional, literal) {
            return {
              START: sym('markup'),

              markup: repeat0(simpleAlt(
                sym('comment'),
                sym('simple value'),
                sym('raw values tag'),
                sym('code tag'),
                sym('ignored newline'),
                sym('newline'),
                sym('single quote'),
                sym('text')
              )),

              'comment': seq1(1, '<!--', repeat0(not('-->', anyChar())), '-->'),

              'simple value': seq('%%', repeat(notChars(' ()-"\r\n><:;,')), optional('()')),

              'raw values tag': simpleAlt(
                seq('<%=', repeat(not('%>', anyChar())), '%>')
              ),

              'code tag': seq('<%', repeat(not('%>', anyChar())), '%>'),
              'ignored newline': simpleAlt(
                literal('\\\r\\\n'),
                literal('\\\n')
              ),
              newline: simpleAlt(
                literal('\r\n'),
                literal('\n')
              ),
              'single quote': literal("'"),
              text: anyChar()
            }
          }
        });

        var self = this;

        g.addActions({
          markup: function(v) {
            var wasSimple = self.simple;
            var ret = wasSimple ? null : self.out.join('');
            self.out = [];
            self.simple = true;
            return [wasSimple, ret];
          },
          'simple value': function(v) {
            self.push("',\n self.",
                v[1].join(''),
                v[2],
                ",\n'");
          },
          'raw values tag': function (v) {
            self.push("',\n",
                v[1].join(''),
                ",\n'");
          },
          'code tag': function (v) {
            self.push("');\n",
                v[1].join(''),
                ";out('");
          },
          'single quote': function() {
            self.push("\\'");
          },
          newline: function() {
            self.push('\\n');
          },
          text: function(v) {
            self.pushSimple(v);
          }
        });
        return g;
      }
    },
    {
      name: 'out',
      factory: function() { return []; }
    },
    {
      name: 'simple',
      value: true
    }
  ],

  methods: [
    function push() {
      this.simple = false;
      this.pushSimple.apply(this, arguments);
    },

    function pushSimple() {
      this.out.push.apply(this.out, arguments);
    },

    function compile(t, name, args) {
      var result = this.grammar.parseString(t);
      if ( ! result ) throw "Error parsing template " + name;

      var code = this.HEADER +
          ( result[0] ? t : result[1] ) +
          this.FOOTER;

      var newArgs = ['opt_outputter'].concat(args);
      var f = eval(
        '(function() { ' +
          'var TOC = function(o) { return foam.templates.TemplateOutput.create(); };' +
          'var f = function(' + newArgs.join(',') + '){' + code + '};' +
          'return function() { '+
          'if ( arguments.length && arguments[0] && ! arguments[0].output ) return f.apply(this, [undefined].concat(Array.from(arguments)));' +
          'return f.apply(this, arguments);};})()');

      return f;
    },

    function lazyCompile(t, name, args) {
      return (function(util) {
        var delegate;
        return function() {
          if ( ! delegate ) delegate = util.compile(t, name, args)
          return delegate.apply(this, arguments);
        };
      })(this);
    }
  ]
});

foam.CLASS({
  package: 'foam.templates',
  name: 'TemplateAxiom',
  extends: 'Method',

  properties: [
    {
      name: 'template',
      class: 'String'
    },
    { name: 'code', required: false },
    'args'
  ],

  methods: [
    function installInProto(proto) {
      proto[this.name] =
          foam.templates.TemplateUtil.create().lazyCompile(
              this.template, this.name, this.args || []);
    }
  ]
});

foam.CLASS({
  package: 'foam.templates',
  name: 'TemplateExtension',
  refines: 'foam.core.Model',

  properties: [
    {
      name: 'templates',
      class: 'AxiomArray',
      of: 'foam.templates.TemplateAxiom',
      adaptArrayElement: function(o, prop) {
        return foam.lookup(prop.of).create(o);
      }
    }
  ]
});
<|endoftext|>