<commit_before>var publisher = {
    subscribers: {
        any: [] // event type: subscribers
    },
    subscribe: function (fn, type) {
        type = type || 'any';
        if (typeof this.subscribers[type] === "undefined") {
            this.subscribers[type] = [];
        }
        this.subscribers[type].push(fn);
    },
    unsubscribe: function (fn, type) {
        this.visitSubscribers('unsubscribe', fn, type);
    },
    publish: function (publication, type) {
        this.visitSubscribers('publish', publication, type);
    },

    visitSubscribers: function (action, arg, type) {
        var pubtype = type || 'any',
            subscribers = this.subscribers[pubtype],
            i,
            max = subscribers.length;

        for (i = 0; i < max; i += 1) {
            if (action === 'publish') {
                subscribers[i](arg);
            } else {
                if (subscribers[i] === arg) {
                    subscribers.splice(i, 1);
                }
            }
        }
    }
 };

 function makePublisher(o) {
     var i;
     for (i in publisher) {
         if (publisher.hasOwnProperty(i) && typeof publisher[i] === "function") {
             o[i] = publisher[i];
         }
     }
     o.subscribers = {
         any: []
     };
 }

 var paper = {
     daily: function() {
         this.publish('big news today');
     },
     monthly: function() {
         this.publish('interesting analysis', 'montly');
     }
 };

 makePublisher(paper);

 var joe = {
     drinkCoffee: function(paper) {
         console.log('Just read ' + paper);
     },
     sundayPreNap: function(montly) {
         console.log('About to fall asleep reading this ' + monthly);
     }
 };
<commit_msg>Change Observer Pattern example with new one<commit_after>function Click() {
    this.handlers = []; // Observer

    this.subscribe = function(fn) {
        this.handlers.push(fn);
    };

    this.unsubscribe = function(fn) {
        this.handlers = this.handlers.filter(function(item) {
            if(item !== fn) {
                return item;
            }
        });
    };

    this.fire = function(obj, thisObj) {
        var scope = thisObj || window;
        this.handlers.forEach(function(item) {
            item.call(scope, obj);
        });
    };
}

// log helper

var log = (function() {
    'use strict';

    var log = '';
    return {
        add: function(msg) {
            log += msg + '\n';
        },
        show: function() {
            console.log(log);
            log = '';
        }
    };
}());

(function run() {
    var clickHandler = function(item) {
        log.add('fired: ' + item);
    };

    var click = new Click();

    click.subscribe(clickHandler);
    click.fire('event #1');
    click.unsubscribe(clickHandler);
    click.fire('event #2');
    click.subscribe(clickHandler);
    click.fire('event #3');

    log.show();
}());
<|endoftext|>


<commit_before>pbc.assignD.get('I2C')['check_assign'] = function(py2block, node, targets, value) {
    var funcName = py2block.identifier(value.func.attr);
    var moduleName = py2block.Name_str(value.func.value);
    if(value._astname === "Call" && moduleName === "machine"
        && funcName === "I2C" && value.keywords.length === 3)
        return true;
    return false;
}

pbc.assignD.get('I2C')['create_block'] = function(py2block, node, targets, value){

    var astname = value.keywords[0]._astname;
    if(astname === "keyword" && value.keywords[0].arg.v == "scl"
        && value.keywords[0].value.func.attr.v === "Pin"){
    var sdablock = null;
    var sclblock = null;
    var freqblock = null;
    var param = value.keywords[0];
    var key = py2block.identifier(param.arg);
    var i2cblock=py2block.convert(targets[0])
    for (var i = 0; i < value.keywords.length; i++) {
        var param = value.keywords[i];
        var key = py2block.identifier(param.arg);
        if (key === "sda") {
            pbc.inScope = "communicate_i2c_init";
            pbc.pinType = "pins_digital_pin";
            sdablock = py2block.convert(param.value.args[0]);
            pbc.pinType = null;
            pbc.inScope = null;
        } else if (key === "scl") {
            pbc.inScope = "communicate_i2c_init";
            pbc.pinType = "pins_digital_pin";
            sclblock = py2block.convert(param.value.args[0]);
            pbc.pinType = null;
            pbc.inScope = null;
        } else if (key === "freq") {
            freqblock = py2block.convert(param.value);
        }
    }
}
    if (sdablock != null && sclblock != null && freqblock != null) {
        return block("communicate_i2c_init", node.lineno, {}, {
            "SUB":i2cblock,
            'RX': sdablock,
            'TX': sclblock,
            "freq": freqblock
        }, {
            "inline": "true"
        });
    }
}

pbc.objectFunctionD.get('readfrom')['I2C'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
    if (args.length !== 2) {
        throw new Error("Incorrect number of arguments");
    }
    var objblock = py2block.convert(func.value);
    var adblock = py2block.convert(args[0]);
    var datablock = py2block.convert(args[1]);
    return [block("communicate_i2c_read", func.lineno, {}, {
        "address": adblock,
        "data": datablock,
        "VAR": objblock
    }, {
        "inline": "true"
    })];
}

pbc.objectFunctionD.get('writeto')['I2C'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
    if (args.length !== 2) {
        throw new Error("Incorrect number of arguments");
    }
    var objblock = py2block.convert(func.value);
    var adblock = py2block.convert(args[0]);
    var datablock = py2block.convert(args[1]);
    return [block("communicate_i2c_write", func.lineno, {}, {
        "address": adblock,
        "data": datablock,
        "VAR": objblock
    }, {
        "inline": "true"
    })];
}

pbc.objectFunctionD.get('scan')['I2C'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
    if (args.length !== 0) {
        throw new Error("Incorrect number of arguments");
    }
    var objblock = py2block.convert(func.value);
    return [block("communicate_i2c_scan", func.lineno, {}, {
        "VAR": objblock,
    }, {
        "inline": "true"
    })];
}

pbc.objectFunctionD.get('read')['I2C'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
    if (args.length !== 0) {
        throw new Error("Incorrect number of arguments");
    }
    var objblock = py2block.convert(func.value);
    return [block("communicate_i2c_master_read", func.lineno, {}, {
        "VAR": objblock,
    }, {
        "inline": "true"
    })];
}

pbc.objectFunctionD.get('available')['I2C'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
    if (args.length !== 0) {
        throw new Error("Incorrect number of arguments");
    }
    var objblock = py2block.convert(func.value);
    return [block("communicate_i2c_available", func.lineno, {}, {
        "VAR": objblock,
    }, {
        "inline": "true"
    })];
}

pbc.assignD.get('SPI')['check_assign'] = function(py2block, node, targets, value) {
    var funcName = py2block.identifier(value.func.attr);
    var moduleName = py2block.Name_str(value.func.value);
    if(value._astname === "Call" && moduleName === "machine"
        && funcName === "SPI" && value.keywords.length === 6)
        return true;
    return false;
}

pbc.assignD.get('SPI')['create_block'] = function(py2block, node, targets, value){

    var astname = value.keywords[0]._astname;
    if(value.keywords[0].arg.v == "baudrate" && value.keywords[3].arg.v == "sck" && value.keywords[3].value.func.attr.v == "Pin"){
    var polarityblock = null;
    var phaseblock = null;
    var sckblock = null;
    var mosiblock = null;
    var misoblock = null;
    var freqblock = null;
    var param = value.keywords[0];
    var key = py2block.identifier(param.arg);
    var spiblock=py2block.convert(targets[0]);
    for (var i = 0; i < value.keywords.length; i++) {
        var param = value.keywords[i];
        var key = py2block.identifier(param.arg);
        if (key === "baudrate") {
            freqblock = py2block.convert(param.value);
        } else if (key === "polarity") {
            polarityblock = py2block.convert(param.value);
        } else if (key === "phase") {
            phaseblock = py2block.convert(param.value);
        } else if (key === "sck") {
            pbc.inScope = "communicate_spi_init";
            pbc.pinType = "pins_digital_pin";
            sckblock = py2block.convert(param.value.args[0]);
            pbc.pinType = null;
            pbc.inScope = null;
        } else if (key === "mosi") {
            pbc.inScope = "communicate_spi_init";
            pbc.pinType = "pins_digital_pin";
            mosiblock = py2block.convert(param.value.args[0]);
            pbc.pinType = null;
            pbc.inScope = null;
        } else if (key === "miso") {
            pbc.inScope = "communicate_spi_init";
            pbc.pinType = "pins_digital_pin";
            misoblock = py2block.convert(param.value.args[0]);
            pbc.pinType = null;
            pbc.inScope = null;
        }
    }
}
    if (polarityblock != null && phaseblock != null && freqblock != null && sckblock != null && mosiblock != null && misoblock != null) {
        return block("communicate_spi_init", node.lineno, {}, {
            "VAR":spiblock,
            "freq": freqblock,
            "polarity": polarityblock,
            "phase": phaseblock,
            "sck": sckblock,
            "mosi": mosiblock,
            "miso": misoblock,
        }, {
            "inline": "true"
        });
    }
}

pbc.objectFunctionD.get('init')['SPI'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
    if (args.length == 0 & keywords.length == 1){
        var objblock = py2block.convert(func.value);
        var btlblock = null;
        var param = keywords[0];
        var key = py2block.identifier(param.arg);
        if (key === "baudrate") {
            bltblock = py2block.convert(param.value);
        }
        if (bltblock != null ) {
            return [block("communicate_spi_set", func.lineno, {}, {
                "VAR":objblock,
                "data": bltblock,
            }, {
                "inline": "true"
            })];
        }
    }else{
        throw new Error("Incorrect number of arguments");
    }
}

pbc.assignD.get('spi')['check_assign'] = function(py2block, node, targets, value) {
    if(value._astname != "Call" || value.func._astname != "Name"){
        return false;
    }
    var funcName = py2block.Name_str(value.func);
    if(funcName === "bytearray" && value.args.length === 1)
        return true;
    return false;
}

pbc.assignD.get('spi')['create_block'] = function(py2block, node, targets, value){
    return block("communicate_spi_buffer", node.lineno, {
    }, {
        "data":py2block.convert(value.args[0]),
        "VAR":py2block.convert(targets[0])
    });
}

