<commit_before>var io = require('./io');
var modm = require('modm');

// TODO let the user define this configs
var config = {
    dbName: 'dms', // TODO handle with datasources
    templateId: modm.ObjectId('000000000000000000000000'), // TODO handle with datasources
    roleTemplateId: modm.ObjectId('000000000000000000000002'),
    templateColName: 'd_templates', // TODO handle with datasources
    templateSchema: {
        _id: {type: 'objectid'},
        _tp: {type: 'objectid', required: true},
        _li: {type: 'array'},
        db: {type: 'string', required: true},
        collection: {type: 'string', required: true},
        name: {type: 'string', required: true},
        roles: {type: 'object', required: true},
        schema: {type: 'object', required: true},
        label: {type: 'string'},
        links: {type: 'array'},
        options: {type: 'object'}
    }
};

var templateSchema = new modm.Schema(config.templateSchema);

// template cache
var templateCache = {
    // template's template must be in the cache, otherwise
    // it's impossible to create the first template item
    '000000000000000000000000': {
        _id: modm.ObjectId('000000000000000000000000'),
        label: 'Templates',
        db: config.dbName,
        collection: config.templateColName,
        schema: templateSchema,
        itemAccess: 'crud',
        roles: {
            '*': {
                access: 'r'
            }
        },
        model: modm(config.dbName, {
            server: {pooSize: 3},
            db: {w: 1}
        })
    }

    // TODO move all core tempaltes to crud module
};
// init collection
templateCache[config.templateId].collection = templateCache[config.templateId].model(config.templateColName, templateSchema);

function ObjectId (id) {
    try {
        return modm.ObjectId(id);
    } catch (err) {
        return null;
    }
}

function getAccessKey (method) {
    switch (method) {
        case 'find':
            return 'r';
        case 'update':
            return 'u';
        case 'insert':
            return 'c';
        case 'remove':
            return 'd';
    }
}

// check access
function checkAccess (template, role, method) {

    // grant access for templates without roles or for the role wildcard
    if (!template.roles || (template.roles['*'] && typeof template.roles['*'].access === 'string' && template.roles['*'].access.indexOf(getAccessKey(method)) > -1)) {
        return true;
    }

    // check if role has read rights
    if (template.roles[role] && typeof template.roles[role].access === 'string' && template.roles[role].access.indexOf(getAccessKey(method)) > -1) {
        return true;
    }

    return false;
}

function initAndCache (template) {

    if (typeof template.db !== 'string') {
        return;
    };

    template.model = modm(template.db, {
        server: {pooSize: 3},
        db: {w: 1}
    });

    // add mandatory field _tp
    template.schema._tp = {
        type: 'objectid',
        required: true
    };

    // add mandatory field _id
    template.schema._id = {
        type: 'objectid',
        required: true
    };

    template.schema = new modm.Schema(template.schema);
    template.collection = template.model(template.collection, template.schema);
    return templateCache[template._id] = template;
}

function getCachedTemplates (templates, role, method) {

    if (!templates || templates.length === 0) {
        return;
    }

    var resultTemplates = {};
    var queryTemplates = [];
    var addedTemplates = {};

    if (templates && templates.length > 0) {
        // check cached templates
        for (var i = 0, l = templates.length; i < l; ++i) {
            // add to result if role has access
            if (templateCache[templates[i]] && checkAccess(templateCache[templates[i]], role, method)) {
                resultTemplates[templates[i]] = templateCache[templates[i]];
            } else if (!addedTemplates[templates[i]]) {
                addedTemplates[templates[i]] = true;
                queryTemplates.push(templates[i]);
            }
        }
    }

    return {
        query: queryTemplates,
        cached: resultTemplates
    }
}

function fetchTemplatesFromDb (templates, role, fields, method, callback) {

    var tpls = getCachedTemplates(templates, role, method);
    var resultTemplates = {};

    // build query
    var dbReq = {
        query: {_tp: config.templateId},
        options: {
            fields: fields || {},
            limit: templates.length
        },
        template: templateCache[config.templateId]
    };

    if (tpls) {
        var templates = tpls.query;
        resultTemplates = tpls.cached;

        dbReq.query['roles.' + role + '.access'] = {$regex: getAccessKey(method)};

        if (templates.length > 1) {

            dbReq.query._id = {$in: []};
            dbReq.options.limit = templates.length;

            for (var i = 0, l = templates.length; i < l; ++i) {
                templates[i] = ObjectId(templates[i]);
                if (!templates[i]) {
                    var err = new Error('Invalid templates.');
                    err.statusCode = 400;
                    return callback(err);
                }

                dbReq.query._id.$in.push(templates[i]);
            }
        } else if (templates.length > 0) {

            if (templates[0] = ObjectId(templates[0])) {
                dbReq.options.limit = 1;
                dbReq.query._id = templates[0];
            } else {
                var err = new Error('Invalid templates.');
                err.statusCode = 400;
                return callback(err);
            }
        }
    }

    if (!tpls || tpls.query.length > 0) {

        io.find(null, dbReq, function (err, cursor) {

            if (err) {
                err.statusCode = 500;
                return callback(err);
            }

            if (!cursor) {
                var err = new Error('Templates not found.');
                err.statusCode = 404;
                return callback(err);
            }

            cursor.toArray(function (err, templates) {

                if (err) {
                    err.statusCode = 500;
                    return callback(err);
                }

                if (!templates || templates.length === 0) {
                    var err = new Error('Templates not found.');
                    err.statusCode = 404;
                    return callback(err);
                }

                for (var i = 0, l = templates.length; i < l; ++i) {
                    var temp = initAndCache(templates[i]);
                    if (temp) {
                        resultTemplates[templates[i]._id] = temp;
                    }
                }

                callback(null, resultTemplates);
            });
        });
    } else {
        callback(null, tpls.cached);
    }
}

function getTemplate (request, callback) {

    fetchTemplatesFromDb([request.templateId], request.role, {}, request.method, function (err, template) {

        if (err) {
            err.statusCode = err.statusCode || 500;
            return callback(err);
        }

        request.template = template[request.templateId];

        if (!request.template) {
            err = new Error('No right to access template ' + request.templateId + ' with the "' + request.method + '" method.');
            err.statusCode = 500;
            return callback(err);
        }

        callback(null, request);
    });
}

function getMergeTemplates (templates, role, callback) {

    fetchTemplatesFromDb(templates, role, {}, 'find', function (err, templates) {

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

        callback(null, templates);
    });
}

function getTemplates (templates, role, callback) {

    var myRoleString = role ? role.toString() : '';

    fetchTemplatesFromDb(templates, role, {}, 'find', function (err, templates) {

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

        var result = {};
        for (var id in templates) {

            result[id] = {
                id: templates[id]._id,
                //name: templates[id].name,
                schema: templates[id].schema.paths
            };

            // let the UI template information go through
            var uiElems = ['label', 'html', 'filters', 'sort'];
            for (var i in uiElems) {
                if ((templates[id].options || {})[uiElems[i]]) {
                    result[id].options = result[id].options || {};
                    result[id].options[uiElems[i]] = templates[id].options[uiElems[i]];
                }
            }
            result[id].links = templates[id].links;
        }

        callback(null, result);
    });
}

M.on('crud_getTemplate', getTemplate);

exports.getTemplate = getTemplate;
exports.getTemplates = getTemplates;
exports.getMergeTemplates = getMergeTemplates;
exports.getAccessKey = getAccessKey;
<commit_msg>added _li core schema field<commit_after>var io = require('./io');
var modm = require('modm');

// TODO let the user define this configs
var config = {
    dbName: 'dms', // TODO handle with datasources
    templateId: modm.ObjectId('000000000000000000000000'), // TODO handle with datasources
    roleTemplateId: modm.ObjectId('000000000000000000000002'),
    templateColName: 'd_templates', // TODO handle with datasources
    templateSchema: {
        _id: {type: 'objectid'},
        _tp: {type: 'objectid', required: true},
        _li: {type: 'array'},
        db: {type: 'string', required: true},
        collection: {type: 'string', required: true},
        name: {type: 'string', required: true},
        roles: {type: 'object', required: true},
        schema: {type: 'object', required: true},
        label: {type: 'string'},
        links: {type: 'array'},
        options: {type: 'object'}
    }
};

var templateSchema = new modm.Schema(config.templateSchema);

// template cache
var templateCache = {
    // template's template must be in the cache, otherwise
    // it's impossible to create the first template item
    '000000000000000000000000': {
        _id: modm.ObjectId('000000000000000000000000'),
        label: 'Templates',
        db: config.dbName,
        collection: config.templateColName,
        schema: templateSchema,
        itemAccess: 'crud',
        roles: {
            '*': {
                access: 'r'
            }
        },
        model: modm(config.dbName, {
            server: {pooSize: 3},
            db: {w: 1}
        })
    }

    // TODO move all core tempaltes to crud module
};
// init collection
templateCache[config.templateId].collection = templateCache[config.templateId].model(config.templateColName, templateSchema);

function ObjectId (id) {
    try {
        return modm.ObjectId(id);
    } catch (err) {
        return null;
    }
}

function getAccessKey (method) {
    switch (method) {
        case 'find':
            return 'r';
        case 'update':
            return 'u';
        case 'insert':
            return 'c';
        case 'remove':
            return 'd';
    }
}

// check access
function checkAccess (template, role, method) {

    // grant access for templates without roles or for the role wildcard
    if (!template.roles || (template.roles['*'] && typeof template.roles['*'].access === 'string' && template.roles['*'].access.indexOf(getAccessKey(method)) > -1)) {
        return true;
    }

    // check if role has read rights
    if (template.roles[role] && typeof template.roles[role].access === 'string' && template.roles[role].access.indexOf(getAccessKey(method)) > -1) {
        return true;
    }

    return false;
}

function initAndCache (template) {

    if (typeof template.db !== 'string') {
        return;
    };

    template.model = modm(template.db, {
        server: {pooSize: 3},
        db: {w: 1}
    });

    // add mandatory field _tp
    template.schema._tp = {
        type: 'objectid',
        required: true
    };

    // add mandatory field _id
    template.schema._id = {
        type: 'objectid',
        required: true
    };

    // add mandatory field _id
    template.schema._li = {
        type: 'array'
    };

    template.schema = new modm.Schema(template.schema);
    template.collection = template.model(template.collection, template.schema);
    return templateCache[template._id] = template;
}

function getCachedTemplates (templates, role, method) {

    if (!templates || templates.length === 0) {
        return;
    }

    var resultTemplates = {};
    var queryTemplates = [];
    var addedTemplates = {};

    if (templates && templates.length > 0) {
        // check cached templates
        for (var i = 0, l = templates.length; i < l; ++i) {
            // add to result if role has access
            if (templateCache[templates[i]] && checkAccess(templateCache[templates[i]], role, method)) {
                resultTemplates[templates[i]] = templateCache[templates[i]];
            } else if (!addedTemplates[templates[i]]) {
                addedTemplates[templates[i]] = true;
                queryTemplates.push(templates[i]);
            }
        }
    }

    return {
        query: queryTemplates,
        cached: resultTemplates
    }
}

function fetchTemplatesFromDb (templates, role, fields, method, callback) {

    var tpls = getCachedTemplates(templates, role, method);
    var resultTemplates = {};

    // build query
    var dbReq = {
        query: {_tp: config.templateId},
        options: {
            fields: fields || {},
            limit: templates.length
        },
        template: templateCache[config.templateId]
    };

    if (tpls) {
        var templates = tpls.query;
        resultTemplates = tpls.cached;

        dbReq.query['roles.' + role + '.access'] = {$regex: getAccessKey(method)};

        if (templates.length > 1) {

            dbReq.query._id = {$in: []};
            dbReq.options.limit = templates.length;

            for (var i = 0, l = templates.length; i < l; ++i) {
                templates[i] = ObjectId(templates[i]);
                if (!templates[i]) {
                    var err = new Error('Invalid templates.');
                    err.statusCode = 400;
                    return callback(err);
                }

                dbReq.query._id.$in.push(templates[i]);
            }
        } else if (templates.length > 0) {

            if (templates[0] = ObjectId(templates[0])) {
                dbReq.options.limit = 1;
                dbReq.query._id = templates[0];
            } else {
                var err = new Error('Invalid templates.');
                err.statusCode = 400;
                return callback(err);
            }
        }
    }

    if (!tpls || tpls.query.length > 0) {

        io.find(null, dbReq, function (err, cursor) {

            if (err) {
                err.statusCode = 500;
                return callback(err);
            }

            if (!cursor) {
                var err = new Error('Templates not found.');
                err.statusCode = 404;
                return callback(err);
            }

            cursor.toArray(function (err, templates) {

                if (err) {
                    err.statusCode = 500;
                    return callback(err);
                }

                if (!templates || templates.length === 0) {
                    var err = new Error('Templates not found.');
                    err.statusCode = 404;
                    return callback(err);
                }

                for (var i = 0, l = templates.length; i < l; ++i) {
                    var temp = initAndCache(templates[i]);
                    if (temp) {
                        resultTemplates[templates[i]._id] = temp;
                    }
                }

                callback(null, resultTemplates);
            });
        });
    } else {
        callback(null, tpls.cached);
    }
}

function getTemplate (request, callback) {

    fetchTemplatesFromDb([request.templateId], request.role, {}, request.method, function (err, template) {

        if (err) {
            err.statusCode = err.statusCode || 500;
            return callback(err);
        }

        request.template = template[request.templateId];

        if (!request.template) {
            err = new Error('No right to access template ' + request.templateId + ' with the "' + request.method + '" method.');
            err.statusCode = 500;
            return callback(err);
        }

        callback(null, request);
    });
}

function getMergeTemplates (templates, role, callback) {

    fetchTemplatesFromDb(templates, role, {}, 'find', function (err, templates) {

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

        callback(null, templates);
    });
}

function getTemplates (templates, role, callback) {

    var myRoleString = role ? role.toString() : '';

    fetchTemplatesFromDb(templates, role, {}, 'find', function (err, templates) {

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

        var result = {};
        for (var id in templates) {

            result[id] = {
                id: templates[id]._id,
                //name: templates[id].name,
                schema: templates[id].schema.paths
            };

            // let the UI template information go through
            var uiElems = ['label', 'html', 'filters', 'sort'];
            for (var i in uiElems) {
                if ((templates[id].options || {})[uiElems[i]]) {
                    result[id].options = result[id].options || {};
                    result[id].options[uiElems[i]] = templates[id].options[uiElems[i]];
                }
            }
            result[id].links = templates[id].links;
        }

        callback(null, result);
    });
}

M.on('crud_getTemplate', getTemplate);

exports.getTemplate = getTemplate;
exports.getTemplates = getTemplates;
exports.getMergeTemplates = getMergeTemplates;
exports.getAccessKey = getAccessKey;
<|endoftext|>


<commit_before>class ProcessSettings2CompositionComponentController {
    /*@ngInject*/
    constructor(experimentsService, toast, $stateParams) {
        this.experimentsService = experimentsService;
        this.toast = toast;
        this.$stateParams = $stateParams;
        this.projectId = $stateParams.project_id;
        this.experimentId = $stateParams.experiment_id;
    }

    updateSettingProperty(property) {

        if (!property.value) {
            console.log("No value -> ", property);
            return;
        }

        if (property.otype != "string") {
            console.log("Not a string -> ", property);
            return;
        }

        property.setup_attribute = this.attribute;
        let propertyArgs = {
            template_id: this.templateId,
            properties: [property]
        };

        this.experimentsService.updateProcess(this.projectId, this.experimentId, this.processId, propertyArgs)
            .then(
                () => null,
                () => this.toast.error('Unable to update property')
            );
    }
}

angular.module('materialscommons').component('processSettings2Composition', {
    templateUrl: 'app/global.components/process/process-settings2-composition.html',
    controller: ProcessSettings2CompositionComponentController,
    bindings: {
        setting: '<',
        templateId: '<',
        attribute: '<',
        processId: '<'
    }
});
<commit_msg>minor fix on Composition component for settings<commit_after>class ProcessSettings2CompositionComponentController {
    /*@ngInject*/
    constructor(experimentsService, toast, $stateParams) {
        this.experimentsService = experimentsService;
        this.toast = toast;
        this.$stateParams = $stateParams;
        this.projectId = $stateParams.project_id;
        this.experimentId = $stateParams.experiment_id;
    }

    updateSettingProperty(property) {

        if (!property.value) {
            console.log("No value -> ", property);
            return;
        }

        if (property.otype != "composition") {
            console.log("Not a composition -> ", property);
            return;
        }

        property.setup_attribute = this.attribute;
        let propertyArgs = {
            template_id: this.templateId,
            properties: [property]
        };

        this.experimentsService.updateProcess(this.projectId, this.experimentId, this.processId, propertyArgs)
            .then(
                () => null,
                () => this.toast.error('Unable to update property')
            );
    }
}

angular.module('materialscommons').component('processSettings2Composition', {
    templateUrl: 'app/global.components/process/process-settings2-composition.html',
    controller: ProcessSettings2CompositionComponentController,
    bindings: {
        setting: '<',
        templateId: '<',
        attribute: '<',
        processId: '<'
    }
});
<|endoftext|>


<commit_before>/**
 * Created by knut on 14-12-20.
 */
//var log = require('../../logger').create();
exports.drawRect = function(elem , rectData){
    var rectElem = elem.append('rect');
    rectElem.attr('x', rectData.x);
    rectElem.attr('y', rectData.y);
    rectElem.attr('fill', rectData.fill);
    rectElem.attr('stroke', rectData.stroke);
    rectElem.attr('width', rectData.width);
    rectElem.attr('height', rectData.height);
    rectElem.attr('rx', rectData.rx);
    rectElem.attr('ry', rectData.ry);

    if(typeof rectData.class !== 'undefined'){
        rectElem.attr('class', rectData.class);
    }

    return rectElem;
};

exports.drawText = function(elem, textData, width) {
    // Remove and ignore br:s
    var nText = textData.text.replace(/<br\/?>/ig,' ');

    var textElem = elem.append('text');
    textElem.attr('x', textData.x);
    textElem.attr('y', textData.y);
    textElem.style('text-anchor', textData.anchor);
    textElem.attr('fill', textData.fill);
    if (typeof textData.class !== 'undefined') {
        textElem.attr('class', textData.class);
    }
    /*    textData.text.split(/<br\/?>/ig).forEach(function(rowText){
            var span = textElem.append('tspan');
            span.attr('x', textData.x +textData.textMargin);
            span.attr('dy', textData.dy);
            span.text(rowText);
        });*/

    var span = textElem.append('tspan');
    //span.attr('x', textData.x);
    span.attr('x', textData.x+textData.textMargin*2);
    //span.attr('dy', textData.dy);
    span.text(nText);
    if(typeof textElem.textwrap !== 'undefined'){

        textElem.textwrap({
            x: textData.x, // bounding box is 300 pixels from the left
            y: textData.y, // bounding box is 400 pixels from the top
            width: width, // bounding box is 500 pixels across
            height: 1800 // bounding box is 600 pixels tall
        }, textData.textMargin);
    }

    return textElem;
};

exports.drawLabel = function(elem , txtObject){
    var rectData = exports.getNoteRect();
    rectData.x = txtObject.x;
    rectData.y = txtObject.y;
    rectData.width = 50;
    rectData.height = 20;
    rectData.fill = '#526e52';
    rectData.stroke = 'none';
    rectData.class = 'labelBox';
    //rectData.color = 'white';

    exports.drawRect(elem, rectData);

    txtObject.y = txtObject.y + txtObject.labelMargin;
    txtObject.x = txtObject.x + 0.5*txtObject.labelMargin;
    txtObject.fill = 'white';
    exports.drawText(elem, txtObject);

    //return textElem;
};
var actorCnt  = -1;
/**
 * Draws an actor in the diagram with the attaced line
 * @param center - The center of the the actor
 * @param pos The position if the actor in the liost of actors
 * @param description The text in the box
 */
exports.drawActor = function(elem, left, verticalPos, description,conf){
    var center = left + (conf.width/2);
    var g = elem.append('g');
    if(verticalPos === 0) {
        actorCnt++;
        g.append('line')
            .attr('id', 'actor'+actorCnt)
            .attr('x1', center)
            .attr('y1', 5)
            .attr('x2', center)
            .attr('y2', 2000)
            .attr('class', 'actor-line')
            .attr('stroke-width', '0.5px')
            .attr('stroke', '#999');
    }

    var rect = exports.getNoteRect();
    rect.x = left;
    rect.y = verticalPos;
    rect.fill = '#eaeaea';
    rect.width = conf.width;
    rect.height = conf.height;
    rect.class = 'actor';
    rect.rx = 3;
    rect.ry = 3;
    exports.drawRect(g, rect);

    _drawTextCandidateFunc(conf)(
      description, g, rect.x, rect.y, rect.width, rect.height);
};

exports.anchorElement = function(elem) {
    return elem.append('g');
};
/**
 * Draws an actor in the diagram with the attaced line
 * @param elem - element to append activation rect
 * @param bounds - activation box bounds
 * @param verticalPos - precise y cooridnate of bottom activation box edge
 */
exports.drawActivation = function(elem,bounds,verticalPos){
    var rect = exports.getNoteRect();
    var g = bounds.anchored;
    rect.x = bounds.startx;
    rect.y = bounds.starty;
    rect.fill = '#f4f4f4';
    rect.width = bounds.stopx - bounds.startx;
    rect.height = verticalPos - bounds.starty;
    exports.drawRect(g, rect);
};

/**
 * Draws an actor in the diagram with the attaced line
 * @param center - The center of the the actor
 * @param pos The position if the actor in the list of actors
 * @param description The text in the box
 */
exports.drawLoop = function(elem,bounds,labelText, conf){
    var g = elem.append('g');
    var drawLoopLine = function(startx,starty,stopx,stopy){
        g.append('line')
            .attr('x1', startx)
            .attr('y1', starty)
            .attr('x2', stopx )
            .attr('y2', stopy )
            .attr('stroke-width', 2)
            .attr('stroke', '#526e52')
            .attr('class','loopLine');
    };
    drawLoopLine(bounds.startx, bounds.starty, bounds.stopx , bounds.starty);
    drawLoopLine(bounds.stopx , bounds.starty, bounds.stopx , bounds.stopy );
    drawLoopLine(bounds.startx, bounds.stopy , bounds.stopx , bounds.stopy );
    drawLoopLine(bounds.startx, bounds.starty, bounds.startx, bounds.stopy );
    if(typeof bounds.elsey !== 'undefined'){
        drawLoopLine(bounds.startx, bounds.elsey, bounds.stopx, bounds.elsey );
    }

    var txt = exports.getTextObj();
    txt.text = labelText;
    txt.x = bounds.startx;
    txt.y = bounds.starty;
    txt.labelMargin =  1.5 * 10; // This is the small box that says "loop"
    txt.class =  'labelText';    // Its size & position are fixed.
    txt.fill =  'white';

    exports.drawLabel(g,txt);

    txt = exports.getTextObj();
    txt.text = '[ ' + bounds.title + ' ]';
    txt.x = bounds.startx + (bounds.stopx - bounds.startx)/2;
    txt.y = bounds.starty + 1.5 * conf.boxMargin;
    txt.anchor = 'middle';
    txt.class = 'loopText';

    exports.drawText(g,txt);

    if(typeof bounds.elseText !== 'undefined') {
        txt.text = '[ ' + bounds.elseText + ' ]';
        txt.y = bounds.elsey + 1.5 * conf.boxMargin;
        exports.drawText(g, txt);
    }
};