// pbc.objectFunctionD.get('read')['SPI'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
//     if (args.length !== 1) {
//         throw new Error("Incorrect number of arguments");
//     }
//     var objblock = py2block.convert(func.value);
//     var byteblock = py2block.convert(args[0]);
//     return [block("communicate_spi_read", func.lineno, {}, {
//         "data": byteblock,
//         "VAR": objblock
//     }, {
//         "inline": "true"
//     })];
// }

pbc.objectFunctionD.get('readinto')['SPI'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
    if (args.length !== 1 & args.length !== 2) {
        throw new Error("Incorrect number of arguments");
    }
    var objblock = py2block.convert(func.value);
    var byteblock = py2block.convert(args[0]);
    if (args.length == 1){
        return [block("communicate_spi_readinto", func.lineno, {}, {
                "data": byteblock,
                "VAR": objblock
            }, {
                "inline": "true"
            })];
    }
    if (args.length == 2){
        var outputblock = py2block.convert(args[1]);
        return [block("communicate_spi_readinto_output", func.lineno, {}, {
                "data": byteblock,
                "val": outputblock,
                "VAR": objblock
            }, {
                "inline": "true"
            })];
    }
}

// pbc.objectFunctionD.get('write')['SPI'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
//     if (args.length !== 1) {
//         throw new Error("Incorrect number of arguments");
//     }
//     var objblock = py2block.convert(func.value);
//     var byteblock = py2block.convert(args[0]);
//     return [block("communicate_spi_write", func.lineno, {}, {
//         "VAR": objblock,
//         "data": byteblock
//     }, {
//         "inline": "true"
//     })];
// }

pbc.objectFunctionD.get('write_readinto')['SPI'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
    if (args.length !== 2) {
        throw new Error("Incorrect number of arguments");
    }
    var objblock = py2block.convert(func.value);
    var byteblock = py2block.convert(args[0]);
    var bufblock = py2block.convert(args[1]);
    return [block("communicate_spi_write_readinto", func.lineno, {}, {
        "VAR": objblock,
        "data": byteblock,
        "val": bufblock
    }, {
        "inline": "true"
    })];
}

pbc.assignD.get('OW')['check_assign'] = function(py2block, node, targets, value) {
    if(value._astname != "Call" || value.func._astname != "Attribute" || value.func.value._astname != "Name"){
        return false;
    }
    var moduleName = py2block.Name_str(value.func.value);
    var funcName = py2block.identifier(value.func.attr);
    if(value._astname === "Call" && moduleName === "onewire"
        && funcName === "OneWire" && value.args.length === 1)
        return true;
    return false;
}

pbc.assignD.get('OW')['create_block'] = function(py2block, node, targets, value){
    var pwmAstName = value.args[0]._astname;
    pbc.pinType="pins_digital_pin";
    var pinblock;

    if (pwmAstName === "Call"&& value.args[0].func._astname == "Attribute" && value.args[0].func.attr.v==="Pin") {
        pinblock=py2block.convert(value.args[0].args[0])
    }
    pbc.pinType=null;
    return block("communicate_ow_init", node.lineno, {
    }, {
        "BUS":pinblock,
        "VAR":py2block.convert(targets[0]),
    });
}

pbc.objectFunctionD.get('scan')['OW'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
    if (args.length !== 0) {
        throw new Error("Incorrect number of arguments");
    }
    var objblock = py2block.convert(func.value);
    return [block("communicate_ow_scan", func.lineno, {}, {
        "VAR": objblock,
    }, {
        "inline": "true"
    })];
}

pbc.objectFunctionD.get('readbyte')['OW'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
    if (args.length !== 0) {
        throw new Error("Incorrect number of arguments");
    }
    var objblock = py2block.convert(func.value);
    return [block("communicate_ow_read", func.lineno, {}, {
        "VAR": objblock,
    }, {
        "inline": "true"
    })];
}

pbc.objectFunctionD.get('reset')['OW'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
    if (args.length !== 0) {
        throw new Error("Incorrect number of arguments");
    }
    var objblock = py2block.convert(func.value);
    return [block("communicate_ow_reset", func.lineno, {}, {
        "VAR": objblock,
    }, {
        "inline": "true"
    })];
}

pbc.objectFunctionD.get('select_rom')['OW'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
    if (args.length !== 1) {
        throw new Error("Incorrect number of arguments");
    }
    var objblock = py2block.convert(func.value);
    var byteblock = py2block.convert(args[0].func.value);
    return [block("communicate_ow_select", func.lineno, {}, {
        "VAR": objblock,
        "byte": byteblock
    }, {
        "inline": "true"
    })];
}<commit_msg>补充上一条<commit_after>pbc.assignD.get('I2C')['check_assign'] = function(py2block, node, targets, value) {
    var funcName = py2block.identifier(value.func.attr);
    var moduleName = py2block.Name_str(value.func.value);
    if(value._astname === "Call" && moduleName === "machine"
        && funcName === "I2C" && value.keywords.length === 3)
        return true;
    return false;
}

pbc.assignD.get('I2C')['create_block'] = function(py2block, node, targets, value){

    var astname = value.keywords[0]._astname;
    if(astname === "keyword" && value.keywords[0].arg.v == "scl"
        && value.keywords[0].value.func.attr.v === "Pin"){
    var sdablock = null;
    var sclblock = null;
    var freqblock = null;
    var param = value.keywords[0];
    var key = py2block.identifier(param.arg);
    var i2cblock=py2block.convert(targets[0])
    for (var i = 0; i < value.keywords.length; i++) {
        var param = value.keywords[i];
        var key = py2block.identifier(param.arg);
        if (key === "sda") {
            pbc.inScope = "communicate_i2c_init";
            pbc.pinType = "pins_digital_pin";
            sdablock = py2block.convert(param.value.args[0]);
            pbc.pinType = null;
            pbc.inScope = null;
        } else if (key === "scl") {
            pbc.inScope = "communicate_i2c_init";
            pbc.pinType = "pins_digital_pin";
            sclblock = py2block.convert(param.value.args[0]);
            pbc.pinType = null;
            pbc.inScope = null;
        } else if (key === "freq") {
            freqblock = py2block.convert(param.value);
        }
    }
}
    if (sdablock != null && sclblock != null && freqblock != null) {
        return block("communicate_i2c_init", node.lineno, {}, {
            "SUB":i2cblock,
            'RX': sdablock,
            'TX': sclblock,
            "freq": freqblock
        }, {
            "inline": "true"
        });
    }
}

pbc.objectFunctionD.get('readfrom')['I2C'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
    if (args.length !== 2) {
        throw new Error("Incorrect number of arguments");
    }
    var objblock = py2block.convert(func.value);
    var adblock = py2block.convert(args[0]);
    var datablock = py2block.convert(args[1]);
    return [block("communicate_i2c_read", func.lineno, {}, {
        "address": adblock,
        "data": datablock,
        "VAR": objblock
    }, {
        "inline": "true"
    })];
}

pbc.objectFunctionD.get('writeto')['I2C'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
    if (args.length !== 2) {
        throw new Error("Incorrect number of arguments");
    }
    var objblock = py2block.convert(func.value);
    var adblock = py2block.convert(args[0]);
    var datablock = py2block.convert(args[1]);
    return [block("communicate_i2c_write", func.lineno, {}, {
        "address": adblock,
        "data": datablock,
        "VAR": objblock
    }, {
        "inline": "true"
    })];
}

pbc.objectFunctionD.get('scan')['I2C'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
    if (args.length !== 0) {
        throw new Error("Incorrect number of arguments");
    }
    var objblock = py2block.convert(func.value);
    return [block("communicate_i2c_scan", func.lineno, {}, {
        "VAR": objblock,
    }, {
        "inline": "true"
    })];
}

pbc.objectFunctionD.get('read')['I2C'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
    if (args.length !== 0) {
        throw new Error("Incorrect number of arguments");
    }
    var objblock = py2block.convert(func.value);
    return [block("communicate_i2c_master_read", func.lineno, {}, {
        "VAR": objblock,
    }, {
        "inline": "true"
    })];
}

pbc.objectFunctionD.get('available')['I2C'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
    if (args.length !== 0) {
        throw new Error("Incorrect number of arguments");
    }
    var objblock = py2block.convert(func.value);
    return [block("communicate_i2c_available", func.lineno, {}, {
        "VAR": objblock,
    }, {
        "inline": "true"
    })];
}

pbc.assignD.get('SPI')['check_assign'] = function(py2block, node, targets, value) {
    var funcName = py2block.identifier(value.func.attr);
    var moduleName = py2block.Name_str(value.func.value);
    if(value._astname === "Call" && moduleName === "machine"
        && funcName === "SPI" && value.keywords.length === 6)
        return true;
    return false;
}

pbc.assignD.get('SPI')['create_block'] = function(py2block, node, targets, value){

    var astname = value.keywords[0]._astname;
    if(value.keywords[0].arg.v == "baudrate" && value.keywords[3].arg.v == "sck" && value.keywords[3].value.func.attr.v == "Pin"){
    var polarityblock = null;
    var phaseblock = null;
    var sckblock = null;
    var mosiblock = null;
    var misoblock = null;
    var freqblock = null;
    var param = value.keywords[0];
    var key = py2block.identifier(param.arg);
    var spiblock=py2block.convert(targets[0]);
    for (var i = 0; i < value.keywords.length; i++) {
        var param = value.keywords[i];
        var key = py2block.identifier(param.arg);
        if (key === "baudrate") {
            freqblock = py2block.convert(param.value);
        } else if (key === "polarity") {
            polarityblock = py2block.convert(param.value);
        } else if (key === "phase") {
            phaseblock = py2block.convert(param.value);
        } else if (key === "sck") {
            pbc.inScope = "communicate_spi_init";
            pbc.pinType = "pins_digital_pin";
            sckblock = py2block.convert(param.value.args[0]);
            pbc.pinType = null;
            pbc.inScope = null;
        } else if (key === "mosi") {
            pbc.inScope = "communicate_spi_init";
            pbc.pinType = "pins_digital_pin";
            mosiblock = py2block.convert(param.value.args[0]);
            pbc.pinType = null;
            pbc.inScope = null;
        } else if (key === "miso") {
            pbc.inScope = "communicate_spi_init";
            pbc.pinType = "pins_digital_pin";
            misoblock = py2block.convert(param.value.args[0]);
            pbc.pinType = null;
            pbc.inScope = null;
        }
    }
}
    if (polarityblock != null && phaseblock != null && freqblock != null && sckblock != null && mosiblock != null && misoblock != null) {
        return block("communicate_spi_init", node.lineno, {}, {
            "VAR":spiblock,
            "freq": freqblock,
            "polarity": polarityblock,
            "phase": phaseblock,
            "sck": sckblock,
            "mosi": mosiblock,
            "miso": misoblock,
        }, {
            "inline": "true"
        });
    }
}