/**
 * Setup arrow head and define the marker. The result is appended to the svg.
 */
exports.insertArrowHead = function(elem){
    elem.append('defs').append('marker')
        .attr('id', 'arrowhead')
        .attr('refX', 5)
        .attr('refY', 2)
        .attr('markerWidth', 6)
        .attr('markerHeight', 4)
        .attr('orient', 'auto')
        .append('path')
        .attr('d', 'M 0,0 V 4 L6,2 Z'); //this is actual shape for arrowhead
};
/**
 * Setup arrow head and define the marker. The result is appended to the svg.
 */
exports.insertArrowCrossHead = function(elem){
    var defs = elem.append('defs');
    var marker = defs.append('marker')
        .attr('id', 'crosshead')
        .attr('markerWidth', 15)
        .attr('markerHeight', 8)
        .attr('orient', 'auto')
        .attr('refX', 16)
        .attr('refY', 4);

    // The arrow
    marker.append('path')
            .attr('fill','black')
            .attr('stroke','#000000')
            .style('stroke-dasharray', ('0, 0'))
            .attr('stroke-width','1px')
            .attr('d', 'M 9,2 V 6 L16,4 Z');

    // The cross
    marker.append('path')
            .attr('fill','none')
            .attr('stroke','#000000')
            .style('stroke-dasharray', ('0, 0'))
            .attr('stroke-width','1px')
            .attr('d', 'M 0,1 L 6,7 M 6,1 L 0,7')
        ; //this is actual shape for arrowhead

};

exports.getTextObj = function(){
    var txt = {
        x: 0,
        y: 0,
        'fill':'black',
        'text-anchor': 'start',
        style: '#666',
        width: 100,
        height: 100,
        textMargin:0,
        rx: 0,
        ry: 0
    };
    return txt;
};

exports.getNoteRect = function(){
    var rect = {
        x      : 0,
        y      : 0,
        fill   : '#EDF2AE',
        stroke : '#666',
        width  : 100,
        anchor : 'start',
        height : 100,
        rx     : 0,
        ry     : 0
    };
    return rect;
};

var _drawTextCandidateFunc = (function() {
    var byText = function(content, g, x, y, width, height) {
        var center = x + width / 2;
        g.append('text')
          .attr('x', center).attr('y', y + y / 2 + 5)
          .attr('class', 'actor').style('text-anchor', 'middle')
          .text(content);
    };
    var byFo = function(content, g, x, y, width, height) {
        var s = g.append('switch');
        var f = s.append("foreignObject")
                  .attr('x', x).attr('y', y)
                  .attr('width', width).attr('height', height);

        f.append('div').style('display', 'table')
          .style('height', '100%').style('width', '100%')
          .append('div').style('display', 'table-cell')
           .style('text-align', 'center').style('vertical-align', 'middle')
           .text(content)

        byText(content, s, x, y, width, height);
    };
    return function(conf) {
      return conf.textPlacement==='fo' ? byFo : byText;
    };
})();
<commit_msg>fix non-fo y position as before<commit_after>/**
 * Created by knut on 14-12-20.
 */
//var log = require('../../logger').create();
exports.drawRect = function(elem , rectData){
    var rectElem = elem.append('rect');
    rectElem.attr('x', rectData.x);
    rectElem.attr('y', rectData.y);
    rectElem.attr('fill', rectData.fill);
    rectElem.attr('stroke', rectData.stroke);
    rectElem.attr('width', rectData.width);
    rectElem.attr('height', rectData.height);
    rectElem.attr('rx', rectData.rx);
    rectElem.attr('ry', rectData.ry);

    if(typeof rectData.class !== 'undefined'){
        rectElem.attr('class', rectData.class);
    }

    return rectElem;
};

exports.drawText = function(elem, textData, width) {
    // Remove and ignore br:s
    var nText = textData.text.replace(/<br\/?>/ig,' ');

    var textElem = elem.append('text');
    textElem.attr('x', textData.x);
    textElem.attr('y', textData.y);
    textElem.style('text-anchor', textData.anchor);
    textElem.attr('fill', textData.fill);
    if (typeof textData.class !== 'undefined') {
        textElem.attr('class', textData.class);
    }
    /*    textData.text.split(/<br\/?>/ig).forEach(function(rowText){
            var span = textElem.append('tspan');
            span.attr('x', textData.x +textData.textMargin);
            span.attr('dy', textData.dy);
            span.text(rowText);
        });*/

    var span = textElem.append('tspan');
    //span.attr('x', textData.x);
    span.attr('x', textData.x+textData.textMargin*2);
    //span.attr('dy', textData.dy);
    span.text(nText);
    if(typeof textElem.textwrap !== 'undefined'){

        textElem.textwrap({
            x: textData.x, // bounding box is 300 pixels from the left
            y: textData.y, // bounding box is 400 pixels from the top
            width: width, // bounding box is 500 pixels across
            height: 1800 // bounding box is 600 pixels tall
        }, textData.textMargin);
    }

    return textElem;
};

exports.drawLabel = function(elem , txtObject){
    var rectData = exports.getNoteRect();
    rectData.x = txtObject.x;
    rectData.y = txtObject.y;
    rectData.width = 50;
    rectData.height = 20;
    rectData.fill = '#526e52';
    rectData.stroke = 'none';
    rectData.class = 'labelBox';
    //rectData.color = 'white';

    exports.drawRect(elem, rectData);

    txtObject.y = txtObject.y + txtObject.labelMargin;
    txtObject.x = txtObject.x + 0.5*txtObject.labelMargin;
    txtObject.fill = 'white';
    exports.drawText(elem, txtObject);

    //return textElem;
};
var actorCnt  = -1;
/**
 * Draws an actor in the diagram with the attaced line
 * @param center - The center of the the actor
 * @param pos The position if the actor in the liost of actors
 * @param description The text in the box
 */
exports.drawActor = function(elem, left, verticalPos, description,conf){
    var center = left + (conf.width/2);
    var g = elem.append('g');
    if(verticalPos === 0) {
        actorCnt++;
        g.append('line')
            .attr('id', 'actor'+actorCnt)
            .attr('x1', center)
            .attr('y1', 5)
            .attr('x2', center)
            .attr('y2', 2000)
            .attr('class', 'actor-line')
            .attr('stroke-width', '0.5px')
            .attr('stroke', '#999');
    }

    var rect = exports.getNoteRect();
    rect.x = left;
    rect.y = verticalPos;
    rect.fill = '#eaeaea';
    rect.width = conf.width;
    rect.height = conf.height;
    rect.class = 'actor';
    rect.rx = 3;
    rect.ry = 3;
    exports.drawRect(g, rect);

    _drawTextCandidateFunc(conf)(
      description, g, rect.x, rect.y, rect.width, rect.height);
};

exports.anchorElement = function(elem) {
    return elem.append('g');
};
/**
 * Draws an actor in the diagram with the attaced line
 * @param elem - element to append activation rect
 * @param bounds - activation box bounds
 * @param verticalPos - precise y cooridnate of bottom activation box edge
 */
exports.drawActivation = function(elem,bounds,verticalPos){
    var rect = exports.getNoteRect();
    var g = bounds.anchored;
    rect.x = bounds.startx;
    rect.y = bounds.starty;
    rect.fill = '#f4f4f4';
    rect.width = bounds.stopx - bounds.startx;
    rect.height = verticalPos - bounds.starty;
    exports.drawRect(g, rect);
};

/**
 * Draws an actor in the diagram with the attaced line
 * @param center - The center of the the actor
 * @param pos The position if the actor in the list of actors
 * @param description The text in the box
 */
exports.drawLoop = function(elem,bounds,labelText, conf){
    var g = elem.append('g');
    var drawLoopLine = function(startx,starty,stopx,stopy){
        g.append('line')
            .attr('x1', startx)
            .attr('y1', starty)
            .attr('x2', stopx )
            .attr('y2', stopy )
            .attr('stroke-width', 2)
            .attr('stroke', '#526e52')
            .attr('class','loopLine');
    };
    drawLoopLine(bounds.startx, bounds.starty, bounds.stopx , bounds.starty);
    drawLoopLine(bounds.stopx , bounds.starty, bounds.stopx , bounds.stopy );
    drawLoopLine(bounds.startx, bounds.stopy , bounds.stopx , bounds.stopy );
    drawLoopLine(bounds.startx, bounds.starty, bounds.startx, bounds.stopy );
    if(typeof bounds.elsey !== 'undefined'){
        drawLoopLine(bounds.startx, bounds.elsey, bounds.stopx, bounds.elsey );
    }

    var txt = exports.getTextObj();
    txt.text = labelText;
    txt.x = bounds.startx;
    txt.y = bounds.starty;
    txt.labelMargin =  1.5 * 10; // This is the small box that says "loop"
    txt.class =  'labelText';    // Its size & position are fixed.
    txt.fill =  'white';

    exports.drawLabel(g,txt);

    txt = exports.getTextObj();
    txt.text = '[ ' + bounds.title + ' ]';
    txt.x = bounds.startx + (bounds.stopx - bounds.startx)/2;
    txt.y = bounds.starty + 1.5 * conf.boxMargin;
    txt.anchor = 'middle';
    txt.class = 'loopText';

    exports.drawText(g,txt);

    if(typeof bounds.elseText !== 'undefined') {
        txt.text = '[ ' + bounds.elseText + ' ]';
        txt.y = bounds.elsey + 1.5 * conf.boxMargin;
        exports.drawText(g, txt);
    }
};

/**
 * Setup arrow head and define the marker. The result is appended to the svg.
 */
exports.insertArrowHead = function(elem){
    elem.append('defs').append('marker')
        .attr('id', 'arrowhead')
        .attr('refX', 5)
        .attr('refY', 2)
        .attr('markerWidth', 6)
        .attr('markerHeight', 4)
        .attr('orient', 'auto')
        .append('path')
        .attr('d', 'M 0,0 V 4 L6,2 Z'); //this is actual shape for arrowhead
};
/**
 * Setup arrow head and define the marker. The result is appended to the svg.
 */
exports.insertArrowCrossHead = function(elem){
    var defs = elem.append('defs');
    var marker = defs.append('marker')
        .attr('id', 'crosshead')
        .attr('markerWidth', 15)
        .attr('markerHeight', 8)
        .attr('orient', 'auto')
        .attr('refX', 16)
        .attr('refY', 4);

    // The arrow
    marker.append('path')
            .attr('fill','black')
            .attr('stroke','#000000')
            .style('stroke-dasharray', ('0, 0'))
            .attr('stroke-width','1px')
            .attr('d', 'M 9,2 V 6 L16,4 Z');

    // The cross
    marker.append('path')
            .attr('fill','none')
            .attr('stroke','#000000')
            .style('stroke-dasharray', ('0, 0'))
            .attr('stroke-width','1px')
            .attr('d', 'M 0,1 L 6,7 M 6,1 L 0,7')
        ; //this is actual shape for arrowhead

};

exports.getTextObj = function(){
    var txt = {
        x: 0,
        y: 0,
        'fill':'black',
        'text-anchor': 'start',
        style: '#666',
        width: 100,
        height: 100,
        textMargin:0,
        rx: 0,
        ry: 0
    };
    return txt;
};

exports.getNoteRect = function(){
    var rect = {
        x      : 0,
        y      : 0,
        fill   : '#EDF2AE',
        stroke : '#666',
        width  : 100,
        anchor : 'start',
        height : 100,
        rx     : 0,
        ry     : 0
    };
    return rect;
};

var _drawTextCandidateFunc = (function() {
    var byText = function(content, g, x, y, width, height) {
        var center = x + width / 2;
        g.append('text')
          .attr('x', center).attr('y', y + height / 2 + 5)
          .attr('class', 'actor').style('text-anchor', 'middle')
          .text(content);
    };
    var byFo = function(content, g, x, y, width, height) {
        var s = g.append('switch');
        var f = s.append("foreignObject")
                  .attr('x', x).attr('y', y)
                  .attr('width', width).attr('height', height);

        f.append('div').style('display', 'table')
          .style('height', '100%').style('width', '100%')
          .append('div').style('display', 'table-cell')
           .style('text-align', 'center').style('vertical-align', 'middle')
           .text(content)

        byText(content, s, x, y, width, height);
    };
    return function(conf) {
      return conf.textPlacement==='fo' ? byFo : byText;
    };
})();
<|endoftext|>


<commit_before>// Copyright (c) 2015, Evan Summers (twitter.com/evanxsummers)
// ISC license, see http://github.com/evanx/redexutil/LICENSE

// a more explicit promisification for redis client

// also see more automated attempt using es6-promisify:
// https://github.com/evanx/redex/blob/master/lib/redisPromisified.js

import lodash from 'lodash';
import redis from 'redis';

import Paths from './Paths';
import Loggers from './Loggers';

const logger = Loggers.create(module.filename, 'info');

const state = {
   count: 0,
   clients: new Set()
};

function createClient(options) {
   state.count++;
   let redisClient = redis.createClient(options || {});
   state.clients.add(redisClient);
   redisClient.on('error', err => {
      logger.error('redis error:', err);
   });
   return redisClient;
}

function createCallback(resolve, reject) {
   return (err, reply) => {
      if (err) {
         logger.debug('redis reject error:', err);
         reject(err);
      } else {
         logger.debug('redis resolve:', reply);
         resolve(reply);
      }
   };
}

function createPromise(fn) {
   return new Promise((resolve, reject) => fn(createCallback(resolve, reject)));
}

export default class Redis {

   // @param client
   // client maybe null e.g. if constructed with empty options object i.e. {}
   // if no options, then client is created

   constructor(options) {
      if (options) {
         if (lodash.isString(options)) {
            this.source = Paths.basename(options);
            this.client = createClient();
            logger.info('construct', state.count, this.source);
         } else if (options === {}) {
            logger.info('construct defer');
         } else if (options.client) {
            this.client = options.client;
            logger.info('construct wrapper');
         } else if (options.source) {
            this.source = Files.basename(options.source);
            this.client = createClient(options);
            logger.info('construct', state.count, this.source);
         } else if (options.return_buffers || options.dbNumber) {
            this.client = createClient(options);
         } else {
            throw 'Invalid options: ' + options.toString();
         }
      } else {
         this.client = createClient();
         logger.info('construct', state.count);
      }
      if (this.client) {
         this.init(options);
      }
   }

   init(options) {
      if (!this.client) {
         this.client = createClient(options);
      }
      if (Redis.dbNumber) { // use alternative database for all connections
         this.select(Redis.dbNumber);
      } else if (options && options.dbNumber) {
         this.select(options.dbNumber);
      }
   }

   select(dbNumber) {
      return createPromise(cb => this.client.select(dbNumber, cb));
   }

   end() {
      if (this.client) {
         if (state.clients.size > 0) {
            state.clients.delete(this.client);
            logger.info('end', state.clients.size, this.source);
         } else {
            logger.error('end');
         }
         this.client.end();
         this.client = null;
      }
   }

   time() {
      return createPromise(cb => this.client.time(cb));
   }

   timeSeconds() {
      return this.time().then(time => {
         return parseInt(time[0]);
      });
   }

   del(key) {
      return createPromise(cb => this.client.del(key, cb));
   }

   get(key) {
      return createPromise(cb => this.client.get(key, cb));
   }

   exists(key) {
      return createPromise(cb => this.client.exists(key, cb));
   }

   expire(key, seconds) {
      return createPromise(cb => this.client.expire(key, seconds, cb));
   }

   keys(match) {
      return createPromise(cb => this.client.keys(match, cb));
   }

   mget(keys) {
      return createPromise(cb => this.client.mget(keys, cb));
   }

   scan(cursor, match, count) {
      return createPromise(cb => this.client.scan(cursor, match, count, cb));
   }

   set(key, value) {
      return createPromise(cb => this.client.set(key, value, cb));
   }

   setex(key, seconds, value) {
      return createPromise(cb => this.client.setex(key, seconds, value, cb));
   }

   setnx(key, value) {
      return createPromise(cb => this.client.setnx(key, value, cb));
   }

   sadd(key, member) {
      return createPromise(cb => this.client.sadd(key, member, cb));
   }

   sismember(key, member) {
      return createPromise(cb => this.client.sismember(key, member, cb));
   }

   smembers(key) {
      return createPromise(cb => this.client.smembers(key, cb));
   }

   srem(key, member) {
      return createPromise(cb => this.client.srem(key, member, cb));
   }

   scard(key) {
      return createPromise(cb => this.client.scard(key, cb));
   }

   hdel(key, ...fields) {
      return createPromise(cb => this.client.hdel(key, fields, cb));
   }

   hget(key, field) {
      return createPromise(cb => this.client.hget(key, field, cb));
   }

   hmget(key, fields) {
      return createPromise(cb => this.client.hmget(key, fields, cb));
   }

   hgetall(key) {
      return createPromise(cb => this.client.hgetall(key, cb));
   }

   hkeys(key) {
      return createPromise(cb => this.client.hkeys(key, cb));
   }

   hmset(key, value) {
      return createPromise(cb => this.client.hmset(key, value, cb));
   }

   hset(key, field, value) {
      return createPromise(cb => this.client.hset(key, field, value, cb));
   }

   hsetnx(key, field, value) {
      return createPromise(cb => this.client.hsetnx(key, field, value, cb));
   }

   lindex(key, index) {
      return createPromise(cb => this.client.lindex(key, index, cb));
   }

   linsert(key, position, pivot, value) {
      return createPromise(cb => this.client.linsert(key, position, pivot, value, cb));
   }

   lrem(key, count, value) {
      return createPromise(cb => this.client.lrem(key, count, value, cb));
   }

   lset(key, index, value) {
      return createPromise(cb => this.client.lset(key, index, value, cb));
   }

   llen(key) {
      return createPromise(cb => this.client.llen(key, cb));
   }

   ltrim(key, start, stop) {
      return createPromise(cb => this.client.ltrim(key, start, stop, cb));
   }

   lrange(key, start, stop) {
      return createPromise(cb => this.client.lrange(key, start, stop, cb));
   }

   lpush(key, value) {
      return createPromise(cb => this.client.lpush(key, value, cb));
   }

   rpush(key, value) {
      return createPromise(cb => this.client.rpush(key, value, cb));
   }

   lpop(key) {
      return createPromise(cb => this.client.lpop(key, cb));
   }

   rpop(key) {
      return createPromise(cb => this.client.rpop(key, cb));
   }

   blpop(key, timeout) {
      return createPromise(cb => this.client.blpop(key, timeout, cb));
   }

   brpop(key, timeout) {
      return createPromise(cb => this.client.brpop(key, timeout, cb));
   }

   rpoplpush(source, destination) {
      return createPromise(cb => this.client.rpoplpush(source, destination, cb));
   }

   brpoplpush(source, destination, timeout) {
      return createPromise(cb => this.client.brpoplpush(source, destination, timeout, cb));
   }

   zrange(key, start, stop) {
      return createPromise(cb => this.client.zrange(key, start, stop, cb));
   }

   zrem(key, member) {
      return createPromise(cb => this.client.zrem(key, member, cb));
   }

   zrevrange(key, start, stop) {
      return createPromise(cb => this.client.zrevrange(key, start, stop, cb));
   }

   // TODO all the rest, see https://github.com/mranney/node_redis/blob/master/lib/commands.js

   multi() {
      let multi = this.client.multi();
      multi.execCallback = multi.exec.bind(multi); // TODO
      multi.exec = function() {
         return createPromise(cb => multi.execCallback(cb));
      };
      return multi;
   }
}

// see test: https://github.com/evanx/redex/blob/master/test/redisPromised.js
<commit_msg>zadd and zcard<commit_after>// Copyright (c) 2015, Evan Summers (twitter.com/evanxsummers)
// ISC license, see http://github.com/evanx/redexutil/LICENSE

// a more explicit promisification for redis client

// also see more automated attempt using es6-promisify:
// https://github.com/evanx/redex/blob/master/lib/redisPromisified.js

import lodash from 'lodash';
import redis from 'redis';

import Paths from './Paths';
import Loggers from './Loggers';

const logger = Loggers.create(module.filename, 'info');

const state = {
   count: 0,
   clients: new Set()
};

function createClient(options) {
   state.count++;
   let redisClient = redis.createClient(options || {});
   state.clients.add(redisClient);
   redisClient.on('error', err => {
      logger.error('redis error:', err);
   });
   return redisClient;
}

function createCallback(resolve, reject) {
   return (err, reply) => {
      if (err) {
         logger.debug('redis reject error:', err);
         reject(err);
      } else {
         logger.debug('redis resolve:', reply);
         resolve(reply);
      }
   };
}

function createPromise(fn) {
   return new Promise((resolve, reject) => fn(createCallback(resolve, reject)));
}

export default class Redis {

   // @param client
   // client maybe null e.g. if constructed with empty options object i.e. {}
   // if no options, then client is created

   constructor(options) {
      if (options) {
         if (lodash.isString(options)) {
            this.source = Paths.basename(options);
            this.client = createClient();
            logger.info('construct', state.count, this.source);
         } else if (options === {}) {
            logger.info('construct defer');
         } else if (options.client) {
            this.client = options.client;
            logger.info('construct wrapper');
         } else if (options.source) {
            this.source = Files.basename(options.source);
            this.client = createClient(options);
            logger.info('construct', state.count, this.source);
         } else if (options.return_buffers || options.dbNumber) {
            this.client = createClient(options);
         } else {
            throw 'Invalid options: ' + options.toString();
         }
      } else {
         this.client = createClient();
         logger.info('construct', state.count);
      }
      if (this.client) {
         this.init(options);
      }
   }

   init(options) {
      if (!this.client) {
         this.client = createClient(options);
      }
      if (Redis.dbNumber) { // use alternative database for all connections
         this.select(Redis.dbNumber);
      } else if (options && options.dbNumber) {
         this.select(options.dbNumber);
      }
   }

   select(dbNumber) {
      return createPromise(cb => this.client.select(dbNumber, cb));
   }

   end() {
      if (this.client) {
         if (state.clients.size > 0) {
            state.clients.delete(this.client);
            logger.info('end', state.clients.size, this.source);
         } else {
            logger.error('end');
         }
         this.client.end();
         this.client = null;
      }
   }

   time() {
      return createPromise(cb => this.client.time(cb));
   }

   timeSeconds() {
      return this.time().then(time => {
         return parseInt(time[0]);
      });
   }

   del(key) {
      return createPromise(cb => this.client.del(key, cb));
   }

   get(key) {
      return createPromise(cb => this.client.get(key, cb));
   }

   exists(key) {
      return createPromise(cb => this.client.exists(key, cb));
   }

   expire(key, seconds) {
      return createPromise(cb => this.client.expire(key, seconds, cb));
   }

   keys(match) {
      return createPromise(cb => this.client.keys(match, cb));
   }

   mget(keys) {
      return createPromise(cb => this.client.mget(keys, cb));
   }