// 跟control的system_timer重了
// pbc.objectFunctionD.get('init')['SPI'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
//     if (args.length == 0 & keywords.length == 1){
//         var objblock = py2block.convert(func.value);
//         var btlblock = null;
//         var param = keywords[0];
//         var key = py2block.identifier(param.arg);
//         if (key === "baudrate") {
//             bltblock = py2block.convert(param.value);
//         }
//         if (bltblock != null ) {
//             return [block("communicate_spi_set", func.lineno, {}, {
//                 "VAR":objblock,
//                 "data": bltblock,
//             }, {
//                 "inline": "true"
//             })];
//         }
//     }else{
//         throw new Error("Incorrect number of arguments");
//     }
// }

pbc.assignD.get('spi')['check_assign'] = function(py2block, node, targets, value) {
    if(value._astname != "Call" || value.func._astname != "Name"){
        return false;
    }
    var funcName = py2block.Name_str(value.func);
    if(funcName === "bytearray" && value.args.length === 1)
        return true;
    return false;
}

pbc.assignD.get('spi')['create_block'] = function(py2block, node, targets, value){
    return block("communicate_spi_buffer", node.lineno, {
    }, {
        "data":py2block.convert(value.args[0]),
        "VAR":py2block.convert(targets[0])
    });
}

// pbc.objectFunctionD.get('read')['SPI'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
//     if (args.length !== 1) {
//         throw new Error("Incorrect number of arguments");
//     }
//     var objblock = py2block.convert(func.value);
//     var byteblock = py2block.convert(args[0]);
//     return [block("communicate_spi_read", func.lineno, {}, {
//         "data": byteblock,
//         "VAR": objblock
//     }, {
//         "inline": "true"
//     })];
// }

pbc.objectFunctionD.get('readinto')['SPI'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
    if (args.length !== 1 & args.length !== 2) {
        throw new Error("Incorrect number of arguments");
    }
    var objblock = py2block.convert(func.value);
    var byteblock = py2block.convert(args[0]);
    if (args.length == 1){
        return [block("communicate_spi_readinto", func.lineno, {}, {
                "data": byteblock,
                "VAR": objblock
            }, {
                "inline": "true"
            })];
    }
    if (args.length == 2){
        var outputblock = py2block.convert(args[1]);
        return [block("communicate_spi_readinto_output", func.lineno, {}, {
                "data": byteblock,
                "val": outputblock,
                "VAR": objblock
            }, {
                "inline": "true"
            })];
    }
}

// pbc.objectFunctionD.get('write')['SPI'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
//     if (args.length !== 1) {
//         throw new Error("Incorrect number of arguments");
//     }
//     var objblock = py2block.convert(func.value);
//     var byteblock = py2block.convert(args[0]);
//     return [block("communicate_spi_write", func.lineno, {}, {
//         "VAR": objblock,
//         "data": byteblock
//     }, {
//         "inline": "true"
//     })];
// }

pbc.objectFunctionD.get('write_readinto')['SPI'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
    if (args.length !== 2) {
        throw new Error("Incorrect number of arguments");
    }
    var objblock = py2block.convert(func.value);
    var byteblock = py2block.convert(args[0]);
    var bufblock = py2block.convert(args[1]);
    return [block("communicate_spi_write_readinto", func.lineno, {}, {
        "VAR": objblock,
        "data": byteblock,
        "val": bufblock
    }, {
        "inline": "true"
    })];
}

pbc.assignD.get('OW')['check_assign'] = function(py2block, node, targets, value) {
    if(value._astname != "Call" || value.func._astname != "Attribute" || value.func.value._astname != "Name"){
        return false;
    }
    var moduleName = py2block.Name_str(value.func.value);
    var funcName = py2block.identifier(value.func.attr);
    if(value._astname === "Call" && moduleName === "onewire"
        && funcName === "OneWire" && value.args.length === 1)
        return true;
    return false;
}

pbc.assignD.get('OW')['create_block'] = function(py2block, node, targets, value){
    var pwmAstName = value.args[0]._astname;
    pbc.pinType="pins_digital_pin";
    var pinblock;

    if (pwmAstName === "Call"&& value.args[0].func._astname == "Attribute" && value.args[0].func.attr.v==="Pin") {
        pinblock=py2block.convert(value.args[0].args[0])
    }
    pbc.pinType=null;
    return block("communicate_ow_init", node.lineno, {
    }, {
        "BUS":pinblock,
        "VAR":py2block.convert(targets[0]),
    });
}

pbc.objectFunctionD.get('scan')['OW'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
    if (args.length !== 0) {
        throw new Error("Incorrect number of arguments");
    }
    var objblock = py2block.convert(func.value);
    return [block("communicate_ow_scan", func.lineno, {}, {
        "VAR": objblock,
    }, {
        "inline": "true"
    })];
}

pbc.objectFunctionD.get('readbyte')['OW'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
    if (args.length !== 0) {
        throw new Error("Incorrect number of arguments");
    }
    var objblock = py2block.convert(func.value);
    return [block("communicate_ow_read", func.lineno, {}, {
        "VAR": objblock,
    }, {
        "inline": "true"
    })];
}

pbc.objectFunctionD.get('reset')['OW'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
    if (args.length !== 0) {
        throw new Error("Incorrect number of arguments");
    }
    var objblock = py2block.convert(func.value);
    return [block("communicate_ow_reset", func.lineno, {}, {
        "VAR": objblock,
    }, {
        "inline": "true"
    })];
}

pbc.objectFunctionD.get('select_rom')['OW'] = function (py2block, func, args, keywords, starargs, kwargs, node) {
    if (args.length !== 1) {
        throw new Error("Incorrect number of arguments");
    }
    var objblock = py2block.convert(func.value);
    var byteblock = py2block.convert(args[0].func.value);
    return [block("communicate_ow_select", func.lineno, {}, {
        "VAR": objblock,
        "byte": byteblock
    }, {
        "inline": "true"
    })];
}<|endoftext|>


<commit_before>// jshint devel:true

(function (WWCD) {
  'use strict';

  let templateEngine = {
    run(templatePrefix, context = {}) {
      let template = Handlebars.compile($(`\#${templatePrefix}-template`).html());
      $(`\#${templatePrefix}-target`).html(template(context));
    }
  };

  WWCD.injector = {
    templateEngine: templateEngine,
    featuresGroups: WWCD.featuresGroups
  };

})(window.WWCD = (window.WWCD || {}));
<commit_msg>dependency injection experiment<commit_after>// jshint devel:true

(function (WWCD) {
  'use strict';

  let templateEngine = {
    run(templatePrefix, context = {}) {
      let template = Handlebars.compile($(`\#${templatePrefix}-template`).html());
      $(`\#${templatePrefix}-target`).html(template(context));
    }
  };

  let $defineMultiple = function (callback, config) {
    for (let key in config) {
      if (config.hasOwnProperty(key)) {
        callback(key, config[key]);
      }
    }
  };

  class Configurator {
    constructor(injector) {
      this.$injector = injector;
    }

    $define(name, getter) {
      Object.defineProperty(this.$injector, name, {
        readonly: true,
        enumerable: true,
        get: getter
      });
    }

    singleton(name, instance) {
      this.$define(name, () => instance);
      return this;
    }

    singletons(config) {
      $defineMultiple(this.singleton.bind(this), config);
      return this;
    }

    factory(name, func, ...rest) {
      this.$define(name, () => func(...rest, this.$injector));
      return this;
    }

    factories(config) {
      $defineMultiple(this.factory.bind(this), config);
      return this;
    }

    transientInstance(name, constructor, ...rest) {
      this.$define(name, () => new constructor(...rest, this.$injector));
      return this;
    }

    transientInstances(config) {
      $defineMultiple(this.transientInstance.bind(this), config);
      return this;
    }
  }

  class Container {
    constructor(configureCallback = undefined) {
      this.$injector = Object.create(null);

      if (configureCallback) {
        this.configure(configureCallback);
      }
    }

    configure(configureCallback) {
      configureCallback(new Configurator(this.$injector));
    }

    get injector() {
      return this.$injector;
    }
  }

  let container = new Container(register => register.singletons({
    templateEngine: templateEngine,
    featuresGroups: WWCD.featuresGroups
  }));

  WWCD.injector = container.injector;

})(window.WWCD = (window.WWCD || {}));
<|endoftext|>


<commit_before>import Home from "components/Home";
import { shallow, mount, render } from 'enzyme';

describe("components/Home", () => {
    it("should render without an issue", () => {
        const subject = <Home />;
        expect(shallow(subject)).not.to.equal(undefined);
    });
});

<commit_msg>removing unused dependencies<commit_after>import Home from "components/Home";
import { shallow } from 'enzyme';

describe("components/Home", () => {
    it("should render without an issue", () => {
        const subject = <Home />;
        expect(shallow(subject)).not.to.equal(undefined);
    });
});

<|endoftext|>


<commit_before>'use babel'
/** @jsx etch.dom */

import {CompositeDisposable} from 'atom'
import {Etch} from '../util/etch'

import etch from 'etch'

function editorsForFile(file) {
  return atom.workspace.getTextEditors().filter(ed => ed.getPath() === file)
}

class BreakpointView extends Etch {
  render() {
    return
  }
}

class Breakpoint {
  constructor(manager, {file, line}) {
    this.manager = manager
    this.file = file
    this.line = line
    this.views = []
  }