   scan(cursor, match, count) {
      return createPromise(cb => this.client.scan(cursor, match, count, cb));
   }

   set(key, value) {
      return createPromise(cb => this.client.set(key, value, cb));
   }

   setex(key, seconds, value) {
      return createPromise(cb => this.client.setex(key, seconds, value, cb));
   }

   setnx(key, value) {
      return createPromise(cb => this.client.setnx(key, value, cb));
   }

   sadd(key, member) {
      return createPromise(cb => this.client.sadd(key, member, cb));
   }

   sismember(key, member) {
      return createPromise(cb => this.client.sismember(key, member, cb));
   }

   smembers(key) {
      return createPromise(cb => this.client.smembers(key, cb));
   }

   srem(key, member) {
      return createPromise(cb => this.client.srem(key, member, cb));
   }

   scard(key) {
      return createPromise(cb => this.client.scard(key, cb));
   }

   hdel(key, ...fields) {
      return createPromise(cb => this.client.hdel(key, fields, cb));
   }

   hget(key, field) {
      return createPromise(cb => this.client.hget(key, field, cb));
   }

   hmget(key, fields) {
      return createPromise(cb => this.client.hmget(key, fields, cb));
   }

   hgetall(key) {
      return createPromise(cb => this.client.hgetall(key, cb));
   }

   hkeys(key) {
      return createPromise(cb => this.client.hkeys(key, cb));
   }

   hmset(key, value) {
      return createPromise(cb => this.client.hmset(key, value, cb));
   }

   hset(key, field, value) {
      return createPromise(cb => this.client.hset(key, field, value, cb));
   }

   hsetnx(key, field, value) {
      return createPromise(cb => this.client.hsetnx(key, field, value, cb));
   }

   lindex(key, index) {
      return createPromise(cb => this.client.lindex(key, index, cb));
   }

   linsert(key, position, pivot, value) {
      return createPromise(cb => this.client.linsert(key, position, pivot, value, cb));
   }

   lrem(key, count, value) {
      return createPromise(cb => this.client.lrem(key, count, value, cb));
   }

   lset(key, index, value) {
      return createPromise(cb => this.client.lset(key, index, value, cb));
   }

   llen(key) {
      return createPromise(cb => this.client.llen(key, cb));
   }

   ltrim(key, start, stop) {
      return createPromise(cb => this.client.ltrim(key, start, stop, cb));
   }

   lrange(key, start, stop) {
      return createPromise(cb => this.client.lrange(key, start, stop, cb));
   }

   lpush(key, value) {
      return createPromise(cb => this.client.lpush(key, value, cb));
   }

   rpush(key, value) {
      return createPromise(cb => this.client.rpush(key, value, cb));
   }

   lpop(key) {
      return createPromise(cb => this.client.lpop(key, cb));
   }

   rpop(key) {
      return createPromise(cb => this.client.rpop(key, cb));
   }

   blpop(key, timeout) {
      return createPromise(cb => this.client.blpop(key, timeout, cb));
   }

   brpop(key, timeout) {
      return createPromise(cb => this.client.brpop(key, timeout, cb));
   }

   rpoplpush(source, destination) {
      return createPromise(cb => this.client.rpoplpush(source, destination, cb));
   }

   brpoplpush(source, destination, timeout) {
      return createPromise(cb => this.client.brpoplpush(source, destination, timeout, cb));
   }

   zadd(key, score, member) {
      return createPromise(cb => this.client.zadd(key, score, member, cb));
   }

   zcard(key) {
      return createPromise(cb => this.client.zcard(key, cb));
   }

   zrange(key, start, stop) {
      return createPromise(cb => this.client.zrange(key, start, stop, cb));
   }

   zrem(key, member) {
      return createPromise(cb => this.client.zrem(key, member, cb));
   }

   zrevrange(key, start, stop) {
      return createPromise(cb => this.client.zrevrange(key, start, stop, cb));
   }

   // TODO all the rest, see https://github.com/mranney/node_redis/blob/master/lib/commands.js

   multi() {
      let multi = this.client.multi();
      multi.execCallback = multi.exec.bind(multi); // TODO
      multi.exec = function() {
         return createPromise(cb => multi.execCallback(cb));
      };
      return multi;
   }
}

// see test: https://github.com/evanx/redex/blob/master/test/redisPromised.js
<|endoftext|>


<commit_before>// Copyright (c) 2015, Evan Summers (twitter.com/evanxsummers)
// ISC license, see http://github.com/evanx/redexutil/LICENSE

// A more explicit promisification for redis client.
// Also see more automated attempt using es6-promisify:
// https://github.com/evanx/redex/blob/master/lib/redisPromisified.js

import lodash from 'lodash';
import redis from 'redis';

import Loggers from './Loggers';
import Paths from './Paths';

const logger = Loggers.create(__filename, 'info');

const state = {
   count: 0,
   clients: new Set(),
   globalDefaultOptions: {},
   globalOverrideOptions: {}
};

function createClient(options) {
   let redisClient;
   state.count++;
   options = Object.assign({}, state.globalDefaultOptions, options || {}, state.globalOverrideOptions);
   if (options.url) {
      let match = options.url.match(/^redis:\/\/([^:]+):([0-9]+)$/);
      if (match) {
         options.host = match[1];
         options.port = parseInt(match[2]);
         redisClient = redis.createClient(options.port, options.host);
      }
   }
   if (!redisClient) {
      redisClient = redis.createClient(options);
   }
   logger.info('createClient', state.count, options);
   redisClient.on('error', err => {
      logger.error('redis', err);
   });
   state.clients.add(redisClient);
   if (options.select) {
      redisClient.select(options.select);
   }
   return redisClient;
}

function createCallback(resolve, reject) {
   return (err, reply) => {
      if (err) {
         logger.warn('redis reject error', err);
         reject(err);
      } else {
         logger.debug('redis resolve', reply);
         resolve(reply);
      }
   };
}

function createPromise(fn) {
   return new Promise((resolve, reject) => fn(createCallback(resolve, reject)));
}

export default class Redis {

   static async start(initialState) {
      Object.assign(state, initialState);
   }

   // @param client
   // client maybe null e.g. if constructed with empty options object i.e. {}
   // if no options, then client is created

   constructor(options) {
      logger.info('Redis constructor', options);
      if (options) {
         if (lodash.isString(options)) {
            this.source = Paths.basename(options);
            this.client = createClient();
            logger.info('construct', state.count, this.source);
         } else if (options === {}) {
            logger.info('construct defer');
         } else if (options.client) {
            this.client = options.client;
            logger.info('construct wrapper');
         } else if (options.source) {
            this.source = Files.basename(options.source);
            this.client = createClient(options);
            logger.info('construct', state.count, this.source);
         } else if (options.return_buffers || options.dbNumber || options.url) {
            this.client = createClient(options);
         } else {
            throw 'Invalid Redis options: ' + JSON.stringify(options);
         }
      } else {
         this.client = createClient();
         logger.info('construct', state.count);
      }
      if (this.client) {
         this.init(options);
      }
   }

   init(options) {
      if (!this.client) {
         this.client = createClient(options);
      }
      if (global.redisNumber) { // use alternative database for all connections
         this.select(global.redisNumber);
      } else if (options && options.dbNumber) {
         this.select(options.dbNumber);
      }
   }

   select(dbNumber) {
      return createPromise(cb => this.client.select(dbNumber, cb));
   }

   end() {
      if (this.client) {
         if (state.clients.size > 0) {
            state.clients.delete(this.client);
            logger.info('end', state.clients.size, this.source);
         } else {
            logger.error('end');
         }
         this.client.end();
         this.client = null;
      }
   }

   time() {
      return createPromise(cb => this.client.time(cb));
   }

   timeSeconds() {
      return this.time().then(time => {
         return parseInt(time[0]);
      });
   }

   del(key) {
      return createPromise(cb => this.client.del(key, cb));
   }

   dump(key) {
      return createPromise(cb => this.client.dump(key, cb));
   }

   get(key) {
      return createPromise(cb => this.client.get(key, cb));
   }

   exists(key) {
      return createPromise(cb => this.client.exists(key, cb));
   }

   expire(key, seconds) {
      return createPromise(cb => this.client.expire(key, seconds, cb));
   }

   keys(match) {
      return createPromise(cb => this.client.keys(match, cb));
   }

   mget(keys) {
      //logger.info('mget', lodash.isArray(keys), keys);
      return createPromise(cb => this.client.mget(keys, cb));
   }

   restore(key, ttl, value) {
      return createPromise(cb => this.client.restore(key, ttl, value, cb));
   }

   scan(cursor, match, count) {
      return createPromise(cb => this.client.scan(cursor, 'match', match, 'count', count, cb));
   }

   set(key, value) {
      return createPromise(cb => this.client.set(key, value, cb));
   }

   setex(key, seconds, value) {
      return createPromise(cb => this.client.setex(key, seconds, value, cb));
   }

   setnx(key, value) {
      return createPromise(cb => this.client.setnx(key, value, cb));
   }

   sadd(key, member) {
      return createPromise(cb => this.client.sadd(key, member, cb));
   }

   sismember(key, member) {
      return createPromise(cb => this.client.sismember(key, member, cb));
   }

   sinter(key, members) {
      return createPromise(cb => this.client.sinter(key, members, cb));
   }

   smembers(key) {
      return createPromise(cb => this.client.smembers(key, cb));
   }

   srem(key, member) {
      return createPromise(cb => this.client.srem(key, member, cb));
   }

   scard(key) {
      return createPromise(cb => this.client.scard(key, cb));
   }

   ttl(key) {
      return createPromise(cb => this.client.ttl(key, cb));
   }

   hdel(key, ...fields) {
      return createPromise(cb => this.client.hdel(key, fields, cb));
   }

   hget(key, field) {
      return createPromise(cb => this.client.hget(key, field, cb));
   }

   hmget(key, fields) {
      return createPromise(cb => this.client.hmget(key, fields, cb));
   }

   hgetall(key) {
      return createPromise(cb => this.client.hgetall(key, cb));
   }

   hkeys(key) {
      return createPromise(cb => this.client.hkeys(key, cb));
   }

   hmset(key, value) {
      return createPromise(cb => this.client.hmset(key, value, cb));
   }

   hset(key, field, value) {
      return createPromise(cb => this.client.hset(key, field, value, cb));
   }

   hsetnx(key, field, value) {
      return createPromise(cb => this.client.hsetnx(key, field, value, cb));
   }

   lindex(key, index) {
      return createPromise(cb => this.client.lindex(key, index, cb));
   }

   linsert(key, position, pivot, value) {
      return createPromise(cb => this.client.linsert(key, position, pivot, value, cb));
   }

   lrem(key, count, value) {
      return createPromise(cb => this.client.lrem(key, count, value, cb));
   }

   lset(key, index, value) {
      return createPromise(cb => this.client.lset(key, index, value, cb));
   }

   llen(key) {
      return createPromise(cb => this.client.llen(key, cb));
   }

   ltrim(key, start, stop) {
      return createPromise(cb => this.client.ltrim(key, start, stop, cb));
   }

   lrange(key, start, stop) {
      return createPromise(cb => this.client.lrange(key, start, stop, cb));
   }

   lpush(key, value) {
      return createPromise(cb => this.client.lpush(key, value, cb));
   }

   rpush(key, value) {
      return createPromise(cb => this.client.rpush(key, value, cb));
   }

   lpop(key) {
      return createPromise(cb => this.client.lpop(key, cb));
   }

   rpop(key) {
      return createPromise(cb => this.client.rpop(key, cb));
   }

   blpop(key, timeout) {
      return createPromise(cb => this.client.blpop(key, timeout, cb));
   }

   brpop(key, timeout) {
      return createPromise(cb => this.client.brpop(key, timeout, cb));
   }

   rpoplpush(source, destination) {
      return createPromise(cb => this.client.rpoplpush(source, destination, cb));
   }

   brpoplpush(source, destination, timeout) {
      return createPromise(cb => this.client.brpoplpush(source, destination, timeout, cb));
   }

   zadd(key, score, member) {
      return createPromise(cb => this.client.zadd(key, score, member, cb));
   }

   zcard(key) {
      return createPromise(cb => this.client.zcard(key, cb));
   }

   zrange(key, start, stop) {
      return createPromise(cb => this.client.zrange(key, start, stop, cb));
   }

   zrem(key, member) {
      return createPromise(cb => this.client.zrem(key, member, cb));
   }

   zrevrange(key, start, stop) {
      return createPromise(cb => this.client.zrevrange(key, start, stop, cb));
   }

   // TODO all the rest, see https://github.com/mranney/node_redis/blob/master/lib/commands.js

   multi() {
      let multi_ = this.client.multi();
      multi_.execCallback = multi_.exec.bind(multi_); // TODO
      multi_.exec = function() {
         return createPromise(cb => multi_.execCallback(cb));
      };
      return multi_;
   }
}

// see test: https://github.com/evanx/redex/blob/master/test/redisPromised.js
<commit_msg>added hexists<commit_after>// Copyright (c) 2015, Evan Summers (twitter.com/evanxsummers)
// ISC license, see http://github.com/evanx/redexutil/LICENSE

// A more explicit promisification for redis client.
// Also see more automated attempt using es6-promisify:
// https://github.com/evanx/redex/blob/master/lib/redisPromisified.js

import lodash from 'lodash';
import redis from 'redis';

import Loggers from './Loggers';
import Paths from './Paths';

const logger = Loggers.create(__filename, 'info');

const state = {
   count: 0,
   clients: new Set(),
   globalDefaultOptions: {},
   globalOverrideOptions: {}
};

function createClient(options) {
   let redisClient;
   state.count++;
   options = Object.assign({}, state.globalDefaultOptions, options || {}, state.globalOverrideOptions);
   if (options.url) {
      let match = options.url.match(/^redis:\/\/([^:]+):([0-9]+)$/);
      if (match) {
         options.host = match[1];
         options.port = parseInt(match[2]);
         redisClient = redis.createClient(options.port, options.host);
      }
   }
   if (!redisClient) {
      redisClient = redis.createClient(options);
   }
   logger.info('createClient', state.count, options);
   redisClient.on('error', err => {
      logger.error('redis', err);
   });
   state.clients.add(redisClient);
   if (options.select) {
      redisClient.select(options.select);
   }
   return redisClient;
}

function createCallback(resolve, reject) {
   return (err, reply) => {
      if (err) {
         logger.warn('redis reject error', err);
         reject(err);
      } else {
         logger.debug('redis resolve', reply);
         resolve(reply);
      }
   };
}

function createPromise(fn) {
   return new Promise((resolve, reject) => fn(createCallback(resolve, reject)));
}

export default class Redis {

   static async start(initialState) {
      Object.assign(state, initialState);
   }

   // @param client
   // client maybe null e.g. if constructed with empty options object i.e. {}
   // if no options, then client is created

   constructor(options) {
      logger.info('Redis constructor', options);
      if (options) {
         if (lodash.isString(options)) {
            this.source = Paths.basename(options);
            this.client = createClient();
            logger.info('construct', state.count, this.source);
         } else if (options === {}) {
            logger.info('construct defer');
         } else if (options.client) {
            this.client = options.client;
            logger.info('construct wrapper');
         } else if (options.source) {
            this.source = Files.basename(options.source);
            this.client = createClient(options);
            logger.info('construct', state.count, this.source);
         } else if (options.return_buffers || options.dbNumber || options.url) {
            this.client = createClient(options);
         } else {
            throw 'Invalid Redis options: ' + JSON.stringify(options);
         }
      } else {
         this.client = createClient();
         logger.info('construct', state.count);
      }
      if (this.client) {
         this.init(options);
      }
   }

   init(options) {
      if (!this.client) {
         this.client = createClient(options);
      }
      if (global.redisNumber) { // use alternative database for all connections
         this.select(global.redisNumber);
      } else if (options && options.dbNumber) {
         this.select(options.dbNumber);
      }
   }

   select(dbNumber) {
      return createPromise(cb => this.client.select(dbNumber, cb));
   }

   end() {
      if (this.client) {
         if (state.clients.size > 0) {
            state.clients.delete(this.client);
            logger.info('end', state.clients.size, this.source);
         } else {
            logger.error('end');
         }
         this.client.end();
         this.client = null;
      }
   }

   time() {
      return createPromise(cb => this.client.time(cb));
   }

   timeSeconds() {
      return this.time().then(time => {
         return parseInt(time[0]);
      });
   }

   del(key) {
      return createPromise(cb => this.client.del(key, cb));
   }

   dump(key) {
      return createPromise(cb => this.client.dump(key, cb));
   }

   get(key) {
      return createPromise(cb => this.client.get(key, cb));
   }

   exists(key) {
      return createPromise(cb => this.client.exists(key, cb));
   }

   expire(key, seconds) {
      return createPromise(cb => this.client.expire(key, seconds, cb));
   }

   keys(match) {
      return createPromise(cb => this.client.keys(match, cb));
   }

   mget(keys) {
      //logger.info('mget', lodash.isArray(keys), keys);
      return createPromise(cb => this.client.mget(keys, cb));
   }

   restore(key, ttl, value) {
      return createPromise(cb => this.client.restore(key, ttl, value, cb));
   }

   scan(cursor, match, count) {
      return createPromise(cb => this.client.scan(cursor, 'match', match, 'count', count, cb));
   }

   set(key, value) {
      return createPromise(cb => this.client.set(key, value, cb));
   }

   setex(key, seconds, value) {
      return createPromise(cb => this.client.setex(key, seconds, value, cb));
   }

   setnx(key, value) {
      return createPromise(cb => this.client.setnx(key, value, cb));
   }

   sadd(key, member) {
      return createPromise(cb => this.client.sadd(key, member, cb));
   }

   sismember(key, member) {
      return createPromise(cb => this.client.sismember(key, member, cb));
   }

   sinter(key, members) {
      return createPromise(cb => this.client.sinter(key, members, cb));
   }

   smembers(key) {
      return createPromise(cb => this.client.smembers(key, cb));
   }

   srem(key, member) {
      return createPromise(cb => this.client.srem(key, member, cb));
   }

   scard(key) {
      return createPromise(cb => this.client.scard(key, cb));
   }

   ttl(key) {
      return createPromise(cb => this.client.ttl(key, cb));
   }

   hexists(key, field) {
      return createPromise(cb => this.client.hexists(key, field, cb));
   }

   hdel(key, ...fields) {
      return createPromise(cb => this.client.hdel(key, fields, cb));
   }

   hget(key, field) {
      return createPromise(cb => this.client.hget(key, field, cb));
   }

   hmget(key, fields) {
      return createPromise(cb => this.client.hmget(key, fields, cb));
   }

   hgetall(key) {
      return createPromise(cb => this.client.hgetall(key, cb));
   }

   hkeys(key) {
      return createPromise(cb => this.client.hkeys(key, cb));
   }

   hmset(key, value) {
      return createPromise(cb => this.client.hmset(key, value, cb));
   }

   hset(key, field, value) {
      return createPromise(cb => this.client.hset(key, field, value, cb));
   }

   hsetnx(key, field, value) {
      return createPromise(cb => this.client.hsetnx(key, field, value, cb));
   }

   lindex(key, index) {
      return createPromise(cb => this.client.lindex(key, index, cb));
   }

   linsert(key, position, pivot, value) {
      return createPromise(cb => this.client.linsert(key, position, pivot, value, cb));
   }

   lrem(key, count, value) {
      return createPromise(cb => this.client.lrem(key, count, value, cb));
   }

   lset(key, index, value) {
      return createPromise(cb => this.client.lset(key, index, value, cb));
   }

   llen(key) {
      return createPromise(cb => this.client.llen(key, cb));
   }

   ltrim(key, start, stop) {
      return createPromise(cb => this.client.ltrim(key, start, stop, cb));
   }

   lrange(key, start, stop) {
      return createPromise(cb => this.client.lrange(key, start, stop, cb));
   }

   lpush(key, value) {
      return createPromise(cb => this.client.lpush(key, value, cb));
   }

   rpush(key, value) {
      return createPromise(cb => this.client.rpush(key, value, cb));
   }

   lpop(key) {
      return createPromise(cb => this.client.lpop(key, cb));
   }

   rpop(key) {
      return createPromise(cb => this.client.rpop(key, cb));
   }

   blpop(key, timeout) {
      return createPromise(cb => this.client.blpop(key, timeout, cb));
   }

   brpop(key, timeout) {
      return createPromise(cb => this.client.brpop(key, timeout, cb));
   }

   rpoplpush(source, destination) {
      return createPromise(cb => this.client.rpoplpush(source, destination, cb));
   }

   brpoplpush(source, destination, timeout) {
      return createPromise(cb => this.client.brpoplpush(source, destination, timeout, cb));
   }

   zadd(key, score, member) {
      return createPromise(cb => this.client.zadd(key, score, member, cb));
   }

   zcard(key) {
      return createPromise(cb => this.client.zcard(key, cb));
   }

   zrange(key, start, stop) {
      return createPromise(cb => this.client.zrange(key, start, stop, cb));
   }

   zrem(key, member) {
      return createPromise(cb => this.client.zrem(key, member, cb));
   }

   zrevrange(key, start, stop) {
      return createPromise(cb => this.client.zrevrange(key, start, stop, cb));
   }

   // TODO all the rest, see https://github.com/mranney/node_redis/blob/master/lib/commands.js

   multi() {
      let multi_ = this.client.multi();
      multi_.execCallback = multi_.exec.bind(multi_); // TODO
      multi_.exec = function() {
         return createPromise(cb => multi_.execCallback(cb));
      };
      return multi_;
   }
}

// see test: https://github.com/evanx/redex/blob/master/test/redisPromised.js
<|endoftext|>


<commit_before>// vim:sw=2:ts=2:et:
var assert = require("assert");
var fs = require('fs')
var TrelloReader = require("../trello-json-reader");