  destroy() {
    this.manager.remove(this)
  }
}

export default class BreakpointManager {
  constructor(scopes) {
    this.subs = new CompositeDisposable()
    this.scopes = scopes
    this.breakpoints = []

    this.subs.add(atom.workspace.observeTextEditors(ed => {
      this.subs.add(ed.observeGrammar(() => {
        if (this.appliesToEditor(ed)) {
          this.init(ed)
        } else {
          this.deinit(ed)
        }
      }))
    }))
  }

  destroy() {
    this.subs.dispose()
    atom.workspace.getTextEditors().forEach(ed => this.deinit(ed))
  }

  getForFile(path) {
    return this.breakpoints.filter(({file}) => file === path)
  }

  get(file, l) {
    return this.getForFile(file).filter(({line}) => line === l)[0]
  }

  appliesToEditor(ed) {
    return this.scopes.indexOf(ed.getGrammar().scopeName) > -1
  }

  init(ed) {
    // TODO: gutter should be namespaced
    let g = ed.addGutter({name: 'ink-breakpoints'})

    // TODO: once atom 1.13 is out we can do this properly, but for now the
    //       shadowDOM makes this a bit difficult
    // click on gutter creates new bp
    // this.listener.add('.gutter[gutter-name="ink-breakpoints"', 'click', event => {
    //   console.log('clicked! yay :D');
    //   let ed = atom.workspace.getActiveTextEditor()
    //   let row = ed.getElement().component.screenPositionForMouseEvent(event)[0]
    //   this.add(file, row)
    // })

    this.getForFile(ed.getPath()).map(bp => this.insertView(ed, bp))
  }

  deinit(ed) {
    if (g = ed.gutterWithName('ink-breakpoints')) g.destroy()
  }

  insertView(ed, bp) {
    if (!this.appliesToEditor(ed)) return
    let marker = ed.markBufferPosition({row: bp.line})
    let gutter = ed.gutterWithName('ink-breakpoints')
    let view = new BreakpointView({})
    let decoration = gutter.decorateMarker(marker, {item: view.element})
    bp.views.push({
      destroy() {
        view.destroy()
        marker.destroy()
      }
    })
  }

  add(file, line) {
    let bp = new Breakpoint(this, {file, line})
    editorsForFile(file).forEach(ed => this.insertView(ed, bp))
    this.breakpoints.push(bp)
    return bp
  }

  remove(bp) {
    bp.views.forEach(v => v.destroy())
    this.breakpoints = this.breakpoints.filter(x => x !== bp)
  }

  toggle(file, line) {
    let bp = this.get(file, line)
    if (bp) {
      bp.destroy()
      return
    } else {
      return this.add(file, line)
    }
  }

  clear() {
    bps = this.breakpoints
    this.breakpoints = []
    bps.forEach(bp => bp.destroy())
  }
}
<commit_msg>keep bps stable<commit_after>'use babel'
/** @jsx etch.dom */

import {CompositeDisposable} from 'atom'
import {Etch} from '../util/etch'

import etch from 'etch'

function editorsForFile(file) {
  return atom.workspace.getTextEditors().filter(ed => ed.getPath() === file)
}

class BreakpointView extends Etch {
  render() {
    return
  }
}

class Breakpoint {
  constructor(manager, {file, line}) {
    this.manager = manager
    this.file = file
    this.line = line
    this.views = []
  }

  destroy() {
    this.manager.remove(this)
  }
}

export default class BreakpointManager {
  constructor(scopes) {
    this.subs = new CompositeDisposable()
    this.scopes = scopes
    this.breakpoints = []

    this.subs.add(atom.workspace.observeTextEditors(ed => {
      this.subs.add(ed.observeGrammar(() => {
        if (this.appliesToEditor(ed)) {
          this.init(ed)
        } else {
          this.deinit(ed)
        }
      }))
    }))
  }

  destroy() {
    this.subs.dispose()
    atom.workspace.getTextEditors().forEach(ed => this.deinit(ed))
  }

  getForFile(path) {
    return this.breakpoints.filter(({file}) => file === path)
  }

  get(file, l) {
    return this.getForFile(file).filter(({line}) => line === l)[0]
  }

  appliesToEditor(ed) {
    return this.scopes.indexOf(ed.getGrammar().scopeName) > -1
  }

  init(ed) {
    // TODO: gutter should be namespaced
    let g = ed.addGutter({name: 'ink-breakpoints'})

    // TODO: once atom 1.13 is out we can do this properly, but for now the
    //       shadowDOM makes this a bit difficult
    // click on gutter creates new bp
    // this.listener.add('.gutter[gutter-name="ink-breakpoints"', 'click', event => {
    //   console.log('clicked! yay :D');
    //   let ed = atom.workspace.getActiveTextEditor()
    //   let row = ed.getElement().component.screenPositionForMouseEvent(event)[0]
    //   this.add(file, row)
    // })

    this.getForFile(ed.getPath()).map(bp => this.insertView(ed, bp))
  }

  deinit(ed) {
    if (g = ed.gutterWithName('ink-breakpoints')) g.destroy()
  }

  insertView(ed, bp) {
    if (!this.appliesToEditor(ed)) return
    let marker = ed.markBufferPosition({row: bp.line}, {invalidate: 'never'})
    // TODO: remove bps if they are past the end of a file
    marker.onDidChange(() => marker.setBufferRange([[bp.line, 0], [bp.line, 0]]))
    let gutter = ed.gutterWithName('ink-breakpoints')
    let view = new BreakpointView({})
    let decoration = gutter.decorateMarker(marker, {item: view.element})
    bp.views.push({
      destroy() {
        view.destroy()
        marker.destroy()
      }
    })
  }

  add(file, line) {
    let bp = new Breakpoint(this, {file, line})
    editorsForFile(file).forEach(ed => this.insertView(ed, bp))
    this.breakpoints.push(bp)
    return bp
  }

  remove(bp) {
    bp.views.forEach(v => v.destroy())
    this.breakpoints = this.breakpoints.filter(x => x !== bp)
  }

  toggle(file, line) {
    let bp = this.get(file, line)
    if (bp) {
      bp.destroy()
      return
    } else {
      return this.add(file, line)
    }
  }

  clear() {
    bps = this.breakpoints
    this.breakpoints = []
    bps.forEach(bp => bp.destroy())
  }
}
<|endoftext|>


<commit_before>import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'

import FeaturedGene from './FeaturedGene'

const propTypes = {
  featuredGenes: PropTypes.object
}

const Layout = styled.div`
  padding-top: 1em;
  column-count: 3;
  column-gap: 2em;
`

const FeaturedGenes = ({ featuredGenes }) => {
  return (
    <Layout>
      {featuredGenes &&
        featuredGenes.genes.length > 0 &&
        featuredGenes.genes
          .map(featuredGene => (
            <FeaturedGene key={featuredGene.id} {...featuredGene} />
          ))
          .slice(0, 3)}
    </Layout>
  )
}

FeaturedGenes.propTypes = propTypes

export default FeaturedGenes
<commit_msg>Suppress featured thumbs at small sizes<commit_after>import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'

import FeaturedGene from './FeaturedGene'

const propTypes = {
  featuredGenes: PropTypes.object
}

const Layout = styled.div`
  display: none;

  @media (min-width: 768px) {
    display: block;
    padding-top: 1em;
    column-count: 3;
    column-gap: 2em;
  }
`

const FeaturedGenes = ({ featuredGenes }) => {
  return (
    <Layout>
      {featuredGenes &&
        featuredGenes.genes.length > 0 &&
        featuredGenes.genes
          .map(featuredGene => (
            <FeaturedGene key={featuredGene.id} {...featuredGene} />
          ))
          .slice(0, 3)}
    </Layout>
  )
}

FeaturedGenes.propTypes = propTypes

export default FeaturedGenes
<|endoftext|>