describe('TrelloReader.Data', function(){
  it('should return a instance of Data class', function(){
    assert.equal(true, (new TrelloReader.Data()) instanceof TrelloReader.Data);
  });

  it('should return a instance of Data class (2)', function(){
    fs.readFile('test/data/testdata-Data-1.json', 'utf8', function(err, data) {
      if (err) throw err;
      assert.equal(true, (new TrelloReader.Data(JSON.parse(data))) instanceof TrelloReader.Data);
    });
  });

  it('should has activity list', function(){
    fs.readFile('test/data/testdata-Data-1.json', 'utf8', function(err, data) {
      if (err) throw err;
      var data = new TrelloReader.Data(JSON.parse(data));
      assert.equal(2, data.activities.length);
      assert.equal("514e2f8fb6f1dd2d7c002dcf", data.activities[0].id);
      assert.equal("514e2ed443663060620025f7", data.activities[1].id);
      assert.equal(undefined, data.activities[2]);
    });
  });

  it('should has card list', function(){
    fs.readFile('test/data/testdata-Data-1.json', 'utf8', function(err, data) {
      if (err) throw err;
      var data = new TrelloReader.Data(JSON.parse(data));
      assert.equal(1, data.cards.length);
      assert.equal("514e2f8fb6f1dd2d7c002dce", data.cards[0].id);
      assert.equal(undefined, data.cards[1]);
    });
  });

  it('should has card list with relations to list', function(){
    fs.readFile('test/data/testdata-Data-1.json', 'utf8', function(err, data) {
      if (err) throw err;
      var data = new TrelloReader.Data(JSON.parse(data));
      assert.equal("514e2ed443663060620025f3", data.cards[0].idList);
      assert.equal("514e2ed443663060620025f3", data.cards[0].list.id);
    });
  });

  it('should has List', function(){
    fs.readFile('test/data/testdata-Data-1.json', 'utf8', function(err, data) {
      if (err) throw err;
      var data = new TrelloReader.Data(JSON.parse(data));
      assert.equal('514e2ed443663060620025f3', data.listsHash['514e2ed443663060620025f3'].id);
    });
  });

  it('should has List', function(){
    fs.readFile('test/data/testdata-Data-1.json', 'utf8', function(err, data) {
      if (err) throw err;
      var data = new TrelloReader.Data(JSON.parse(data));
      assert.equal(3, data.lists.length);
      assert.equal("514e2ed443663060620025f3", data.lists[0].id);
      assert.equal("514e2ed443663060620025f4", data.lists[1].id);
      assert.equal("514e2ed443663060620025f5", data.lists[2].id);
    });
  });

  it('should has card list with relations to cards', function(){
    fs.readFile('test/data/testdata-Data-1.json', 'utf8', function(err, data) {
      if (err) throw err;
      var data = new TrelloReader.Data(JSON.parse(data));
      assert.equal(1, data.lists[0].cards.length);
      assert.equal("514e2f8fb6f1dd2d7c002dce", data.lists[0].cards[0].id);
    });
  });
});

<commit_msg>refactoring test/Data.js<commit_after>// vim:sw=2:ts=2:et:
var assert = require("assert");
var fs = require('fs')
var TrelloReader = require("../trello-json-reader");

describe('TrelloReader.Data', function(){
  it('should return a instance of Data class', function(){
    assert.equal(true, (new TrelloReader.Data()) instanceof TrelloReader.Data);
  });

  it('should return a instance of Data class (file load)', function(){
    fs.readFile('test/data/testdata-Data-1.json', 'utf8', function(err, data) {
      if (err) throw err;
      assert.equal(true, (new TrelloReader.Data(JSON.parse(data))) instanceof TrelloReader.Data);
    });
  });
});

describe('TrelloReader.Data.activity', function(){
  it('should has a list', function(){
    fs.readFile('test/data/testdata-Data-1.json', 'utf8', function(err, data) {
      if (err) throw err;
      var data = new TrelloReader.Data(JSON.parse(data));
      assert.equal(2, data.activities.length);
      assert.equal("514e2f8fb6f1dd2d7c002dcf", data.activities[0].id);
      assert.equal("514e2ed443663060620025f7", data.activities[1].id);
      assert.equal(undefined, data.activities[2]);
    });
  });
});

describe('TrelloReader.Data.cards', function(){
  it('should has a list', function(){
    fs.readFile('test/data/testdata-Data-1.json', 'utf8', function(err, data) {
      if (err) throw err;
      var data = new TrelloReader.Data(JSON.parse(data));
      assert.equal(1, data.cards.length);
      assert.equal("514e2f8fb6f1dd2d7c002dce", data.cards[0].id);
      assert.equal(undefined, data.cards[1]);
    });
  });

  it('should has relations with list', function(){
    fs.readFile('test/data/testdata-Data-1.json', 'utf8', function(err, data) {
      if (err) throw err;
      var data = new TrelloReader.Data(JSON.parse(data));
      assert.equal("514e2ed443663060620025f3", data.cards[0].idList);
      assert.equal("514e2ed443663060620025f3", data.cards[0].list.id);
    });
  });
});

describe('TrelloReader.Data.listsHash', function(){
  it('should has a list internaly', function(){
    fs.readFile('test/data/testdata-Data-1.json', 'utf8', function(err, data) {
      if (err) throw err;
      var data = new TrelloReader.Data(JSON.parse(data));
      assert.equal('514e2ed443663060620025f3', data.listsHash['514e2ed443663060620025f3'].id);
    });
  });
});

describe('TrelloReader.Data.lists', function(){
  it('should has list', function(){
    fs.readFile('test/data/testdata-Data-1.json', 'utf8', function(err, data) {
      if (err) throw err;
      var data = new TrelloReader.Data(JSON.parse(data));
      assert.equal(3, data.lists.length);
      assert.equal("514e2ed443663060620025f3", data.lists[0].id);
      assert.equal("514e2ed443663060620025f4", data.lists[1].id);
      assert.equal("514e2ed443663060620025f5", data.lists[2].id);
    });
  });

  it('should has relations with cards', function(){
    fs.readFile('test/data/testdata-Data-1.json', 'utf8', function(err, data) {
      if (err) throw err;
      var data = new TrelloReader.Data(JSON.parse(data));
      assert.equal(1, data.lists[0].cards.length);
      assert.equal("514e2f8fb6f1dd2d7c002dce", data.lists[0].cards[0].id);
    });
  });
});

<|endoftext|>