<commit_before>define([
], function(
) {
  'use strict';

  function getRefreshProvider(tasklistData) {
    return {
      refreshTaskList : function () {
        tasklistData.changed('taskList');
      }
    };
  }

  var operatorTable = {
    "<" : "lt",
    ">" : "gt",
    "=" : "eq",
    "!=": "neq",
    ">=": "gteq",
    "<=": "lteq",
    "like":"like",
    "BEFORE":"lteq",
    "AFTER":"gteq"
  };

  var typeTable = {
    "Process Variable" : "processVariables",
    "Task Variable" : "taskVariables",
    "Case Variable" : "caseInstanceVariables"
  };

  return [
    '$scope',
    '$q',
    '$location',
    '$interval',
    'search',
    'dataDepend',
    'camAPI',
  function(
    $scope,
    $q,
    $location,
    $interval,
    search,
    dataDepend,
    camAPI
  ) {

    function getPropertyFromLocation(property) {
      var search = $location.search() || {};
      return search[property] || null;
    }

    function updateSilently(params) {
      search.updateSilently(params);
    }

    $scope.$on('$destroy', function () {
      $scope.tasklistApp.refreshProvider = null;
    });

    // init data depend for task list data
    var tasklistData = $scope.tasklistData = dataDepend.create($scope);

    // init taslist app with a refresh provider
    if ($scope.tasklistApp) {
      $scope.tasklistApp.refreshProvider = getRefreshProvider(tasklistData);
    }

    // get current task id from location
    var taskId = getPropertyFromLocation('task');
    var detailsTab = getPropertyFromLocation('detailsTab');

    // resources
    var Filter = camAPI.resource('filter');
    var Task = camAPI.resource('task');

    // current selected filter
    var currentFilter;

    // provide /////////////////////////////////////////////////////////////////////////////////

    /**
     * Provides the list of filters
     */
    tasklistData.provide('filters', [ function() {
      var deferred = $q.defer();

      Filter.list({
        itemCount: false,
        resoureType: 'Task'
      }, function(err, res) {
        if(!!err) {
          deferred.reject(err);

        }
        else {
          deferred.resolve(res);
        }
      });

      return deferred.promise;
    }]);

    tasklistData.provide('currentFilter', ['filters', function(filters) {

      var focused,
          filterId = getPropertyFromLocation('filter');

      for (var i = 0, filter; !!(filter = filters[i]); i++) {

          if (filterId === filter.id) {
            focused = filter;
            break;
          }
          // auto focus first filter
          if(!focused || filter.properties.priority < focused.properties.priority) {
            focused = filter;
          }
      }
      if(currentFilter) {
        updateSilently({
          page: '1'
        });
      }

      if(focused && focused.id !== filterId) {
        updateSilently({
          filter: focused.id
        });
      }

      return angular.copy(focused);

    }]);

    tasklistData.provide('taskListQuery', ['currentFilter', function(currentFilter) {
      if (!currentFilter) {
        return null;
      }

      var querySearchParam = getPropertyFromLocation('query');
      var searches = JSON.parse(querySearchParam);

      var query = {};

      query.processVariables = [];
      query.taskVariables = [];
      query.caseInstanceVariables = [];

      angular.forEach(searches, function(search) {

         query[typeTable[search.type]].push({
           name: search.name,
           operator: operatorTable[search.operator],
           value: search.value
         });

      });

      var firstResult = (getPropertyFromLocation('page') - 1 || 0) * 15;
      var sortBy = getPropertyFromLocation('sortBy') || 'priority';
      var sortOrder = getPropertyFromLocation('sortOrder') || 'asc';

      return {
        id : currentFilter.id,
        firstResult : firstResult,
        maxResults : 15,
        sortBy : sortBy,
        sortOrder: sortOrder,
        active: true,
        processVariables : query.processVariables,
        taskVariables : query.taskVariables,
        caseInstanceVariables : query.caseInstanceVariables
      };

    }]);

     /**
      * Provide the list of tasks
      */
     tasklistData.provide('taskList', [ 'taskListQuery', function(taskListQuery) {
       var deferred = $q.defer();

       if(!taskListQuery || taskListQuery.id === null) {
         // no filter selected
         deferred.resolve({
           count: 0,
           _embedded : {}
         });
       }
       else {
         // filter selected
         Filter.getTasks(angular.copy(taskListQuery), function(err, res) {
           if(err) {
             deferred.reject(err);
           }
           else {
             deferred.resolve(res);
           }
         });
       }
       return deferred.promise;
     }]);

   /**
     * Provide current task id
     */
    tasklistData.provide('taskId', { 'taskId' : taskId });

    /**
     * Provide the current task or the value 'null' in case no task is selected
     */
    tasklistData.provide('task', ['taskId', function(task) {

      var deferred = $q.defer();

      var taskId = task.taskId;

      if(typeof taskId !== 'string') {
        deferred.resolve(null);
      }
      else {
        Task.get(taskId, function(err, res) {
          if(err) {
            deferred.reject(err);
          }
          else {
            deferred.resolve(res);
          }

        });
      }

      return deferred.promise;
    }]);

    // observe //////////////////////////////////////////////////////////////////////////////

    tasklistData.observe('currentFilter', function(_currentFilter) {
      currentFilter = _currentFilter;
    });

    /*
     * automatically refresh the taskList every 10 seconds so that changes
     * (such as claims) are represented in realtime
     */
    var intervalPromise;
    tasklistData.observe('currentFilter', function(currentFilter) {
      // stop current refresh
      if(intervalPromise) {
        $interval.cancel(intervalPromise);
      }

      if(currentFilter && currentFilter.properties.refresh) {
        intervalPromise = $interval(function(){

          if($scope.tasklistApp && $scope.tasklistApp.refreshProvider) {
            $scope.tasklistApp.refreshProvider.refreshTaskList();

          }
          else {
            $interval.cancel(intervalPromise);
          }

        }, 10000);
      }
    });

    // routeChanged listener ////////////////////////////////////////////////////////////////

    /**
     * Update task if location changes
     */
    $scope.$on('$routeChanged', function(prev, current) {
      var oldTaskId = taskId;
      var oldDetailsTab = detailsTab;

      taskId = getPropertyFromLocation('task');
      detailsTab = getPropertyFromLocation('detailsTab');

      if (oldTaskId !== taskId || oldDetailsTab === detailsTab) {
        tasklistData.set('taskId', { 'taskId' : taskId });
      }

      currentFilter = null;
      tasklistData.changed('currentFilter');

    });
  }];
});
<commit_msg>fix(tasklist): request first page if no page is specified<commit_after>define([
], function(
) {
  'use strict';

  function getRefreshProvider(tasklistData) {
    return {
      refreshTaskList : function () {
        tasklistData.changed('taskList');
      }
    };
  }

  var operatorTable = {
    "<" : "lt",
    ">" : "gt",
    "=" : "eq",
    "!=": "neq",
    ">=": "gteq",
    "<=": "lteq",
    "like":"like",
    "BEFORE":"lteq",
    "AFTER":"gteq"
  };

  var typeTable = {
    "Process Variable" : "processVariables",
    "Task Variable" : "taskVariables",
    "Case Variable" : "caseInstanceVariables"
  };

  return [
    '$scope',
    '$q',
    '$location',
    '$interval',
    'search',
    'dataDepend',
    'camAPI',
  function(
    $scope,
    $q,
    $location,
    $interval,
    search,
    dataDepend,
    camAPI
  ) {

    function getPropertyFromLocation(property) {
      var search = $location.search() || {};
      return search[property] || null;
    }

    function updateSilently(params) {
      search.updateSilently(params);
    }

    $scope.$on('$destroy', function () {
      $scope.tasklistApp.refreshProvider = null;
    });

    // init data depend for task list data
    var tasklistData = $scope.tasklistData = dataDepend.create($scope);

    // init taslist app with a refresh provider
    if ($scope.tasklistApp) {
      $scope.tasklistApp.refreshProvider = getRefreshProvider(tasklistData);
    }

    // get current task id from location
    var taskId = getPropertyFromLocation('task');
    var detailsTab = getPropertyFromLocation('detailsTab');

    // resources
    var Filter = camAPI.resource('filter');
    var Task = camAPI.resource('task');

    // current selected filter
    var currentFilter;

    // provide /////////////////////////////////////////////////////////////////////////////////

    /**
     * Provides the list of filters
     */
    tasklistData.provide('filters', [ function() {
      var deferred = $q.defer();

      Filter.list({
        itemCount: false,
        resoureType: 'Task'
      }, function(err, res) {
        if(!!err) {
          deferred.reject(err);

        }
        else {
          deferred.resolve(res);
        }
      });

      return deferred.promise;
    }]);

    tasklistData.provide('currentFilter', ['filters', function(filters) {

      var focused,
          filterId = getPropertyFromLocation('filter');

      for (var i = 0, filter; !!(filter = filters[i]); i++) {

          if (filterId === filter.id) {
            focused = filter;
            break;
          }
          // auto focus first filter
          if(!focused || filter.properties.priority < focused.properties.priority) {
            focused = filter;
          }
      }
      if(currentFilter) {
        updateSilently({
          page: '1'
        });
      }

      if(focused && focused.id !== filterId) {
        updateSilently({
          filter: focused.id
        });
      }

      return angular.copy(focused);

    }]);

    tasklistData.provide('taskListQuery', ['currentFilter', function(currentFilter) {
      if (!currentFilter) {
        return null;
      }

      var querySearchParam = getPropertyFromLocation('query');
      var searches = JSON.parse(querySearchParam);

      var query = {};

      query.processVariables = [];
      query.taskVariables = [];
      query.caseInstanceVariables = [];

      angular.forEach(searches, function(search) {

         query[typeTable[search.type]].push({
           name: search.name,
           operator: operatorTable[search.operator],
           value: search.value
         });

      });

      var firstResult = ((getPropertyFromLocation('page') || 1) - 1) * 15;
      var sortBy = getPropertyFromLocation('sortBy') || 'priority';
      var sortOrder = getPropertyFromLocation('sortOrder') || 'asc';

      return {
        id : currentFilter.id,
        firstResult : firstResult,
        maxResults : 15,
        sortBy : sortBy,
        sortOrder: sortOrder,
        active: true,
        processVariables : query.processVariables,
        taskVariables : query.taskVariables,
        caseInstanceVariables : query.caseInstanceVariables
      };

    }]);

     /**
      * Provide the list of tasks
      */
     tasklistData.provide('taskList', [ 'taskListQuery', function(taskListQuery) {
       var deferred = $q.defer();

       if(!taskListQuery || taskListQuery.id === null) {
         // no filter selected
         deferred.resolve({
           count: 0,
           _embedded : {}
         });
       }
       else {
         // filter selected
         Filter.getTasks(angular.copy(taskListQuery), function(err, res) {
           if(err) {
             deferred.reject(err);
           }
           else {
             deferred.resolve(res);
           }
         });
       }
       return deferred.promise;
     }]);

   /**
     * Provide current task id
     */
    tasklistData.provide('taskId', { 'taskId' : taskId });

    /**
     * Provide the current task or the value 'null' in case no task is selected
     */
    tasklistData.provide('task', ['taskId', function(task) {

      var deferred = $q.defer();

      var taskId = task.taskId;

      if(typeof taskId !== 'string') {
        deferred.resolve(null);
      }
      else {
        Task.get(taskId, function(err, res) {
          if(err) {
            deferred.reject(err);
          }
          else {
            deferred.resolve(res);
          }

        });
      }

      return deferred.promise;
    }]);

    // observe //////////////////////////////////////////////////////////////////////////////

    tasklistData.observe('currentFilter', function(_currentFilter) {
      currentFilter = _currentFilter;
    });

    /*
     * automatically refresh the taskList every 10 seconds so that changes
     * (such as claims) are represented in realtime
     */
    var intervalPromise;
    tasklistData.observe('currentFilter', function(currentFilter) {
      // stop current refresh
      if(intervalPromise) {
        $interval.cancel(intervalPromise);
      }

      if(currentFilter && currentFilter.properties.refresh) {
        intervalPromise = $interval(function(){

          if($scope.tasklistApp && $scope.tasklistApp.refreshProvider) {
            $scope.tasklistApp.refreshProvider.refreshTaskList();

          }
          else {
            $interval.cancel(intervalPromise);
          }

        }, 10000);
      }
    });

    // routeChanged listener ////////////////////////////////////////////////////////////////

    /**
     * Update task if location changes
     */
    $scope.$on('$routeChanged', function(prev, current) {
      var oldTaskId = taskId;
      var oldDetailsTab = detailsTab;

      taskId = getPropertyFromLocation('task');
      detailsTab = getPropertyFromLocation('detailsTab');

      if (oldTaskId !== taskId || oldDetailsTab === detailsTab) {
        tasklistData.set('taskId', { 'taskId' : taskId });
      }

      currentFilter = null;
      tasklistData.changed('currentFilter');

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


<commit_before>angular.module('ot.view.admin.health', [
    'ui.router',
    'ot.service.core'
])
    .config(function ($stateProvider) {
        $stateProvider.state('admin-health', {
            url: '/admin-health',
            templateUrl: 'app/view/view.admin.health.tpl.html',
            controller: 'AdminHealthCtrl'
        });
    })
    .controller('AdminHealthCtrl', function ($scope, $http, ot) {
        var view = ot.view();
        view.title = "System health";
        view.description = "Status of Ontrack system and configured resources";
        view.commands = [
            ot.viewCloseCommand('/home')
        ];

        // Loads the statuses
        function loadHealth() {
            ot.call($http.get('admin/status')).then(function (health) {
                $scope.health = health;
            });
        }

        // Initialisation
        loadHealth();

    })
;<commit_msg>#675 Correction of error display<commit_after>angular.module('ot.view.admin.health', [
    'ui.router',
    'ot.service.core'
])
    .config(function ($stateProvider) {
        $stateProvider.state('admin-health', {
            url: '/admin-health',
            templateUrl: 'app/view/view.admin.health.tpl.html',
            controller: 'AdminHealthCtrl'
        });
    })
    .controller('AdminHealthCtrl', function ($scope, $http, ot) {
        var view = ot.view();
        view.title = "System health";
        view.description = "Status of Ontrack system and configured resources";
        view.commands = [
            ot.viewCloseCommand('/home')
        ];

        // Loads the statuses
        function loadHealth() {
            ot.call($http.get('admin/status')).then(function (health) {
                $scope.health = health;
            });
        }

        // Show errors
        $scope.showError = function (config) {
            config.errorShown = true;
        };
        $scope.showDetails = function (config) {
            config.detailsShown = true;
        };

        // Initialisation
        loadHealth();

    })
;<|endoftext|>


<commit_before>/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @format
 */

/** @type {import('@docusaurus/types').DocusaurusConfig} */
module.exports = {
  title: 'Flow',
  tagline: 'A Static Type Checker for JavaScript',
  url: 'https://flow.org',
  baseUrl: '/',
  onBrokenLinks: 'throw',
  onBrokenMarkdownLinks: 'warn',
  favicon: 'img/favicon.png',
  organizationName: 'facebook', // Usually your GitHub org/user name.
  projectName: 'flow', // Usually your repo name.
  trailingSlash: true,
  plugins: [
    function polyfillNodeBuiltinsForFlowJS(context, options) {
      return {
        name: 'polyfillNodeBuiltinsForFlowJS',
        configureWebpack() {
          return {resolve: {fallback: {fs: false, constants: false}}};
        },
      };
    },
    function enableWasm() {
      return {
        name: 'enableWasm',
        configureWebpack() {
          return {
            experiments: {syncWebAssembly: true},
            module: {
              rules: [
                {
                  test: /\.wasm$/i,
                  loader: 'file-loader',
                  type: 'javascript/auto',
                },
              ],
            },
          };
        },
      };
    },
  ],
  themeConfig: {
    prism: {
      theme: require('prism-react-renderer/themes/github'),
    },
    navbar: {
      logo: {
        alt: 'My Facebook Project Logo',
        src: 'img/logo.svg',
      },
      items: [
        {
          to: 'docs/',
          activeBasePath: 'docs',
          label: 'Docs',
          position: 'left',
        },
        {
          to: 'try/',
          activeBasePath: 'try',
          label: 'Try',
          position: 'left',
        },
        {
          to: 'blog/',
          label: 'Blog',
          position: 'left',
        },
        {
          href: 'https://twitter.com/flowtype',
          'aria-label': 'Twitter',
          position: 'right',
          className: 'navbar__icon twitter__link',
        },
        {
          href: 'http://stackoverflow.com/questions/tagged/flowtype',
          'aria-label': 'Stack Overflow',
          position: 'right',
          className: 'navbar__icon stackoverflow__link',
        },
        // Please keep GitHub link to the right for consistency.
        {
          href: 'https://github.com/facebook/flow',
          'aria-label': 'GitHub',
          position: 'right',
          className: 'navbar__icon github__link',
        },
      ],
    },
    footer: {
      style: 'dark',
      links: [
        {
          title: 'Learn',
          items: [
            {
              label: 'Getting Started',
              to: 'docs/',
            },
          ],
        },
        {
          title: 'Community',
          items: [
            {
              label: 'Twitter',
              href: 'https://twitter.com/flowtype',
            },
            {
              label: 'Discord',
              href: 'https://discordapp.com/invite/8ezwRUK',
            },
          ],
        },
        {
          title: 'More',
          items: [
            {
              label: 'Medium',
              to: 'https://medium.com/flow-type',
            },
            {
              label: 'GitHub',
              href: 'https://github.com/facebook/flow',
            },
          ],
        },
        {
          title: 'Legal',
          // Please do not remove the privacy and terms, it's a legal requirement.
          items: [
            {
              label: 'Privacy',
              href: 'https://opensource.facebook.com/legal/privacy/',
            },
            {
              label: 'Terms',
              href: 'https://opensource.facebook.com/legal/terms/',
            },
            {
              label: 'Data Policy',
              href: 'https://opensource.facebook.com/legal/data-policy/',
            },
            {
              label: 'Cookie Policy',
              href: 'https://opensource.facebook.com/legal/cookie-policy/',
            },
          ],
        },
      ],
      logo: {
        alt: 'Facebook Open Source Logo',
        src: 'img/oss_logo.png',
        href: 'https://opensource.facebook.com',
      },
      // Please do not remove the credits, help to publicize Docusaurus :)
      copyright: `Copyright © ${new Date().getFullYear()} Facebook, Inc. Built with Docusaurus.`,
    },
  },
  customFields: {
    flowVersion: 'v0.193.0',
  },
  presets: [
    [
      '@docusaurus/preset-classic',
      {
        docs: {
          sidebarPath: require.resolve('./sidebars.js'),
          editUrl: 'https://github.com/facebook/flow/edit/main/new_website/',
          remarkPlugins: [
            [require('@docusaurus/remark-plugin-npm2yarn'), {sync: true}],
            require('./src/js/flow-check-remark-plugin'),
          ],
        },
        blog: {
          path: '../website/_posts',
          postsPerPage: 50,
          showReadingTime: false,
          blogSidebarCount: 'ALL',
          blogSidebarTitle: 'All our posts',
        },
        theme: {
          customCss: require.resolve('./src/css/custom.css'),
        },
      },
    ],
  ],
};
<commit_msg>[new_website] Disable dark mode<commit_after>/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @format
 */

/** @type {import('@docusaurus/types').DocusaurusConfig} */
module.exports = {
  title: 'Flow',
  tagline: 'A Static Type Checker for JavaScript',
  url: 'https://flow.org',
  baseUrl: '/',
  onBrokenLinks: 'throw',
  onBrokenMarkdownLinks: 'warn',
  favicon: 'img/favicon.png',
  organizationName: 'facebook', // Usually your GitHub org/user name.
  projectName: 'flow', // Usually your repo name.
  trailingSlash: true,
  plugins: [
    function polyfillNodeBuiltinsForFlowJS(context, options) {
      return {
        name: 'polyfillNodeBuiltinsForFlowJS',
        configureWebpack() {
          return {resolve: {fallback: {fs: false, constants: false}}};
        },
      };
    },
    function enableWasm() {
      return {
        name: 'enableWasm',
        configureWebpack() {
          return {
            experiments: {syncWebAssembly: true},
            module: {
              rules: [
                {
                  test: /\.wasm$/i,
                  loader: 'file-loader',
                  type: 'javascript/auto',
                },
              ],
            },
          };
        },
      };
    },
  ],
  themeConfig: {
    prism: {
      theme: require('prism-react-renderer/themes/github'),
    },
    colorMode: {
      defaultMode: 'light',
      disableSwitch: true,
      respectPrefersColorScheme: false,
    },
    navbar: {
      logo: {
        alt: 'My Facebook Project Logo',
        src: 'img/logo.svg',
      },
      items: [
        {
          to: 'docs/',
          activeBasePath: 'docs',
          label: 'Docs',
          position: 'left',
        },
        {
          to: 'try/',
          activeBasePath: 'try',
          label: 'Try',
          position: 'left',
        },
        {
          to: 'blog/',
          label: 'Blog',
          position: 'left',
        },
        {
          href: 'https://twitter.com/flowtype',
          'aria-label': 'Twitter',
          position: 'right',
          className: 'navbar__icon twitter__link',
        },
        {
          href: 'http://stackoverflow.com/questions/tagged/flowtype',
          'aria-label': 'Stack Overflow',
          position: 'right',
          className: 'navbar__icon stackoverflow__link',
        },
        // Please keep GitHub link to the right for consistency.
        {
          href: 'https://github.com/facebook/flow',
          'aria-label': 'GitHub',
          position: 'right',
          className: 'navbar__icon github__link',
        },
      ],
    },
    footer: {
      style: 'dark',
      links: [
        {
          title: 'Learn',
          items: [
            {
              label: 'Getting Started',
              to: 'docs/',
            },
          ],
        },
        {
          title: 'Community',
          items: [
            {
              label: 'Twitter',
              href: 'https://twitter.com/flowtype',
            },
            {
              label: 'Discord',
              href: 'https://discordapp.com/invite/8ezwRUK',
            },
          ],
        },
        {
          title: 'More',
          items: [
            {
              label: 'Medium',
              to: 'https://medium.com/flow-type',
            },
            {
              label: 'GitHub',
              href: 'https://github.com/facebook/flow',
            },
          ],
        },
        {
          title: 'Legal',
          // Please do not remove the privacy and terms, it's a legal requirement.
          items: [
            {
              label: 'Privacy',
              href: 'https://opensource.facebook.com/legal/privacy/',
            },
            {
              label: 'Terms',
              href: 'https://opensource.facebook.com/legal/terms/',
            },
            {
              label: 'Data Policy',
              href: 'https://opensource.facebook.com/legal/data-policy/',
            },
            {
              label: 'Cookie Policy',
              href: 'https://opensource.facebook.com/legal/cookie-policy/',
            },
          ],
        },
      ],
      logo: {
        alt: 'Facebook Open Source Logo',
        src: 'img/oss_logo.png',
        href: 'https://opensource.facebook.com',
      },
      // Please do not remove the credits, help to publicize Docusaurus :)
      copyright: `Copyright © ${new Date().getFullYear()} Facebook, Inc. Built with Docusaurus.`,
    },
  },
  customFields: {
    flowVersion: 'v0.193.0',
  },
  presets: [
    [
      '@docusaurus/preset-classic',
      {
        docs: {
          sidebarPath: require.resolve('./sidebars.js'),
          editUrl: 'https://github.com/facebook/flow/edit/main/new_website/',
          remarkPlugins: [
            [require('@docusaurus/remark-plugin-npm2yarn'), {sync: true}],
            require('./src/js/flow-check-remark-plugin'),
          ],
        },
        blog: {
          path: '../website/_posts',
          postsPerPage: 50,
          showReadingTime: false,
          blogSidebarCount: 'ALL',
          blogSidebarTitle: 'All our posts',
        },
        theme: {
          customCss: require.resolve('./src/css/custom.css'),
        },
      },
    ],
  ],
};
<|endoftext|>


<commit_before>/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

/*
 * Copyright (c) 2015, Joyent, Inc.
 */

/**
 * A Transform stream to apply changes to napi/portolan based on
 * incoming UFDS objects.
 */

var assert = require('assert-plus');
var NAPI = require('sdc-clients').NAPI;
var Transform = require('stream').Transform;
var util = require('util');
var uuid = require('node-uuid');
var vasync = require('vasync');

function DefaultFabricSetupStream(opts) {
    assert.object(opts, 'opts');
    assert.object(opts.log, 'opts.log');
    assert.object(opts.napi, 'opts.napi');
    assert.object(opts.default_vlan, 'opts.default_vlan');
    assert.string(opts.default_vlan.name, 'default vlan name');
    assert.number(opts.default_vlan.vlan_id, 'default vlan id');
    assert.object(opts.default_network, 'network');
    assert.string(opts.default_network.gateway, 'default gateway');
    assert.string(opts.default_network.name, 'default name');
    assert.string(opts.default_network.provision_start_ip, 'start_ip');
    assert.string(opts.default_network.provision_end_ip, 'end_ip');
    assert.string(opts.default_network.resolvers, 'resolvers');
    assert.number(opts.default_network.vlan_id, 'vlan_id');
    assert.number(opts.default_network.mtu, 'mtu');

    Transform.call(this, { objectMode: true });

    var self = this;

    self.log = opts.log.child({ component: 'DefaultFabricSetupStream' }, true);
    self.dead = false;

    self.napiClient = new NAPI(opts.napi);

    function findDefaultVlan(_opts, cb) {
        assert.object(_opts, '_opts');
        assert.string(_opts.uuid, 'uuid');
        assert.string(_opts.requestId, 'requestId');

        var reqOptions = { headers: { 'x-request-id': _opts.requestId }};

        self.napiClient.listFabricVLANs(_opts.uuid,
            reqOptions,
            function (err, vlans) {

            if (err) {
                return cb(err);
            }

            var defaultVlan = vlans.reduce(function (acc, v) {
                return acc || (v.name === opts.default_vlan.name ? v : null);
            }, null);

            if (defaultVlan) {
                self.log.info({ vlan: defaultVlan, user: _opts.uuid },
                    'Default vlan exists for user');
                _opts.defaultVlan = defaultVlan;
                return cb();
            }

            self.log.info({ user: _opts.uuid },
                'Default vlan does not exist for user');
            return cb();
        });
    }

    function createDefaultVlan(_opts, cb) {
        assert.object(_opts, '_opts');
        assert.string(_opts.uuid, 'uuid');
        assert.string(_opts.requestId, 'requestId');

        var reqOptions = { headers: { 'x-request-id': _opts.requestId }};

        if (_opts.defaultVlan) {
            return cb();
        }

        function create() {
            self.napiClient.createFabricVLAN(_opts.uuid,
                opts.default_vlan,
                reqOptions,
                function (_err, vlan) {
                var timeout = 10000;
                if (_err &&
                    _err.statusCode >= 500 && _err.statusCode < 600) {
                    self.log.error({ err: _err, user: _opts.uuid,
                        requestId: _opts.requestId },
                        'Server error creating vlan for user %s. ' +
                        'Retrying in %sms',
                        _opts.uuid, timeout);
                    setTimeout(create, timeout);
                    return;
                } else if (_err) {
                    self.log.error({ err: _err },
                        'Error creating fabric vlan for user');
                    return cb(_err);
                }
                _opts.defaultVlan = vlan;
                _opts.createdVlan = true;
                self.log.info({ vlan: vlan, user: _opts.uuid },
                    'Created default fabric vlan for user');
                return cb();
            });
        }
        create();
    }

    function findDefaultNetwork(_opts, cb) {
        assert.object(_opts, 'opts');
        assert.string(_opts.uuid, 'uuid');
        assert.string(_opts.requestId, 'requestId');

        var reqOptions = { headers: { 'x-request-id': _opts.requestId }};

        self.napiClient.listFabricNetworks(_opts.uuid,
            opts.default_network.vlan_id,
            reqOptions,
            function (err, networks) {
            var defaultNetwork;
            if (err) {
                self.log.error({ err: err, user: _opts.uuid,
                    requestId: _opts.requestId },
                    'Error creating default fabric network for user');
                return cb(err);
            }
            // XXX - this network is not necessarily the right one.
            defaultNetwork = networks.reduce(function (acc, n) {
                return n.name === opts.default_network.name ? n : null;
            }, null);
            if (defaultNetwork) {
                self.log.info({ network: defaultNetwork, user: _opts.uuid,
                    requestId: _opts.requestId },
                    'Default network exists for user',
                    defaultNetwork.uuid, _opts.uuid);
                _opts.defaultNetwork = defaultNetwork;
                return cb();
            }

            self.log.info({ user: _opts.uuid },
                'Default network does not exist for user');
            return cb();
        });
    }

    function createDefaultNetwork(_opts, cb) {
        assert.object(_opts, 'opts');
        assert.string(_opts.uuid, 'uuid');
        assert.string(_opts.requestId, 'requestId');

        var reqOptions = { headers: { 'x-request-id': _opts.requestId }};

        if (_opts.defaultNetwork) {
            return cb();
        }

        function create() {
            self.napiClient.createFabricNetwork(_opts.uuid,
                opts.default_network.vlan_id, opts.default_network,
                reqOptions,
                function (_err, network) {
                    var timeout = 10000;
                    if (_err &&
                        _err.statusCode >= 500 && _err.statusCode < 600) {
                        self.log.warn({ err: _err },
                            'Server error creating network for user %s. ' +
                            'Retrying in %sms',
                            _opts.uuid, timeout);
                        setTimeout(create, timeout);
                        return;
                    } else if (_err) {
                        self.log.error({ err: _err, user: _opts.uuid },
                            'Error creating network for user %s',
                            _opts.uuid);
                        return cb(_err);
                    }
                    self.log.info({ network: network, user: _opts.uuid },
                        'create default network %s for user %s',
                        network.uuid, _opts.uuid);
                    _opts.defaultNetwork = network;
                    _opts.createdNetwork = true;
                    return cb();
                });
        }
        create();
    }

    // expects objs like:
    // {
    //     user: { UFDS user },
    //     changenumber: 12,
    //     requestId: UUID
    // }
    function napiWorker(obj, cb) {
        assert.string(obj.user.uuid, 'user uuid');
        assert.string(obj.requestId, 'requestId');

        var msg;

        if (self.dead) {
            return cb();
        }

        self.log.debug({ user: obj.user }, 'Adding network for user');

        var arg = {
            uuid: obj.user.uuid,
            requestId: obj.requestId
        };

        vasync.pipeline({
            arg: arg,
            funcs: [
                findDefaultVlan,
                createDefaultVlan,
                findDefaultNetwork,
                createDefaultNetwork
            ]
        }, function (err, results) {
            if (err) {
                return cb(err);
            }
            obj.vlan = arg.defaultVlan;
            obj.network = arg.defaultNetwork;
            if (obj.createdNetwork || obj.createdVlan) {
                msg = 'created default overlay for user';
            } else {
                msg = 'found existing default overlay for user';
            }
            self.log.info({ obj: obj }, msg);
            self.push(obj);

            return cb();
        });
    }

    this.napiQueue = vasync.queue(wrapWorker(napiWorker), 10);
}
util.inherits(DefaultFabricSetupStream, Transform);
module.exports = DefaultFabricSetupStream;

// wraps a stream object such that it calls the stream cb when the task
// is started by vasync.queue
function wrapTask(obj, streamCb) {
    return function task() {
        streamCb();
        return obj;
    };
}

// wraps a typical vasync.queue worker to call a stream callback
function wrapWorker(workerFunc) {
    return function worker(wrappedObj, cb) {
        workerFunc(wrappedObj(), cb);
    };
}

DefaultFabricSetupStream.prototype._transform =
function _transform(obj, _, cb) {
    var self = this;

    if (self.dead) {
        return cb();
    }

    self.napiQueue.push(wrapTask(obj, cb), function (err) {
        // TODO: emit error here?

        if (err) {
            // does error/failure here depend on the type of error?
            // this is the appropriate level of encapsulation.
            self.emit('failure', err, obj);

            // most errors imply failure as well
            // some errors are 'success' at least that we don't want
            // to repeat - typically pass those through.
        }

        self.log.debug({ npending: self.napiQueue.npending,
        queued: self.napiQueue.queued.length },
        'finish: napiQueue has %d tasks running, %d queued',
        self.napiQueue.npending, self.napiQueue.queued.length);
    });
    self.log.debug({ npending: self.napiQueue.npending,
        queued: self.napiQueue.queued.length },
        'pushed: napiQueue has %d tasks running, %d queued',
        self.napiQueue.npending, self.napiQueue.queued.length);
};

DefaultFabricSetupStream.prototype.close = function close() {
    var self = this;
    self.log.debug('close: entered');
    if (self.dead) {
        setImmediate(self.emit.bind(self, 'close'));
        return;
    }

    self.dead = true;
    self.push(null);
    self.emit('close');

    self.log.debug('close: done');
};
<commit_msg>NET-330 watcher mistakenly passes headers as query parameters Reviewed by: Joshua M. Clulow <jmc@joyent.com><commit_after>/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

/*
 * Copyright (c) 2015, Joyent, Inc.
 */

/**
 * A Transform stream to apply changes to napi/portolan based on
 * incoming UFDS objects.
 */

var assert = require('assert-plus');
var NAPI = require('sdc-clients').NAPI;
var Transform = require('stream').Transform;
var util = require('util');
var uuid = require('node-uuid');
var vasync = require('vasync');

function DefaultFabricSetupStream(opts) {
    assert.object(opts, 'opts');
    assert.object(opts.log, 'opts.log');
    assert.object(opts.napi, 'opts.napi');
    assert.object(opts.default_vlan, 'opts.default_vlan');
    assert.string(opts.default_vlan.name, 'default vlan name');
    assert.number(opts.default_vlan.vlan_id, 'default vlan id');
    assert.object(opts.default_network, 'network');
    assert.string(opts.default_network.gateway, 'default gateway');
    assert.string(opts.default_network.name, 'default name');
    assert.string(opts.default_network.provision_start_ip, 'start_ip');
    assert.string(opts.default_network.provision_end_ip, 'end_ip');
    assert.string(opts.default_network.resolvers, 'resolvers');
    assert.number(opts.default_network.vlan_id, 'vlan_id');
    assert.number(opts.default_network.mtu, 'mtu');

    Transform.call(this, { objectMode: true });

    var self = this;

    self.log = opts.log.child({ component: 'DefaultFabricSetupStream' }, true);
    self.dead = false;

    self.napiClient = new NAPI(opts.napi);

    function findDefaultVlan(_opts, cb) {
        assert.object(_opts, '_opts');
        assert.string(_opts.uuid, 'uuid');
        assert.string(_opts.requestId, 'requestId');

        var reqOptions = { headers: { 'x-request-id': _opts.requestId }};

        self.napiClient.listFabricVLANs(_opts.uuid,
            reqOptions,
            function (err, vlans) {

            if (err) {
                return cb(err);
            }

            var defaultVlan = vlans.reduce(function (acc, v) {
                return acc || (v.name === opts.default_vlan.name ? v : null);
            }, null);

            if (defaultVlan) {
                self.log.info({ vlan: defaultVlan, user: _opts.uuid },
                    'Default vlan exists for user');
                _opts.defaultVlan = defaultVlan;
                return cb();
            }

            self.log.info({ user: _opts.uuid },
                'Default vlan does not exist for user');
            return cb();
        });
    }

    function createDefaultVlan(_opts, cb) {
        assert.object(_opts, '_opts');
        assert.string(_opts.uuid, 'uuid');
        assert.string(_opts.requestId, 'requestId');

        var reqOptions = { headers: { 'x-request-id': _opts.requestId }};

        if (_opts.defaultVlan) {
            return cb();
        }

        function create() {
            self.napiClient.createFabricVLAN(_opts.uuid,
                opts.default_vlan,
                reqOptions,
                function (_err, vlan) {
                var timeout = 10000;
                if (_err &&
                    _err.statusCode >= 500 && _err.statusCode < 600) {
                    self.log.error({ err: _err, user: _opts.uuid,
                        requestId: _opts.requestId },
                        'Server error creating vlan for user %s. ' +
                        'Retrying in %sms',
                        _opts.uuid, timeout);
                    setTimeout(create, timeout);
                    return;
                } else if (_err) {
                    self.log.error({ err: _err },
                        'Error creating fabric vlan for user');
                    return cb(_err);
                }
                _opts.defaultVlan = vlan;
                _opts.createdVlan = true;
                self.log.info({ vlan: vlan, user: _opts.uuid },
                    'Created default fabric vlan for user');
                return cb();
            });
        }
        create();
    }

    function findDefaultNetwork(_opts, cb) {
        assert.object(_opts, 'opts');
        assert.string(_opts.uuid, 'uuid');
        assert.string(_opts.requestId, 'requestId');

        var reqOptions = { headers: { 'x-request-id': _opts.requestId }};

        self.napiClient.listFabricNetworks(_opts.uuid,
            opts.default_network.vlan_id,
            {},
            reqOptions,
            function (err, networks) {
            var defaultNetwork;
            if (err) {
                self.log.error({ err: err, user: _opts.uuid,
                    requestId: _opts.requestId },
                    'Error creating default fabric network for user');
                return cb(err);
            }
            // XXX - this network is not necessarily the right one.
            defaultNetwork = networks.reduce(function (acc, n) {
                return n.name === opts.default_network.name ? n : null;
            }, null);
            if (defaultNetwork) {
                self.log.info({ network: defaultNetwork, user: _opts.uuid,
                    requestId: _opts.requestId },
                    'Default network exists for user',
                    defaultNetwork.uuid, _opts.uuid);
                _opts.defaultNetwork = defaultNetwork;
                return cb();
            }

            self.log.info({ user: _opts.uuid },
                'Default network does not exist for user');
            return cb();
        });
    }

    function createDefaultNetwork(_opts, cb) {
        assert.object(_opts, 'opts');
        assert.string(_opts.uuid, 'uuid');
        assert.string(_opts.requestId, 'requestId');

        var reqOptions = { headers: { 'x-request-id': _opts.requestId }};

        if (_opts.defaultNetwork) {
            return cb();
        }

        function create() {
            self.napiClient.createFabricNetwork(_opts.uuid,
                opts.default_network.vlan_id, opts.default_network,
                reqOptions,
                function (_err, network) {
                    var timeout = 10000;
                    if (_err &&
                        _err.statusCode >= 500 && _err.statusCode < 600) {
                        self.log.warn({ err: _err },
                            'Server error creating network for user %s. ' +
                            'Retrying in %sms',
                            _opts.uuid, timeout);
                        setTimeout(create, timeout);
                        return;
                    } else if (_err) {
                        self.log.error({ err: _err, user: _opts.uuid },
                            'Error creating network for user %s',
                            _opts.uuid);
                        return cb(_err);
                    }
                    self.log.info({ network: network, user: _opts.uuid },
                        'create default network %s for user %s',
                        network.uuid, _opts.uuid);
                    _opts.defaultNetwork = network;
                    _opts.createdNetwork = true;
                    return cb();
                });
        }
        create();
    }

    // expects objs like:
    // {
    //     user: { UFDS user },
    //     changenumber: 12,
    //     requestId: UUID
    // }
    function napiWorker(obj, cb) {
        assert.string(obj.user.uuid, 'user uuid');
        assert.string(obj.requestId, 'requestId');

        var msg;

        if (self.dead) {
            return cb();
        }

        self.log.debug({ user: obj.user }, 'Adding network for user');

        var arg = {
            uuid: obj.user.uuid,
            requestId: obj.requestId
        };

        vasync.pipeline({
            arg: arg,
            funcs: [
                findDefaultVlan,
                createDefaultVlan,
                findDefaultNetwork,
                createDefaultNetwork
            ]
        }, function (err, results) {
            if (err) {
                return cb(err);
            }
            obj.vlan = arg.defaultVlan;
            obj.network = arg.defaultNetwork;
            if (obj.createdNetwork || obj.createdVlan) {
                msg = 'created default overlay for user';
            } else {
                msg = 'found existing default overlay for user';
            }
            self.log.info({ obj: obj }, msg);
            self.push(obj);

            return cb();
        });
    }

    this.napiQueue = vasync.queue(wrapWorker(napiWorker), 10);
}
util.inherits(DefaultFabricSetupStream, Transform);
module.exports = DefaultFabricSetupStream;

// wraps a stream object such that it calls the stream cb when the task
// is started by vasync.queue
function wrapTask(obj, streamCb) {
    return function task() {
        streamCb();
        return obj;
    };
}

// wraps a typical vasync.queue worker to call a stream callback
function wrapWorker(workerFunc) {
    return function worker(wrappedObj, cb) {
        workerFunc(wrappedObj(), cb);
    };
}

DefaultFabricSetupStream.prototype._transform =
function _transform(obj, _, cb) {
    var self = this;

    if (self.dead) {
        return cb();
    }

    self.napiQueue.push(wrapTask(obj, cb), function (err) {
        // TODO: emit error here?

        if (err) {
            // does error/failure here depend on the type of error?
            // this is the appropriate level of encapsulation.
            self.emit('failure', err, obj);

            // most errors imply failure as well
            // some errors are 'success' at least that we don't want
            // to repeat - typically pass those through.
        }

        self.log.debug({ npending: self.napiQueue.npending,
        queued: self.napiQueue.queued.length },
        'finish: napiQueue has %d tasks running, %d queued',
        self.napiQueue.npending, self.napiQueue.queued.length);
    });
    self.log.debug({ npending: self.napiQueue.npending,
        queued: self.napiQueue.queued.length },
        'pushed: napiQueue has %d tasks running, %d queued',
        self.napiQueue.npending, self.napiQueue.queued.length);
};

DefaultFabricSetupStream.prototype.close = function close() {
    var self = this;
    self.log.debug('close: entered');
    if (self.dead) {
        setImmediate(self.emit.bind(self, 'close'));
        return;
    }

    self.dead = true;
    self.push(null);
    self.emit('close');

    self.log.debug('close: done');
};
<|endoftext|>