<commit_before>(function() {

internets.InternetsBrowser = function(map) {
  google.maps.event.addListener(map, 'idle', refreshInternets);
  $('input#filter-lan').add('input#filter-wifi').change(refreshInternets);
  var internets_list = $('ul#internets-list');

  return {
  }

  function refreshInternets() {
    var bounds = map.getBounds();
    var ne = bounds.getNorthEast(), sw = bounds.getSouthWest();
    var data = { top: ne.lat(), right: ne.lng(),
                 bottom: sw.lat(), left: sw.lng() };

    loadLanList(data, function(lan_list) {
      loadWifiList(data, function(wifi_list) {
        showInternets(lan_list, wifi_list);
      });
    });

    function loadLanList(data, callback) {
      if(! $('input#filter-lan').is(':checked')) { callback([]); return; }
      $.get('/api/lan', data, callback);
    }
    function loadWifiList(data, callback) {
      if(! $('input#filter-wifi').is(':checked')) { callback([]); return; }
      $.get('/api/wifi', data, callback);
    }

    function showInternets(lan_list, wifi_list) {
      $('> li.lan', internets_list).each(function() {
        $(this).data('polygon').setMap(null);
      });
      $('> li.wifi', internets_list).each(function() {
        $(this).data('marker').setMap(null);
      });
      internets_list.empty();
      $.each(lan_list, function(i, lan_data) { createLan(lan_data); });
      $.each(wifi_list, function(i, wifi_data) { createWifi(wifi_data); });
    }
  }

  function createWifi(wifi_data) {
    var coord = new google.maps.LatLng(wifi_data.geo.lat, wifi_data.geo.lon);
    var marker = new google.maps.Marker({ map: map, position: coord,
                                          icon: internets.icon_normal });
    var li = $('
').text(wifi_data['name']);
    li.data('marker', marker);
    internets_list.append(li);
  }

  function createLan(lan_data) {
    var points = new google.maps.MVCArray();
    $.each(JSON.parse(lan_data['geo']['points_json']), function(i, p) {
      points.push(new google.maps.LatLng(p.lat, p.lon));
    });
    var polygon = new google.maps.Polygon({ map: map, paths: points });
    google.maps.event.addListener(polygon, 'click', focusOnLan);

    var li = $('
').text(lan_data['name']);
    styleNormal();
    li.mouseover(styleHighlight);
    li.mouseout(styleNormal);
    li.click(focusOnLan);

    li.data('polygon', polygon);
    internets_list.append(li);

    function styleHighlight() {
      polygon.setOptions({fillOpacity: .6});
    }

    function styleNormal() {
      polygon.setOptions({fillOpacity: .3});
    }

    function focusOnLan() {
      var geo = lan_data['geo'];
      var ne = new google.maps.LatLng(geo['bbox_top'], geo['bbox_right']);
      var sw = new google.maps.LatLng(geo['bbox_bottom'], geo['bbox_left']);
      map.fitBounds(new google.maps.LatLngBounds(sw, ne));
    }
  }
}

})();
<commit_msg>Show bubble on poly click<commit_after>(function() {

internets.InternetsBrowser = function(map) {
  google.maps.event.addListener(map, 'idle', refreshInternets);
  $('input#filter-lan').add('input#filter-wifi').change(refreshInternets);
  var internets_list = $('ul#internets-list');

  return {
  }

  function refreshInternets() {
    var bounds = map.getBounds();
    var ne = bounds.getNorthEast(), sw = bounds.getSouthWest();
    var data = { top: ne.lat(), right: ne.lng(),
                 bottom: sw.lat(), left: sw.lng() };

    loadLanList(data, function(lan_list) {
      loadWifiList(data, function(wifi_list) {
        showInternets(lan_list, wifi_list);
      });
    });

    function loadLanList(data, callback) {
      if(! $('input#filter-lan').is(':checked')) { callback([]); return; }
      $.get('/api/lan', data, callback);
    }
    function loadWifiList(data, callback) {
      if(! $('input#filter-wifi').is(':checked')) { callback([]); return; }
      $.get('/api/wifi', data, callback);
    }

    function showInternets(lan_list, wifi_list) {
      $('> li.lan', internets_list).each(function() {
        $(this).data('polygon').setMap(null);
      });
      $('> li.wifi', internets_list).each(function() {
        $(this).data('marker').setMap(null);
      });
      internets_list.empty();
      $.each(lan_list, function(i, lan_data) { createLan(lan_data); });
      $.each(wifi_list, function(i, wifi_data) { createWifi(wifi_data); });
    }
  }

  function createWifi(wifi_data) {
    var coord = new google.maps.LatLng(wifi_data.geo.lat, wifi_data.geo.lon);
    var marker = new google.maps.Marker({ map: map, position: coord,
                                          icon: internets.icon_normal });
    var li = $('
').text(wifi_data['name']);
    li.data('marker', marker);
    internets_list.append(li);
  }

  function createLan(lan_data) {
    var points = new google.maps.MVCArray();
    $.each(JSON.parse(lan_data['geo']['points_json']), function(i, p) {
      points.push(new google.maps.LatLng(p.lat, p.lon));
    });
    var polygon = new google.maps.Polygon({ map: map, paths: points });
    google.maps.event.addListener(polygon, 'click', focusOnLan);

    var li = $('
').text(lan_data['name']);
    styleNormal();
    li.mouseover(styleHighlight);
    li.mouseout(styleNormal);
    li.click(focusOnLan);

    li.data('polygon', polygon);
    internets_list.append(li);

    function styleHighlight() {
      polygon.setOptions({fillOpacity: .6});
    }

    function styleNormal() {
      polygon.setOptions({fillOpacity: .3});
    }

    function focusOnLan(event) {
      var geo = lan_data['geo'];
      var ne = new google.maps.LatLng(geo['bbox_top'], geo['bbox_right']);
      var sw = new google.maps.LatLng(geo['bbox_bottom'], geo['bbox_left']);
      map.fitBounds(new google.maps.LatLngBounds(sw, ne));
      showBubble()
    }

    function showBubble(){
      var bubble = new google.maps.InfoWindow({
        content:
          "
"+lan_data['name']+"
" +
          "
"+lan_data['info']+"
"
      });
      polygon.position = polygon.getPath().getAt(0);
      bubble.open(map, polygon);
    }
  }
}

})();
<|endoftext|>


<commit_before><commit_msg>List module tests<commit_after>import { expect } from 'chai';
import List from '../src/List';

describe('List.js', () => {
  describe('List.each', () => {
    it('Should apply a function to each item in a list, not returning any value', () => {
      const input = [1, 2, 3, 4, 5];
      const output = [];
      const expected = [2, 3, 4, 5, 6];
      List.each((x) => output.push(++x), input);
      expect(output).to.deep.equal(expected);
    });
    it('Should apply a function to each item in a list, not returning any value, partially', () => {
      const input = [1, 2, 3, 4, 5];
      const output = [];
      const expected = [2, 3, 4, 5, 6];
      List.each((x) => output.push(++x))(input);
      expect(output).to.deep.equal(expected);
    });
  });

  describe('List.map', () => {
    it('Should apply a function to each item in a list, returning a new list with the result', () => {
      const input = [1, 2, 3, 4, 5];
      expect(List.map((x) => ++x, input)).to.deep.equal([2, 3, 4, 5, 6]);
    });
    it('Should apply a function to each item in a list, returning a new list with the result, partially', () => {
      const input = [1, 2, 3, 4, 5];
      expect(List.map((x) => ++x)(input)).to.deep.equal([2, 3, 4, 5, 6]);
    });
  });
});
<|endoftext|>


<commit_before>module.exports = {
  minPageNr: 151,
  maxPageNr: 200
}
<commit_msg>indexer: add config file<commit_after>module.exports = {
  minPageNr: 751,
  maxPageNr: 800
}
<|endoftext|>


<commit_before>/*global describe, it*/
var expect = require('unexpected'),
    Mail = require('../lib/Mail');

describe('Mail', function () {
    it('should rfc2047 decode the header values', function () {
        var mail = new Mail('Subject: =?iso-8859-1?Q?=A1?=Hola, se=?iso-8859-1?Q?=F1?=or!');
        expect(mail.headers.get('subject'), 'to equal', '¡Hola, señor!');
    });

    it('should rfc2047 encode when serializing', function () {
        var mail = new Mail({body: 'bar'});
        mail.headers.set('subject', '¡Hola, señor!');
        expect(mail.toString(), 'to equal', 'Subject: =?iso-8859-1?Q?=A1Hola=2C?= =?iso-8859-1?Q?_se=F1or!?=\r\n\r\nbar');
    });

    describe('#fileName', function () {
        describe('when invoked as a getter', function () {
            it('should fall back to the name property of the Content-Type header when the Content-Disposition header has no filename parameter', function () {
                var mail = new Mail(
                    'Content-Transfer-Encoding: base64\r\n' +
                    'Content-Disposition: attachment\r\n' +
                    'Content-Type: image/png; name="=?iso-8859-1?Q?=E6=F8=E5.png?="'
                );
                expect(mail.fileName, 'to equal', 'æøå.png');
            });

            it('should fall back to the name property of the Content-Type header when there is no Content-Disposition header', function () {
                var mail = new Mail(
                    'Content-Transfer-Encoding: base64\r\n' +
                    'Content-Type: image/png; name="=?iso-8859-1?Q?=E6=F8=E5.png?="'
                );
                expect(mail.fileName, 'to equal', 'æøå.png');
            });
        });

        describe('when invoked as a setter', function () {
            it('should update the name property of the Content-Type header if available', function () {
                var mail = new Mail({headers: {'Content-Type': 'image/png'}});
                mail.fileName = 'æøå.png';
                expect(
                    mail.toString(),
                    'to equal',
                    // TODO: Would be better to emit 'Content-Type: image/png; name="=?iso-8859-1?Q?=E6=F8=E5.png?="\r\n' +
                    'Content-Type: image/png; =?iso-8859-1?Q?name==E6=F8=E5?=.png\r\n' +
                    'Content-Disposition: attachment;\r\n' +
                    " filename*=iso-8859-1''%E6%F8%E5%2E%70%6E%67\r\n"
                );
            });
        });
    });
});
<commit_msg>Fix tests.<commit_after>/*global describe, it*/
var expect = require('unexpected'),
    Mail = require('../lib/Mail');

describe('Mail', function () {
    it('should rfc2047 decode the header values', function () {
        var mail = new Mail('Subject: =?iso-8859-1?Q?=A1?=Hola, se=?iso-8859-1?Q?=F1?=or!');
        expect(mail.headers.get('subject'), 'to equal', '¡Hola, señor!');
    });

    it('should rfc2047 encode when serializing', function () {
        var mail = new Mail({body: 'bar'});
        mail.headers.set('subject', '¡Hola, señor!');
        expect(mail.toString(), 'to equal', 'Subject: =?utf-8?Q?=C2=A1Hola=2C?= =?utf-8?Q?_se=C3=B1or!?=\r\n\r\nbar');
    });

    describe('#fileName', function () {
        describe('when invoked as a getter', function () {
            it('should fall back to the name property of the Content-Type header when the Content-Disposition header has no filename parameter', function () {
                var mail = new Mail(
                    'Content-Transfer-Encoding: base64\r\n' +
                    'Content-Disposition: attachment\r\n' +
                    'Content-Type: image/png; name="=?iso-8859-1?Q?=E6=F8=E5.png?="'
                );
                expect(mail.fileName, 'to equal', 'æøå.png');
            });

            it('should fall back to the name property of the Content-Type header when there is no Content-Disposition header', function () {
                var mail = new Mail(
                    'Content-Transfer-Encoding: base64\r\n' +
                    'Content-Type: image/png; name="=?iso-8859-1?Q?=E6=F8=E5.png?="'
                );
                expect(mail.fileName, 'to equal', 'æøå.png');
            });
        });

        describe('when invoked as a setter', function () {
            it('should update the name property of the Content-Type header if available', function () {
                var mail = new Mail({headers: {'Content-Type': 'image/png'}});
                mail.fileName = 'æøå.png';
                expect(
                    mail.toString(),
                    'to equal',
                    // TODO: Would be better to emit 'Content-Type: image/png; name="=?iso-8859-1?Q?=E6=F8=E5.png?="\r\n' +
                    'Content-Type: image/png; =?utf-8?Q?name=3D=C3=A6=C3=B8=C3=A5?=.png\r\n' +
                    'Content-Disposition: attachment;\r\n' +
                    " filename*=iso-8859-1''%E6%F8%E5%2E%70%6E%67\r\n"
                );
            });
        });
    });
});
<|endoftext|>


<commit_before>(function($) {
  /**
   * Visualization-related variables from the outside.
   */
  jQuery.visualization = { };

  $(document).ready(function() {
    if (typeof $.visualization.dataUrl != 'undefined') {
      var flashvars = {
          startup_data_URL: $.visualization.dataUrl,

          callback_onGroupSelection: "onGroupSelection",
          callback_onDocumentSelection: "onDocumentSelection",
          openDocumentsOnClick: true,

          documentsPanel: "AUTO",
          maxVisibleDocuments: 400,

          logo: "carrot2"
        };

      var params = {};
      var attributes = {};

      swfobject.embedSWF($.visualization.skinPath + "/common-dynamic/swf/org.carrotsearch.vis.circles.swf",
          "clusters-visu", "100%", "100%", "10.0.0", $.visualization.skinPath + "/common/swf/expressInstall.swf",
          flashvars, params, attributes);
    }
  });

  /** Safari layout bug hack */
  $(window).load(function() {
    if ($.browser.safari) {
      $("#clusters-visu").css("display", "block");
    }
  });
})(jQuery);

/**
 * An array of selected cluster IDs in the visualization SWF.
 */
var selectedClusters = [];

// Callback function invoked by the visualization:
// a group has been selected or deselected.
function onGroupSelection(clusterId, isSelected, docList) {
  var i  = jQuery.inArray(clusterId, selectedClusters);

  // If re-selected, re-push at the top of the stack.
  if (i != -1) selectedClusters.splice(i, 1);
  if (isSelected) selectedClusters.unshift(clusterId);

  if (selectedClusters.length == 0) {
    $("#clusters-panel").trigger("carrot2-clusters-selected-top");
  } else {
    /*
     * TODO: selectedClusters contains identifiers of clusters to be shown.
     * one could either merge their documents, or display one cluster after
     * another in the documents panel (my pick).
     *
     * Documents from each cluster could be stored in a hash locally here,
     * but it probably makes more sense to reuse the flattenedDocuments array
     * (or jQuery.clusters.documents) function), which contains document lists
     * for each cluster ID anyway.
     *
     * For now, that function is not properly initialized when visualization
     * panel is shown, so I comment out the code below, but you get the point.
     */
    // var clusterId = selectedClusters[0];
    // var documentIndexes = jQuery.clusters.documents(clusterId);
    // $("#clusters-panel").trigger("carrot2-clusters-selected", [ clusterId, documentIndexes ]);
  }
}

// Callback function invoked by the visualization:
// selection has been cleared
function selectionCleared() {
  $("#clusters-panel").trigger("carrot2-clusters-selected-top");
}

// Callback function invoked by the visualization
function onDocumentSelection(documentId) {
  // Ignore the click feedback, using flash directly to open a new
  // browser window (see openDocumentsOnClick above).
  //
  // window.open($("#d" + documentId + " a.title").attr("href"));
}
<commit_msg>- Implemented a temporary workaround that duplicates flattenedDocuments inside the visualization/JS code   and shows the first cluster from the active selection list.<commit_after>(function($) {
  /**
   * Visualization-related variables from the outside.
   */
  jQuery.visualization = { };

  $(document).ready(function() {
    if (typeof $.visualization.dataUrl != 'undefined') {
      var flashvars = {
          startup_data_URL: $.visualization.dataUrl,

          callback_onGroupSelection: "onGroupSelection",
          callback_onDocumentSelection: "onDocumentSelection",
          openDocumentsOnClick: true,

          documentsPanel: "AUTO",
          maxVisibleDocuments: 400,

          logo: "carrot2"
        };

      var params = {};
      var attributes = {};

      swfobject.embedSWF($.visualization.skinPath + "/common-dynamic/swf/org.carrotsearch.vis.circles.swf",
          "clusters-visu", "100%", "100%", "10.0.0", $.visualization.skinPath + "/common/swf/expressInstall.swf",
          flashvars, params, attributes);
    }
  });

  /** Safari layout bug hack */
  $(window).load(function() {
    if ($.browser.safari) {
      $("#clusters-visu").css("display", "block");
    }
  });
})(jQuery);

/**
 * An array of selected cluster IDs in the visualization SWF.
 */
var selectedClusters = [];

/**
 * A cache of document identifiers for each cluster ID, as given by
 * the visualization. The same data is created in carrot2.clusters.core.js,
 * so perhaps we could reuse it?
 */
var flattenedDocuments0 = {};

// Callback function invoked by the visualization:
// a group has been selected or deselected.
function onGroupSelection(clusterId, isSelected, docList) {
  var i  = jQuery.inArray(clusterId, selectedClusters);

  // If re-selected, re-push at the top of the stack.
  if (i != -1) selectedClusters.splice(i, 1);
  if (isSelected) selectedClusters.unshift(clusterId);

  if (selectedClusters.length == 0) {
    $("#clusters-panel").trigger("carrot2-clusters-selected-top");
  } else {
    /*
     * TODO: selectedClusters contains identifiers of clusters to be shown.
     * one could either merge their documents, or display one cluster after
     * another in the documents panel (my pick).
     */
    flattenedDocuments0[clusterId] = docList.split(",");

    var cluster = selectedClusters[0];
    var documentIndexes = flattenedDocuments0[cluster];
    $("#clusters-panel").trigger("carrot2-clusters-selected", [ cluster, documentIndexes ]);
  }
}

// Callback function invoked by the visualization:
// selection has been cleared
function selectionCleared() {
  $("#clusters-panel").trigger("carrot2-clusters-selected-top");
}

// Callback function invoked by the visualization
function onDocumentSelection(documentId) {
  // Ignore the click feedback, using flash directly to open a new
  // browser window (see openDocumentsOnClick above).
  //
  // window.open($("#d" + documentId + " a.title").attr("href"));
}
<|endoftext|>