<commit_before>// muri

/**
 * MongoDB URI parser as described here:
 * http://www.mongodb.org/display/DOCS/Connections
 */

/**
 * Module dependencies
 */

var url = require('url');
var qs = require('querystring');

/**
 * Defaults
 */

const DEFAULT_PORT = 27017;
const DEFAULT_DB = 'admin';

/**
 * Muri
 */

module.exports = exports = function muri (str) {
  if (!/^mongodb:\/\//.test(str)) {
    throw new Error('Invalid mongodb uri. Must begin with "mongodb://"');
  }

  var ret = {
      hosts: []
    , db: 'admin'
    , options: {}
  }

  var match = /^mongodb:\/\/([^\/?]+)(\/?.*)$/.exec(str);
  if (!match) {
    throw new Error('Invalid mongodb uri. Missing hostname');
  }

  var uris = match[1];
  var path = match[2];

  uris.split(',').forEach(function (uri) {
    var o = url.parse('mongodb://' + uri);

    if (o.hostname) {
      ret.hosts.push({
          host: o.hostname
        , port: parseInt(o.port || DEFAULT_PORT, 10)
      })
    }

    if (o.auth) {
      var auth = o.auth.split(':');
      ret.auth = {
          user: auth[0]
        , pass: auth[1]
      }
    }
  })

  var parts = path.split('?');
  if (parts[0]) {
    var db = parts[0].replace(/^\//, '');
    if (db) {
      ret.db = db;
    }
  }

  if (parts[1]) {
    ret.options = options(parts[1]);
  }

  return ret;
}

/**
 * Version
 */

module.exports.version = JSON.parse(
  require('fs').readFileSync(__dirname + '/../package.json', 'utf8')
).version;

/**
 * Parse str into key/val pairs casting values appropriately.
 */

function options (str) {
  var sep = /;/.test(str)
    ? ';'
    : '&';

  var ret = qs.parse(str, sep);

  Object.keys(ret).forEach(function (key) {
    var val = ret[key];
    var num;

    if ('true' == val) {
      val = true;
    } else if ('false' == val) {
      val = false;
    } else {
      num = parseInt(val, 10);
      if (!isNaN(num)) {
        val = num;
      }
    }

    ret[key] = val;
  });

  return ret;
}
<commit_msg>refactor<commit_after>// muri

/**
 * MongoDB URI parser as described here:
 * http://www.mongodb.org/display/DOCS/Connections
 */

/**
 * Module dependencies
 */

var url = require('url');
var qs = require('querystring');

/**
 * Defaults
 */

const DEFAULT_PORT = 27017;
const DEFAULT_DB = 'admin';

/**
 * Muri
 */

module.exports = exports = function muri (str) {
  if (!/^mongodb:\/\//.test(str)) {
    throw new Error('Invalid mongodb uri. Must begin with "mongodb://"');
  }

  var ret = {
      hosts: []
    , db: 'admin'
    , options: {}
  }

  var match = /^mongodb:\/\/([^\/?]+)(\/?.*)$/.exec(str);
  if (!match) {
    throw new Error('Invalid mongodb uri. Missing hostname');
  }

  var uris = match[1];
  var path = match[2];

  uris.split(',').forEach(function (uri) {
    var o = url.parse('mongodb://' + uri);

    if (o.hostname) {
      ret.hosts.push({
          host: o.hostname
        , port: parseInt(o.port || DEFAULT_PORT, 10)
      })
    }

    if (o.auth) {
      var auth = o.auth.split(':');
      ret.auth = {
          user: auth[0]
        , pass: auth[1]
      }
    }
  })

  var parts = path.split('?');
  if (parts[0]) {
    var db = parts[0].replace(/^\//, '');
    if (db) {
      ret.db = db;
    }
  }

  if (parts[1]) {
    ret.options = options(parts[1]);
  }

  return ret;
}

/**
 * Parse str into key/val pairs casting values appropriately.
 */

function options (str) {
  var sep = /;/.test(str)
    ? ';'
    : '&';

  var ret = qs.parse(str, sep);

  Object.keys(ret).forEach(function (key) {
    var val = ret[key];
    var num;

    if ('true' == val) {
      val = true;
    } else if ('false' == val) {
      val = false;
    } else {
      num = parseInt(val, 10);
      if (!isNaN(num)) {
        val = num;
      }
    }

    ret[key] = val;
  });

  return ret;
}

/**
 * Version
 */

module.exports.version = JSON.parse(
  require('fs').readFileSync(__dirname + '/../package.json', 'utf8')
).version;
<|endoftext|>


<commit_before>'use strict';

function check_todo(object, key){
    if(object.hasOwnProperty(key)
      && !object[key]['loop']){
        object[key]['todo']();
    }
}

function get_keycode(event){
    var code = event.keyCode || event.which;
    return {
      'code': code,
      'key': String.fromCharCode(code),
    };
}

function handle_keydown(event){
    var key = get_keycode(event);

    if(keys.hasOwnProperty(key['code'])){
        keys[key['code']]['state'] = true;
        if(!keys[key['code']]['loop']){
            keys[key['code']]['todo']();
        }
    }

    if(keys.hasOwnProperty('all')
      && !keys['all']['loop']){
        keys['all']['todo']();
    }
}

function handle_keyup(event){
    var key = get_keycode(event);

    if(keys.hasOwnProperty(key['code'])){
        keys[key['code']]['state'] = false;
    }
}

function handle_mousedown(event){
    mouse['down'] = true;
    mouse['down-x'] = mouse['x'];
    mouse['down-y'] = mouse['y'];
    check_todo(
      mouse['todo'],
      'mousedown'
    );
}

function handle_mousemove(event){
    mouse['x'] = event.pageX;
    mouse['y'] = event.pageY;
    check_todo(
      mouse['todo'],
      'mousemove'
    );
}

function handle_mouseup(event){
    mouse['down'] = false;
    check_todo(
      mouse['todo'],
      'mouseup'
    );
}

function handle_mousewheel(event){
    var delta = Number(
      event.wheelDelta
        || -event.detail
    );
    check_todo(
      mouse['todo'],
      'mousewheel'
    );
}

function init_input(keybinds, mousebinds){
    keys = {};
    keybinds = keybinds || false;
    if(keybinds !== false){
        for(var key in keybinds){
            keys[key] = {};
            keys[key]['loop'] = keybinds[key]['loop'] || false;
            keys[key]['state'] = false;
            keys[key]['todo'] = keybinds[key]['todo'] || function(){};
        }

        window.onkeydown = handle_keydown;
        window.onkeyup = handle_keyup;
    }

    mouse = {
      'down': false,
      'down-x': 0,
      'down-y': 0,
      'todo': {},
      'x': 0,
      'y': 0,
    };
    mousebinds = mousebinds || false;
    if(mousebinds !== false){
        for(var mousebind in mousebinds){
            mouse['todo'][mousebind] = {};
            mouse['todo'][mousebind]['loop'] = mousebinds[mousebind]['loop'] || false;
            mouse['todo'][mousebind]['todo'] = mousebinds[mousebind]['todo'] || function(){};
        }

        window.onmousedown = handle_mousedown;
        window.onmousemove = handle_mousemove;
        window.onmouseup = handle_mouseup;
        window.ontouchend = handle_mouseup;
        window.ontouchmove = handle_mousemove;
        window.ontouchstart = handle_mousedown;

        if('onmousewheel' in window){
            window.onmousewheel = handle_mousewheel;

        }else{
            document.addEventListener(
              'DOMMouseScroll',
              handle_mousewheel,
              false
            );
        }
    }
}

function repeat_input_todos(){
    for(var key in keys){
        if(keys[key]['loop']){
            keys[key]['todo']();
        }
    }
    for(var mousebind in mouse['todo']){
        if(mouse['todo'][mousebind]['loop']){
            mouse['todo'][mousebind]['todo']();
        }
    }
}

var keys = {};
var mouse = {};
<commit_msg>only run looping keys that are down<commit_after>'use strict';

function check_todo(object, key){
    if(object.hasOwnProperty(key)
      && !object[key]['loop']){
        object[key]['todo']();
    }
}

function get_keycode(event){
    var code = event.keyCode || event.which;
    return {
      'code': code,
      'key': String.fromCharCode(code),
    };
}

function handle_keydown(event){
    var key = get_keycode(event);

    if(keys.hasOwnProperty(key['code'])){
        keys[key['code']]['state'] = true;
        if(!keys[key['code']]['loop']){
            keys[key['code']]['todo']();
        }
    }

    if(keys.hasOwnProperty('all')
      && !keys['all']['loop']){
        keys['all']['todo']();
    }
}

function handle_keyup(event){
    var key = get_keycode(event);

    if(keys.hasOwnProperty(key['code'])){
        keys[key['code']]['state'] = false;
    }
}

function handle_mousedown(event){
    mouse['down'] = true;
    mouse['down-x'] = mouse['x'];
    mouse['down-y'] = mouse['y'];
    check_todo(
      mouse['todo'],
      'mousedown'
    );
}

function handle_mousemove(event){
    mouse['x'] = event.pageX;
    mouse['y'] = event.pageY;
    check_todo(
      mouse['todo'],
      'mousemove'
    );
}

function handle_mouseup(event){
    mouse['down'] = false;
    check_todo(
      mouse['todo'],
      'mouseup'
    );
}

function handle_mousewheel(event){
    var delta = Number(
      event.wheelDelta
        || -event.detail
    );
    check_todo(
      mouse['todo'],
      'mousewheel'
    );
}

function init_input(keybinds, mousebinds){
    keys = {};
    keybinds = keybinds || false;
    if(keybinds !== false){
        for(var key in keybinds){
            keys[key] = {};
            keys[key]['loop'] = keybinds[key]['loop'] || false;
            keys[key]['state'] = false;
            keys[key]['todo'] = keybinds[key]['todo'] || function(){};
        }

        window.onkeydown = handle_keydown;
        window.onkeyup = handle_keyup;
    }

    mouse = {
      'down': false,
      'down-x': 0,
      'down-y': 0,
      'todo': {},
      'x': 0,
      'y': 0,
    };
    mousebinds = mousebinds || false;
    if(mousebinds !== false){
        for(var mousebind in mousebinds){
            mouse['todo'][mousebind] = {};
            mouse['todo'][mousebind]['loop'] = mousebinds[mousebind]['loop'] || false;
            mouse['todo'][mousebind]['todo'] = mousebinds[mousebind]['todo'] || function(){};
        }

        window.onmousedown = handle_mousedown;
        window.onmousemove = handle_mousemove;
        window.onmouseup = handle_mouseup;
        window.ontouchend = handle_mouseup;
        window.ontouchmove = handle_mousemove;
        window.ontouchstart = handle_mousedown;

        if('onmousewheel' in window){
            window.onmousewheel = handle_mousewheel;

        }else{
            document.addEventListener(
              'DOMMouseScroll',
              handle_mousewheel,
              false
            );
        }
    }
}

function repeat_input_todos(){
    for(var key in keys){
        if(keys[key]['loop']
          && keys[key]['state']){
            keys[key]['todo']();
        }
    }
    for(var mousebind in mouse['todo']){
        if(mouse['todo'][mousebind]['loop']){
            mouse['todo'][mousebind]['todo']();
        }
    }
}

var keys = {};
var mouse = {};
<|endoftext|>


<commit_before>var async = require('async');
var Logger = require('bunyan');
var restify = require('restify');

var createUfdsModel = require('./models').createUfdsModel;
var createServer = require('./server').createServer;
var Heartbeater = require('./heartbeater');
var Ur = require('./ur');

function CNAPI(config) {
    this.config = config;
    this.servers = {};
    this.log = new Logger({
        name: 'cnapi',
        level: config.logLevel,
        serializers: {
            err: Logger.stdSerializers.err,
            req: Logger.stdSerializers.req,
            res: restify.bunyan.serializers.response
        }
    });
}

CNAPI.prototype.start = function () {
    var self = this;

    var modelOptions = {
        ufds: self.config.ufds,
        amqp_use_system_config: false,
        amqp: self.config.amqp,
        log: self.log
    };

    var heartbeaterOptions = {
        host: '10.99.99.5',
        log: self.log
    };

    var urOptions = {
        host: '10.99.99.5',
        log: self.log
    };

    async.waterfall([
        function (callback) {
            self.initializeModel(modelOptions, callback);
        },
        function (callback) {
            var serverOptions = {
                model: self.model
            };
            self.initializeServer(serverOptions, callback);
        },
        function (callback) {
            self.initializeHeartbeater(heartbeaterOptions, callback);
        },
        function (callback) {
            self.initializeUr(urOptions, callback);
        }
    ],
    function (error) {
        self.server.listen(8080, function () {
            self.log.info(
                '%s listening at %s',
                self.server.name,
                self.server.url);
        });
    });
};

CNAPI.prototype.initializeModel = function (options, callback) {
    var self = this;

    self.log.info('Initializing model and connecting to ufds');

    var model = self.model = createUfdsModel(options);
    model.connect(function (error) {
        if (error) {
            self.log.error(error, 'Error connecting to ufds');
            return callback(error);
        }
        self.log.debug('Model connected');
        return callback();
    });
};

CNAPI.prototype.initializeServer = function (options, callback) {
    this.server = createServer(options);
    return callback();
};

CNAPI.prototype.initializeHeartbeater = function (options, callback) {
    var self = this;

    var heartbeaterListener = new Heartbeater(options);
    heartbeaterListener.on('heartbeat', self.onHeartbeat.bind(self));
    heartbeaterListener.on('connectionError', function (err) {
        self.log.info('Connection error ' + err.message);
    });

    return callback();
};

CNAPI.prototype.initializeUr = function (options, callback) {
    var self = this;
    var ur = self.ur = new Ur(options);

    ur.connect(function () {
        ur.on('serverStartup', self.onServerStartup.bind(self));

        ur.on('connectionError', function (err) {
            self.log.info('Ur AMQP connection error');
        });
    });

    return callback();
};

CNAPI.prototype.refreshServerFromSysinfo = function (uuid, sysinfo, callback) {
    var self = this;

    if (self.servers[uuid]) {
        self.log.debug('Server %s found in local "cache"', uuid);
        return;
    }

    self.log.info('Server %s not found in cache, checking in ufds', uuid);

    self.model.listServers({ uuid: uuid }, function (list$error, servers) {
        if (list$error) {
            self.log.error(list$error, 'Error listing servers in ufds');
            return callback(list$error);
        }

        if (servers.length > 0) {
            self.log.info('%s already in ufds', uuid);
            self.servers[uuid] = servers[0];
            return callback(null, servers[0]);
        }

        return (
            self.model.createServerFromSysinfo(
                sysinfo,
                function (error, server) {
                    if (error) {
                        self.log.info(error, 'Error creating server in ufds');
                        return;
                    }
                    self.log.debug('Cached server in memory');
                    self.servers[uuid] = server;
                }));
    });
};

CNAPI.prototype.refreshServer = function (uuid, callback) {
    var self = this;

    if (self.servers[uuid]) {
        self.log.debug('Server %s found in local "cache"', uuid);
        callback(null, self.servers[uuid]);
        return;
    }

    self.log.info('Server %s not found in cache, checking in ufds', uuid);

    self.model.listServers({ uuid: uuid }, function (list$error, servers) {
        if (list$error) {
            self.log.error(list$error, 'Error listing servers in ufds');
            callback(list$error);
            return;
        }
        if (servers.length > 0) {
            self.log.info('%s already in ufds', uuid);
            self.servers[uuid] = servers[0];
            if (callback) {
                callback(null, servers[0]);
                return;
            }
        }

        self.ur.serverSysinfo(uuid, function (error, sysinfo) {
            self.model.createServerFromSysinfo(
                sysinfo,
                function (create$error, server) {
                    if (create$error) {
                        self.log.info('Error creating server in ufds');
                        callback(create$error);
                        return;
                    }

                    if (callback) {
                        callback(null, server);
                        return;
                    }
                });
        });
    });
};

CNAPI.prototype.onServerStartup = function (message, routingKey) {
    var self = this;

    var uuid = routingKey.split('.')[2];
    self.log.info('Ur startup message received from %s', uuid);
    self.log.trace(message);

    self.refreshServerFromSysinfo(uuid, message);
};

CNAPI.prototype.onHeartbeat = function (heartbeat, routingKey) {
    var self = this;
    var uuid = routingKey.split('.')[1];
    self.log.debug('Heartbeat (%s) received -- %d zones.',
        uuid, heartbeat[0].length);

    self.refreshServer(uuid, function (error, server) {
        if (error) {
            self.log.error(error, 'Error refreshing server\'s record in ufds');
            return;
        }
        self.servers[uuid] = server;
    });
};

module.exports = CNAPI;
<commit_msg>CNAPI-9: Bump up the maxHttpSockets global to a high enough number<commit_after>var async = require('async');
var Logger = require('bunyan');
var restify = require('restify');
var http = require('http');
var https = require('https');

var createUfdsModel = require('./models').createUfdsModel;
var createServer = require('./server').createServer;
var Heartbeater = require('./heartbeater');
var Ur = require('./ur');

function CNAPI(config) {
    this.config = config;
    this.servers = {};
    this.log = new Logger({
        name: 'cnapi',
        level: config.logLevel,
        serializers: {
            err: Logger.stdSerializers.err,
            req: Logger.stdSerializers.req,
            res: restify.bunyan.serializers.response
        }
    });
}

CNAPI.prototype.start = function () {
    var self = this;

    http.globalAgent.maxSockets = self.config.maxHttpSockets || 100;
    https.globalAgent.maxSockets = self.config.maxHttpSockets || 100;

    var modelOptions = {
        ufds: self.config.ufds,
        amqp_use_system_config: false,
        amqp: self.config.amqp,
        log: self.log
    };

    var heartbeaterOptions = {
        host: '10.99.99.5',
        log: self.log
    };

    var urOptions = {
        host: '10.99.99.5',
        log: self.log
    };

    async.waterfall([
        function (callback) {
            self.initializeModel(modelOptions, callback);
        },
        function (callback) {
            var serverOptions = {
                model: self.model
            };
            self.initializeServer(serverOptions, callback);
        },
        function (callback) {
            self.initializeHeartbeater(heartbeaterOptions, callback);
        },
        function (callback) {
            self.initializeUr(urOptions, callback);
        }
    ],
    function (error) {
        self.server.listen(8080, function () {
            self.log.info(
                '%s listening at %s',
                self.server.name,
                self.server.url);
        });
    });
};

CNAPI.prototype.initializeModel = function (options, callback) {
    var self = this;

    self.log.info('Initializing model and connecting to ufds');

    var model = self.model = createUfdsModel(options);
    model.connect(function (error) {
        if (error) {
            self.log.error(error, 'Error connecting to ufds');
            return callback(error);
        }
        self.log.debug('Model connected');
        return callback();
    });
};

CNAPI.prototype.initializeServer = function (options, callback) {
    this.server = createServer(options);
    return callback();
};

CNAPI.prototype.initializeHeartbeater = function (options, callback) {
    var self = this;

    var heartbeaterListener = new Heartbeater(options);
    heartbeaterListener.on('heartbeat', self.onHeartbeat.bind(self));
    heartbeaterListener.on('connectionError', function (err) {
        self.log.info('Connection error ' + err.message);
    });

    return callback();
};

CNAPI.prototype.initializeUr = function (options, callback) {
    var self = this;
    var ur = self.ur = new Ur(options);

    ur.connect(function () {
        ur.on('serverStartup', self.onServerStartup.bind(self));

        ur.on('connectionError', function (err) {
            self.log.info('Ur AMQP connection error');
        });
    });

    return callback();
};

CNAPI.prototype.refreshServerFromSysinfo = function (uuid, sysinfo, callback) {
    var self = this;

    if (self.servers[uuid]) {
        self.log.debug('Server %s found in local "cache"', uuid);
        return;
    }

    self.log.info('Server %s not found in cache, checking in ufds', uuid);

    self.model.listServers({ uuid: uuid }, function (list$error, servers) {
        if (list$error) {
            self.log.error(list$error, 'Error listing servers in ufds');
            return callback(list$error);
        }

        if (servers.length > 0) {
            self.log.info('%s already in ufds', uuid);
            self.servers[uuid] = servers[0];
            return callback(null, servers[0]);
        }

        return (
            self.model.createServerFromSysinfo(
                sysinfo,
                function (error, server) {
                    if (error) {
                        self.log.info(error, 'Error creating server in ufds');
                        return;
                    }
                    self.log.debug('Cached server in memory');
                    self.servers[uuid] = server;
                }));
    });
};

CNAPI.prototype.refreshServer = function (uuid, callback) {
    var self = this;

    if (self.servers[uuid]) {
        self.log.debug('Server %s found in local "cache"', uuid);
        callback(null, self.servers[uuid]);
        return;
    }

    self.log.info('Server %s not found in cache, checking in ufds', uuid);

    self.model.listServers({ uuid: uuid }, function (list$error, servers) {
        if (list$error) {
            self.log.error(list$error, 'Error listing servers in ufds');
            callback(list$error);
            return;
        }
        if (servers.length > 0) {
            self.log.info('%s already in ufds', uuid);
            self.servers[uuid] = servers[0];
            if (callback) {
                callback(null, servers[0]);
                return;
            }
        }

        self.ur.serverSysinfo(uuid, function (error, sysinfo) {
            self.model.createServerFromSysinfo(
                sysinfo,
                function (create$error, server) {
                    if (create$error) {
                        self.log.info('Error creating server in ufds');
                        callback(create$error);
                        return;
                    }

                    if (callback) {
                        callback(null, server);
                        return;
                    }
                });
        });
    });
};

CNAPI.prototype.onServerStartup = function (message, routingKey) {
    var self = this;

    var uuid = routingKey.split('.')[2];
    self.log.info('Ur startup message received from %s', uuid);
    self.log.trace(message);

    self.refreshServerFromSysinfo(uuid, message);
};

CNAPI.prototype.onHeartbeat = function (heartbeat, routingKey) {
    var self = this;
    var uuid = routingKey.split('.')[1];
    self.log.debug('Heartbeat (%s) received -- %d zones.',
        uuid, heartbeat[0].length);

    self.refreshServer(uuid, function (error, server) {
        if (error) {
            self.log.error(error, 'Error refreshing server\'s record in ufds');
            return;
        }
        self.servers[uuid] = server;
    });
};

module.exports = CNAPI;
<|endoftext|>


<commit_before>/*global MutationObserver, CSSRule */

/**
 * @fileOverview This file contains the /components/ module for emulating Web Components behavior.
 * @name components.js<src>
 * @author Etienne Prud’homme
 * @version 1.0.0
 * @link https://github.com/notetiene/components
 * @todo Keep track of instances. This way, the style tag could be removed.
 * @license GPLv3
 */

/**
 * Module to construct custom components (i.e. Element tree). It tries to emulate the behavior of Web Components while being native HTML.
 * @returns {Object} Methods to register a component ({@link registerElement}) and to create an instance of that component ({@link createElement}).
 * @throws {Error} Errors about component initialization.
 */
var components = (function() {
  if (!String.prototype.trim) {
    String.prototype.trim = function () {
      return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
    };
  }

  function mergeObjects(that, object) {
    var prop;
    for(prop in object) {
      if(object.hasOwnProperty(prop) && that[prop] === undefined) {
        that[prop] = object[prop];
      }
    }
  }

  /**
   * Utility function to parse CSS from a {@link String}.
   * @param {String} styleContent - CSS rules as {@link String}.
   * @returns {CSSRuleList} A list of {@link CSSRule}.
   * @see http://stackoverflow.com/a/14865690
   */
  function rulesForCssText(styleContent) {
    var doc = document.implementation.createHTMLDocument('');
    var styleElement = document.createElement('style');

    styleElement.textContent = styleContent.replace(/\$self/g, '.components-lib-self-component');
    // the style will only be parsed once it is added to a document
    doc.body.appendChild(styleElement);
    return styleElement.sheet.cssRules;
  }

  /**
   * Transform a {@link CSSRuleList} to String while optionally adding
   * a prefix before selectors. Currently only support
   * {@link CSSRuleList} with {@link CSSStyleRule} or
   * {@link CSSMediaRule}.
   * @param {CSSRuleList} ruleList - The list to transform.
   * @param {String} [prefix] - A prefix to add before selectors.
   * @returns {String} The {@link CSSRulesList} transformed into
   * {@link String}.
   * @throws {Error} A rule in {@link ruleList} contains a type not
   * supported.
   */
  function CSSRuleListToString(ruleList, prefix) {
    var i = 0;
    var rule = null;
    var len;
    var result = '';
    var _prefix;
    if(prefix && prefix !== '') {
      _prefix = prefix + ' ';
    } else {
      _prefix = '';
    }

    for(len = ruleList.length; i < len; i++) {
      rule = ruleList[i];

      if(rule.type === CSSRule.MEDIA_RULE) {
        result += ' @media ' + rule.media.mediaText + ' { ';
        result += CSSRuleListToString(rule.cssRules, prefix);
        result += ' }';
        continue;
      }

      if(rule.type !== CSSRule.STYLE_RULE) {
        throw new Error('Only style rules and media rules are ' +
                        'currently supported for style scoping');
      }

      if(rule.selectorText.trim() === '.components-lib-self-component') {
        result += rule.cssText.replace(/\.components-lib-self-component/g, prefix);
        continue;
      }

      result += _prefix + rule.cssText;
    }

    return result;
  }

  /**
   * Utility to add a selector according to {@link topNode} id or
   * classes. Thus, it “makes” the {@link styleContent} scoped.
   * @param {String} styleContent - CSS rules to restrict the
   * scope to {@link topNode}.
   * @param {Node} topNode - A node that has classes that will act as
   * scope.
   */
  function CSSRulesScoped(styleContent, topNode) {
    var rules = rulesForCssText(styleContent);
    var selector = topNode.className;
    var scopedRules = '';

    if(selector.length < 10) {
      throw new Error('“topNode” doesn’t contain classes to act as' +
                      'selector or is too short & risk to have ' +
                      'collisions');
    }

    // Replace spaces with the class selector
    selector = '.' + selector.replace(/ /g, '.');

    scopedRules = CSSRuleListToString(rules, selector);

    return scopedRules;
  }

  /**
   * Inject the {@link customElement} styles if they’re not present
   * already.
   * @param {String} name - The name of the {@link customElement}.
   * @param {String} style - Scoped CSS for the {@link customElement}.
   * @param {DocumentFragment} fragment - Fragment representing the
   * current {@link customElement}.
   * @param {HTMLElement} topNode - The for {@link customElement}.
   * @param {String} topNode - Scoped CSS for instances of
   * {@link customElement}.
   * @returns {HTMLElement} The new {@link topNode} (if any).
   */
  function injectElementStyle(name, style, fragment, topNode, instanceStyle) {
    var styleID = name + '-components-lib-style';
    var styleInjected = document.getElementById(styleID);
    var _style = style || null;
    var styleEl = null;
    var scopedEl = null;
    var className = name + '-components-lib-scoped';

    if(styleInjected !== null ||
       Object.prototype.toString.apply(_style) !== '[object String]') {
      return topNode;
    }

    styleEl = document.createElement('style');
    styleEl.id = styleID;

    // Dirty trick to make the CSS scope. Will probably break many
    // things.
    scopedEl = document.createElement('div');
    scopedEl.className = className;

    if(topNode.style) {
      scopedEl.style.display = topNode.style.display;
    }
    scopedEl.appendChild(topNode);

    topNode = scopedEl;
    fragment.appendChild(scopedEl);
    styleEl.textContent = CSSRulesScoped(style, scopedEl);
    if(instanceStyle && instanceStyle !== '') {
      styleEl.textContent += CSSRulesScoped(instanceStyle, scopedEl);
    }

    document.head.appendChild(styleEl);
    return topNode;
  }

  var customElements = {};

  // Compatibility fix. See: http://stackoverflow.com/a/34292615
  var range = document.createRange();
  range.selectNode(document.body);

  /**
   * Register a custom element.
   * @param {String} _name - The name to identify the custom element.
   * @param {string} _template -
   * @param {Object} _proto - Callbacks for WebComponents. See: http://thejackalofjavascript.com/web-components-future-web/#custELeLifeCyncle
   * @throws {Error} Various errors about a component initialization.
   */
  var registerElement = function(_name, _template, _proto) {
    if(_name.constructor !== String || _name === '') {
      throw new Error('Cannot register the component. The name must be a String.');
    }
    if(_template.constructor !== String || _template === '') {
      throw new Error('Cannot register ' + _name +' component. The template must be a String.');
    }
    if(customElements[_name] !== undefined && customElements.hasOwnProperty(_name)) {
      throw new Error(_name + ' is an already registered component.');
    }

    var proto = _proto || {};

    Object.defineProperty(customElements, _name, {
      enumerable: false,
      configurable: false,
      writable: false,
      value: {
        template: _template,
        proto: proto
      }
    });

  };

  /**
   * Create an instance of a specified element by returning a {@linkcode DocumentFragment}. The responsability to inject the fragment is left to the user. This element must be present in {@link customElements}.
   * @param {String} _name - The unique name of the element.
   * @param {String} _style - Optional style that will be added to the
   * scoped. Note that once an element is created with that attribute, it is no
   * longer possible to add more style with {@link createElement}.
   * @returns {DocumentFragment} - A document fragment containing the element template and its attached callbacks.
   * @throws {Error} Component instantiation error.
   */
  var createElement = function(_name, _style) {
    if(!customElements.hasOwnProperty(_name)) {
      throw new Error('“' + _name + '” is not a registered component');
    }

    var customElement = customElements[_name];
    var customStyle = _style || '';
    var style = customElement.proto.style || undefined;

    // For compatibility reasons, it is the best way to write a String to an
    // Element.
    var fragment = range.createContextualFragment(customElement.template);

    var topNode = null;

    // Take the first Node (not a comment)
    for(var i=0, len=fragment.childNodes.length; i<len; i++) {
      if(fragment.childNodes[i].nodeType === Node.ELEMENT_NODE ||
         fragment.childNodes[i].nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
        topNode = fragment.childNodes[i];
        break;
      }
    }
    // Verifies that there’s at least one node
    if(topNode === null) {
      throw new Error('The “' + _name + '” component doesn’t contain a valid node.');
    }

    topNode = injectElementStyle(_name, style, fragment, topNode, customStyle);

    // Note: using proto.createdCallback is useless here (as far as I know)
    // since it’s handled by the user.
    // Note: not useless at all if we want to hide some operations.
    var createdCallback = customElement.proto.createdCallback || {};

    if(createdCallback instanceof Function) {
      createdCallback.call(topNode);
    }

    // proto.attachedCallback
    // This callback is called when the element is attached to the DOM (i.e. appendChild). It does so because when a DocumentFragment is attached to the DOM, its content is emptied (thus removing its childNodes).
    var attachedCb = customElement.proto.attachedCallback;
    if(attachedCb instanceof Function) {
      var observerAttached = new MutationObserver(function(mutations) {
        for(var i=0, len=mutations.length; i<len; i++) {
          // When a DocumentFragment is appended, it becomes void
          if(mutations[i].type === 'childList' && fragment.childNodes.length === 0) {
            mergeObjects(topNode, fragment);
            attachedCb.call(topNode);
          }
        }
      });
      observerAttached.observe(fragment, {childList: true});
    }

    // proto.attributeChangedCallback
    // This callback is called when an attribute of the container (top most) element changed. It doesn’t include children elements.
    var attributeChangedCb = customElement.proto.attributeChangedCallback;
    if(attributeChangedCb instanceof Function) {
      var observerAttr = new MutationObserver(function(mutations) {
        for(var i = 0, len=mutations.length; i<len; i++) {
          if(mutations[i].type === 'attributes') {
            attributeChangedCb.call(topNode);
          }
        }
      });

      // Only observe attribute mutations
      observerAttr.observe(topNode, {attributes: true});
    }

    // proto.detachedCallback isn’t implemented

    return topNode;
  };

  return {
    registerElement: registerElement,
    createElement: createElement
  };
})();

// components.js<src> ends here
<commit_msg>fix: Use mutation observer instead of fragment<commit_after>/*global MutationObserver, CSSRule */

/**
 * @fileOverview This file contains the /components/ module for emulating Web Components behavior.
 * @name components.js<src>
 * @author Etienne Prud’homme
 * @version 1.0.0
 * @link https://github.com/notetiene/components
 * @todo Keep track of instances. This way, the style tag could be removed.
 * @license GPLv3
 */

/**
 * Module to construct custom components (i.e. Element tree). It tries to emulate the behavior of Web Components while being native HTML.
 * @returns {Object} Methods to register a component ({@link registerElement}) and to create an instance of that component ({@link createElement}).
 * @throws {Error} Errors about component initialization.
 */
var components = (function() {
  if (!String.prototype.trim) {
    String.prototype.trim = function () {
      return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
    };
  }

  function mergeObjects(that, object) {
    var prop;
    for(prop in object) {
      if(object.hasOwnProperty(prop) && that[prop] === undefined) {
        that[prop] = object[prop];
      }
    }
  }

  /**
   * Utility function to parse CSS from a {@link String}.
   * @param {String} styleContent - CSS rules as {@link String}.
   * @returns {CSSRuleList} A list of {@link CSSRule}.
   * @see http://stackoverflow.com/a/14865690
   */
  function rulesForCssText(styleContent) {
    var doc = document.implementation.createHTMLDocument('');
    var styleElement = document.createElement('style');

    styleElement.textContent = styleContent.replace(/\$self/g, '.components-lib-self-component');
    // the style will only be parsed once it is added to a document
    doc.body.appendChild(styleElement);
    return styleElement.sheet.cssRules;
  }

  /**
   * Transform a {@link CSSRuleList} to String while optionally adding
   * a prefix before selectors. Currently only support
   * {@link CSSRuleList} with {@link CSSStyleRule} or
   * {@link CSSMediaRule}.
   * @param {CSSRuleList} ruleList - The list to transform.
   * @param {String} [prefix] - A prefix to add before selectors.
   * @returns {String} The {@link CSSRulesList} transformed into
   * {@link String}.
   * @throws {Error} A rule in {@link ruleList} contains a type not
   * supported.
   */
  function CSSRuleListToString(ruleList, prefix) {
    var i = 0;
    var rule = null;
    var len;
    var result = '';
    var _prefix;
    if(prefix && prefix !== '') {
      _prefix = prefix + ' ';
    } else {
      _prefix = '';
    }

    for(len = ruleList.length; i < len; i++) {
      rule = ruleList[i];

      if(rule.type === CSSRule.MEDIA_RULE) {
        result += ' @media ' + rule.media.mediaText + ' { ';
        result += CSSRuleListToString(rule.cssRules, prefix);
        result += ' }';
        continue;
      }

      if(rule.type !== CSSRule.STYLE_RULE) {
        throw new Error('Only style rules and media rules are ' +
                        'currently supported for style scoping');
      }

      if(rule.selectorText.trim() === '.components-lib-self-component') {
        result += rule.cssText.replace(/\.components-lib-self-component/g, prefix);
        continue;
      }

      result += _prefix + rule.cssText;
    }

    return result;
  }

  /**
   * Utility to add a selector according to {@link topNode} id or
   * classes. Thus, it “makes” the {@link styleContent} scoped.
   * @param {String} styleContent - CSS rules to restrict the
   * scope to {@link topNode}.
   * @param {Node} topNode - A node that has classes that will act as
   * scope.
   */
  function CSSRulesScoped(styleContent, topNode) {
    var rules = rulesForCssText(styleContent);
    var selector = topNode.className;
    var scopedRules = '';

    if(selector.length < 10) {
      throw new Error('“topNode” doesn’t contain classes to act as' +
                      'selector or is too short & risk to have ' +
                      'collisions');
    }

    // Replace spaces with the class selector
    selector = '.' + selector.replace(/ /g, '.');

    scopedRules = CSSRuleListToString(rules, selector);

    return scopedRules;
  }

  /**
   * Inject the {@link customElement} styles if they’re not present
   * already.
   * @param {String} name - The name of the {@link customElement}.
   * @param {String} style - Scoped CSS for the {@link customElement}.
   * @param {DocumentFragment} fragment - Fragment representing the
   * current {@link customElement}.
   * @param {HTMLElement} topNode - The for {@link customElement}.
   * @param {String} topNode - Scoped CSS for instances of
   * {@link customElement}.
   * @returns {HTMLElement} The new {@link topNode} (if any).
   */
  function injectElementStyle(name, style, fragment, topNode, instanceStyle) {
    var styleID = name + '-components-lib-style';
    var styleInjected = document.getElementById(styleID);
    var _style = style || null;
    var styleEl = null;
    var scopedEl = null;
    var className = name + '-components-lib-scoped';

    if(styleInjected !== null ||
       Object.prototype.toString.apply(_style) !== '[object String]') {
      return topNode;
    }

    styleEl = document.createElement('style');
    styleEl.id = styleID;

    // Dirty trick to make the CSS scope. Will probably break many
    // things.
    scopedEl = document.createElement('div');
    scopedEl.className = className;

    if(topNode.style) {
      scopedEl.style.display = topNode.style.display;
    }
    scopedEl.appendChild(topNode);

    topNode = scopedEl;
    fragment.appendChild(scopedEl);
    styleEl.textContent = CSSRulesScoped(style, scopedEl);
    if(instanceStyle && instanceStyle !== '') {
      styleEl.textContent += CSSRulesScoped(instanceStyle, scopedEl);
    }

    document.head.appendChild(styleEl);
    return topNode;
  }

  var customElements = {};

  // Compatibility fix. See: http://stackoverflow.com/a/34292615
  var range = document.createRange();
  range.selectNode(document.body);

  /**
   * Register a custom element.
   * @param {String} _name - The name to identify the custom element.
   * @param {string} _template -
   * @param {Object} _proto - Callbacks for WebComponents. See: http://thejackalofjavascript.com/web-components-future-web/#custELeLifeCyncle
   * @throws {Error} Various errors about a component initialization.
   */
  var registerElement = function(_name, _template, _proto) {
    if(_name.constructor !== String || _name === '') {
      throw new Error('Cannot register the component. The name must be a String.');
    }
    if(_template.constructor !== String || _template === '') {
      throw new Error('Cannot register ' + _name +' component. The template must be a String.');
    }
    if(customElements[_name] !== undefined && customElements.hasOwnProperty(_name)) {
      throw new Error(_name + ' is an already registered component.');
    }

    var proto = _proto || {};

    Object.defineProperty(customElements, _name, {
      enumerable: false,
      configurable: false,
      writable: false,
      value: {
        template: _template,
        proto: proto
      }
    });

  };

  /**
   * Create an instance of a specified element by returning a {@linkcode DocumentFragment}. The responsability to inject the fragment is left to the user. This element must be present in {@link customElements}.
   * @param {String} _name - The unique name of the element.
   * @param {String} _style - Optional style that will be added to the
   * scoped. Note that once an element is created with that attribute, it is no
   * longer possible to add more style with {@link createElement}.
   * @returns {DocumentFragment} - A document fragment containing the element template and its attached callbacks.
   * @throws {Error} Component instantiation error.
   */
  var createElement = function(_name, _style) {
    if(!customElements.hasOwnProperty(_name)) {
      throw new Error('“' + _name + '” is not a registered component');
    }

    var customElement = customElements[_name];
    var customStyle = _style || '';
    var style = customElement.proto.style || undefined;

    // For compatibility reasons, it is the best way to write a String to an
    // Element.
    var fragment = range.createContextualFragment(customElement.template);

    var topNode = null;

    // Take the first Node (not a comment)
    for(var i=0, len=fragment.childNodes.length; i<len; i++) {
      if(fragment.childNodes[i].nodeType === Node.ELEMENT_NODE ||
         fragment.childNodes[i].nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
        topNode = fragment.childNodes[i];
        break;
      }
    }
    // Verifies that there’s at least one node
    if(topNode === null) {
      throw new Error('The “' + _name + '” component doesn’t contain a valid node.');
    }

    topNode = injectElementStyle(_name, style, fragment, topNode, customStyle);

    // Note: using proto.createdCallback is useless here (as far as I know)
    // since it’s handled by the user.
    // Note: not useless at all if we want to hide some operations.
    var createdCallback = customElement.proto.createdCallback || {};

    if(createdCallback instanceof Function) {
      createdCallback.call(topNode);
    }

    // proto.attachedCallback
    // This callback is called when the element is attached to the DOM (i.e. appendChild). It does so because when a DocumentFragment is attached to the DOM, its content is emptied (thus removing its childNodes).
    var attachedCb = customElement.proto.attachedCallback;
    if(attachedCb instanceof Function) {
      var observerAttached = new MutationObserver(function(mutations) {
        for(var i=0, len=mutations.length; i<len; i++) {
          // When a DocumentFragment is appended, it becomes void
          if(mutations[i].type === 'childList' && mutations[i].removedNodes[0] === topNode) {
            // XXX: Is it doing anything?
            mergeObjects(topNode, fragment);
            attachedCb.call(topNode);
          }
        }
      });
      observerAttached.observe(fragment, {childList: true});
    }

    // proto.attributeChangedCallback
    // This callback is called when an attribute of the container (top most) element changed. It doesn’t include children elements.
    var attributeChangedCb = customElement.proto.attributeChangedCallback;
    if(attributeChangedCb instanceof Function) {
      var observerAttr = new MutationObserver(function(mutations) {
        for(var i = 0, len=mutations.length; i<len; i++) {
          if(mutations[i].type === 'attributes') {
            attributeChangedCb.call(topNode);
          }
        }
      });

      // Only observe attribute mutations
      observerAttr.observe(topNode, {attributes: true});
    }

    // proto.detachedCallback isn’t implemented

    return topNode;
  };

  return {
    registerElement: registerElement,
    createElement: createElement
  };
})();

// components.js<src> ends here
<|endoftext|>


<commit_before>define(function (require, exports) {
	const ko = require('knockout');
	const httpService = require('services/http');
	const sharedState = require('atlas-state');
	const config = require('appConfig');
	const authApi = require('services/AuthAPI');
	const vocabularyService = require('services/Vocabulary');
	const commonUtils = require('utils/CommonUtils');
	const hash = require('hash-it').default;
	function getIncludedConceptSetDrawCallback({ searchConceptsColumns }) {
		return async function (settings) {
			if (settings.aoData) {
				const api = this.api();
				const rows = this.api().rows({page: 'current'});
				const data = rows.data();
				// The callback is called even when the table is not really populated with data.
				// In such case we would call API with set of NULLs which both doesn't make sense and breaks some DBs.
				// Therefore, we first check if there is real data to send to API.
				if (data[0] && data[0].CONCEPT_ID) {
					await loadAndApplyAncestors(data);
					const columnIndex = searchConceptsColumns.findIndex(v => v.data === 'ANCESTORS');
					api.cells(null, columnIndex).invalidate();
					rows.nodes().each((element, index) => {
						const rowData = data[index];
						commonUtils.contextSensitiveLinkColor(element, rowData);
						const context = ko.contextFor(element);
						ko.cleanNode(element);
						ko.applyBindings(context, element);
					})
				}
			}
		}
	}

	function getAncestorsModalHandler({ sharedState, ancestors, ancestorsModalIsShown }) {
		return function(conceptId) {
			ancestors(sharedState.includedConcepts()
				.find(v => v.CONCEPT_ID === conceptId)
				.ANCESTORS
				.map(v => ({concept: v})));
			if (!_.isEmpty(ancestors())) {
				ancestorsModalIsShown(true);
			}
		}
	}

	function getAncestorsRenderFunction() {
		return (s,p,d) => {
			const tooltip = d.ANCESTORS.map(d => commonUtils.escapeTooltip(d.CONCEPT_NAME)).join('\n');
			return `<a data-bind="click: d => $parents[1].showAncestorsModal(d.CONCEPT_ID), tooltip: '${tooltip}'">${d.ANCESTORS.length}</a>`
		};
	}

	function enhanceConceptSet(conceptSetItem) {
		return {
			...conceptSetItem,
			isExcluded: ko.observable(conceptSetItem.isExcluded),
			includeDescendants: ko.observable(conceptSetItem.includeDescendants),
			includeMapped: ko.observable(conceptSetItem.includeMapped),
		};
	}

	function loadConceptSet(id) {
		return httpService.doGet(config.api.url + 'conceptset/' + id).then(({ data }) => data);
	}

	function loadConceptSetExpression(conceptSetId) {
		return httpService.doGet(config.api.url + 'conceptset/' + conceptSetId + '/expression').then(({ data }) => data);
	}

	function lookupIdentifiers(identifiers) {
		return httpService.doPost(sharedState.vocabularyUrl() + 'lookup/identifiers', JSON.stringify(identifiers));
	}

	function getInclusionCount(expression) {
		const data = { items: ko.toJS(expression), };
		return httpService.doPost(sharedState.vocabularyUrl() + 'included-concepts/count', data);
	}

	function getGenerationInfo(conceptSetId) {
		return httpService.doGet(config.webAPIRoot + 'conceptset/' + + (conceptSetId || '-1') + '/generationinfo')
			.then(({ data }) => data)
			.catch(authApi.handleAccessDenied);
	}

    function deleteConceptSet(conceptSetId) {
		return httpService.doDelete(config.webAPIRoot + 'conceptset/' + (conceptSetId || '-1'))
			.catch(authApi.handleAccessDenied);
    }

  function exists(name, id) {
		return httpService.doGet(`${config.webAPIRoot}conceptset/${id}/exists?name=${name}`)
			.then(({ data }) => data);
  }

  function saveConceptSet(conceptSet) {
		let promise = new Promise(r => r());
		const url = `${config.api.url}conceptset/${conceptSet.id ? conceptSet.id : ''}`;
		if (conceptSet.id) {
			promise = httpService.doPut(url, conceptSet);
		} else {
			promise = httpService.doPost(url, conceptSet);
		}
		promise.catch(authApi.handleAccessDenied);

		return promise;
	}

	function saveConceptSetItems(id, conceptSetItems) {
		return httpService.doPut(config.api.url + 'conceptset/' + id + '/items', conceptSetItems)
			.catch(authApi.handleAccessDenied);
	}

	function getConceptSet(conceptSetId) {
		return httpService.doGet(config.webAPIRoot + 'conceptset/' + (conceptSetId || '-1'))
			.catch(authApi.handleAccessDenied);
	}

	function getCopyName(id) {
		return httpService.doGet(config.webAPIRoot + 'conceptset/' + (id || "") + "/copy-name")
			.then(({ data }) => data);
	}

	async function loadSourcecodes() {
		sharedState.loadingSourcecodes(true);

		// load mapped
		let identifiers = [];
		let concepts = sharedState.includedConcepts();
		for (var i = 0; i < concepts.length; i++) {
			identifiers.push(concepts[i].CONCEPT_ID);
		}
		try {
			const { data } = await httpService.doPost(`${sharedState.vocabularyUrl()}lookup/mapped`, identifiers);
			sharedState.includedSourcecodes(data);
			return data;
		} catch (err) {
			console.error(err);
		} finally {
			sharedState.loadingSourcecodes(false);
		}
	}

	async function onCurrentConceptSetModeChanged(newMode) {
		let hashcode;
		const loadIncludedWithHash = async function() {
			hashcode = hash(sharedState.conceptSetInclusionIdentifiers());
			if (hashcode !== sharedState.includedHash()) {
				await loadIncluded();
				sharedState.includedHash(hashcode);
			}
		};
		switch (newMode) {
			case 'included-conceptsets':
			case 'included':
				await loadIncludedWithHash();
				break;
			case 'included-sourcecodes':
				await loadIncludedWithHash();
				if (sharedState.includedSourcecodes().length === 0) {
					await loadSourcecodes();
				}
				break;
		}
	}

	async function loadAncestors(ancestors, descendants) {
		const data = { ancestors, descendants };
		return httpService.doPost(sharedState.vocabularyUrl() + 'lookup/identifiers/ancestors', data);
	}

	function loadAndApplyAncestors(data) {
		const selectedConceptIds = sharedState.selectedConcepts().filter(v => !v.isExcluded()).map(v => v.concept.CONCEPT_ID);
		const ids = [];
		$.each(data, idx => {
			const element = data[idx];
			if (_.isEmpty(element.ANCESTORS) && sharedState.selectedConceptsIndex[element.CONCEPT_ID] !== 1) {
				ids.push(element.CONCEPT_ID);
			}
		});
		return new Promise((resolve, reject) => {
			if (!_.isEmpty(selectedConceptIds) && !_.isEmpty(ids)) {
				loadAncestors(selectedConceptIds, ids).then(({ data: ancestors }) => {
					const map = sharedState.includedConceptsMap();
					$.each(data, idx => {
						const line = data[idx];
						const ancArray = ancestors[line.CONCEPT_ID];
						if (!_.isEmpty(ancArray) && _.isEmpty(line.ANCESTORS)) {
							line.ANCESTORS = ancArray.map(conceptId => map[conceptId]);
						}
					});
					resolve();
				});
			} else {
				resolve();
			}
		});
	};

	async function loadIncluded(identifiers) {
		const data = identifiers || sharedState.conceptSetInclusionIdentifiers();
		try {
			sharedState.loadingIncluded(true);
			const response = await httpService.doPost(`${sharedState.vocabularyUrl()}lookup/identifiers`, data);
			await vocabularyService.loadDensity(response.data);
			sharedState.includedConcepts((response.data || []).map(v => ({...v, ANCESTORS: []})));
			const map = response.data.reduce((result, item) => {
				result[item.CONCEPT_ID] = item;
				return result;
			}, {});
			sharedState.includedConceptsMap(map);
			await loadAndApplyAncestors(sharedState.includedConcepts());
		} catch (err) {
			console.error(err);
		} finally {
			sharedState.loadingIncluded(false);
		}
	}

	function setConceptSet(conceptset, expressionItems) {
		var conceptSetItemsToAdd = [];
		expressionItems.forEach((conceptSet) => {
			const conceptSetItem = enhanceConceptSet(conceptSet);

			sharedState.selectedConceptsIndex[conceptSetItem.concept.CONCEPT_ID] = 1;
			conceptSetItemsToAdd.push(conceptSetItem);
		});

		sharedState.selectedConcepts(conceptSetItemsToAdd);
		sharedState.ConceptSet.current({
			name: ko.observable(conceptset.name),
			id: conceptset.id,
			createdBy: conceptset.createdBy,
			createdDate: conceptset.createdDate,
			modifiedBy: conceptset.modifiedBy,
			modifiedDate: conceptset.modifiedDate,
		});
	}

	function setConceptSetExpressionExportItems() {
		var highlightedJson = commonUtils.syntaxHighlight(sharedState.conceptSetExpression());
		sharedState.currentConceptSetExpressionJson(highlightedJson);
		var conceptIdentifierList = [];
		for (var i = 0; i < sharedState.selectedConcepts().length; i++) {
			conceptIdentifierList.push(sharedState.selectedConcepts()[i].concept.CONCEPT_ID);
		}
		sharedState.currentConceptIdentifierList(conceptIdentifierList.join(','));
	}

	// for the current selected concepts:
	// update the export panel
	// resolve the included concepts and update the include concept set identifier list
	function resolveConceptSetExpression(resolveAgainstServer = true) {
		let hashCode = hash(sharedState.conceptSetInclusionIdentifiers());
		if (hashCode !== sharedState.includedHash()) {
			sharedState.includedConcepts.removeAll();
			sharedState.includedSourcecodes.removeAll();
			sharedState.conceptSetInclusionIdentifiers.removeAll();
			sharedState.currentConceptIdentifierList(null);
			sharedState.currentIncludedConceptIdentifierList(null);
		}
		setConceptSetExpressionExportItems(sharedState.conceptSetExpression());
		return resolveAgainstServer ? resolveConceptSetExpressionSimple(sharedState.conceptSetExpression()) : null;
	}

	function resolveConceptSetExpressionSimple(expression, success) {
		const callback = typeof success === 'function'
			? success
			: ({ data }) => {
				let info = data;
				if (!Array.isArray(info)) {
					throw new Error();
				}
				sharedState.conceptSetInclusionIdentifiers(info);
				sharedState.currentIncludedConceptIdentifierList(info.join(','));
			};
		sharedState.resolvingConceptSetExpression(true);
		const resolvingPromise = httpService.doPost(sharedState.vocabularyUrl() + 'resolveConceptSetExpression', expression)
			.then(callback)
			.then(() => sharedState.resolvingConceptSetExpression(false))

		return resolvingPromise;
	}

	function clearConceptSet() {
		sharedState.ConceptSet.current(null);
		sharedState.clearSelectedConcepts();
		resolveConceptSetExpression(false);
		sharedState.ConceptSet.dirtyFlag().reset();
	}

	const api = {
		getIncludedConceptSetDrawCallback: getIncludedConceptSetDrawCallback,
		getAncestorsModalHandler: getAncestorsModalHandler,
		getAncestorsRenderFunction: getAncestorsRenderFunction,
		enhanceConceptSet,
		loadConceptSet,
		loadConceptSetExpression,
		lookupIdentifiers,
		getInclusionCount,
		getCopyName: getCopyName,
		getConceptSet: getConceptSet,
		getGenerationInfo: getGenerationInfo,
		deleteConceptSet: deleteConceptSet,
		exists: exists,
		saveConceptSet,
		saveConceptSetItems,
		loadSourcecodes,
		onCurrentConceptSetModeChanged,
		loadIncluded,
		setConceptSet,
		setConceptSetExpressionExportItems,
		resolveConceptSetExpression,
		resolveConceptSetExpressionSimple,
		clearConceptSet,
	};

	return api;
});<commit_msg>Added vocab parameter to CS expression request (#2281)<commit_after>define(function (require, exports) {
	const ko = require('knockout');
	const httpService = require('services/http');
	const sharedState = require('atlas-state');
	const config = require('appConfig');
	const authApi = require('services/AuthAPI');
	const vocabularyService = require('services/Vocabulary');
	const commonUtils = require('utils/CommonUtils');
	const hash = require('hash-it').default;
	function getIncludedConceptSetDrawCallback({ searchConceptsColumns }) {
		return async function (settings) {
			if (settings.aoData) {
				const api = this.api();
				const rows = this.api().rows({page: 'current'});
				const data = rows.data();
				// The callback is called even when the table is not really populated with data.
				// In such case we would call API with set of NULLs which both doesn't make sense and breaks some DBs.
				// Therefore, we first check if there is real data to send to API.
				if (data[0] && data[0].CONCEPT_ID) {
					await loadAndApplyAncestors(data);
					const columnIndex = searchConceptsColumns.findIndex(v => v.data === 'ANCESTORS');
					api.cells(null, columnIndex).invalidate();
					rows.nodes().each((element, index) => {
						const rowData = data[index];
						commonUtils.contextSensitiveLinkColor(element, rowData);
						const context = ko.contextFor(element);
						ko.cleanNode(element);
						ko.applyBindings(context, element);
					})
				}
			}
		}
	}

	function getAncestorsModalHandler({ sharedState, ancestors, ancestorsModalIsShown }) {
		return function(conceptId) {
			ancestors(sharedState.includedConcepts()
				.find(v => v.CONCEPT_ID === conceptId)
				.ANCESTORS
				.map(v => ({concept: v})));
			if (!_.isEmpty(ancestors())) {
				ancestorsModalIsShown(true);
			}
		}
	}

	function getAncestorsRenderFunction() {
		return (s,p,d) => {
			const tooltip = d.ANCESTORS.map(d => commonUtils.escapeTooltip(d.CONCEPT_NAME)).join('\n');
			return `<a data-bind="click: d => $parents[1].showAncestorsModal(d.CONCEPT_ID), tooltip: '${tooltip}'">${d.ANCESTORS.length}</a>`
		};
	}

	function enhanceConceptSet(conceptSetItem) {
		return {
			...conceptSetItem,
			isExcluded: ko.observable(conceptSetItem.isExcluded),
			includeDescendants: ko.observable(conceptSetItem.includeDescendants),
			includeMapped: ko.observable(conceptSetItem.includeMapped),
		};
	}

	function loadConceptSet(id) {
		return httpService.doGet(config.api.url + 'conceptset/' + id).then(({ data }) => data);
	}

	function loadConceptSetExpression(conceptSetId) {
		return httpService.doGet(config.api.url + 'conceptset/' + conceptSetId + '/expression/' + sharedState.sourceKeyOfVocabUrl()).then(({ data }) => data);
	}

	function lookupIdentifiers(identifiers) {
		return httpService.doPost(sharedState.vocabularyUrl() + 'lookup/identifiers', JSON.stringify(identifiers));
	}

	function getInclusionCount(expression) {
		const data = { items: ko.toJS(expression), };
		return httpService.doPost(sharedState.vocabularyUrl() + 'included-concepts/count', data);
	}

	function getGenerationInfo(conceptSetId) {
		return httpService.doGet(config.webAPIRoot + 'conceptset/' + + (conceptSetId || '-1') + '/generationinfo')
			.then(({ data }) => data)
			.catch(authApi.handleAccessDenied);
	}

    function deleteConceptSet(conceptSetId) {
		return httpService.doDelete(config.webAPIRoot + 'conceptset/' + (conceptSetId || '-1'))
			.catch(authApi.handleAccessDenied);
    }

  function exists(name, id) {
		return httpService.doGet(`${config.webAPIRoot}conceptset/${id}/exists?name=${name}`)
			.then(({ data }) => data);
  }

  function saveConceptSet(conceptSet) {
		let promise = new Promise(r => r());
		const url = `${config.api.url}conceptset/${conceptSet.id ? conceptSet.id : ''}`;
		if (conceptSet.id) {
			promise = httpService.doPut(url, conceptSet);
		} else {
			promise = httpService.doPost(url, conceptSet);
		}
		promise.catch(authApi.handleAccessDenied);

		return promise;
	}

	function saveConceptSetItems(id, conceptSetItems) {
		return httpService.doPut(config.api.url + 'conceptset/' + id + '/items', conceptSetItems)
			.catch(authApi.handleAccessDenied);
	}

	function getConceptSet(conceptSetId) {
		return httpService.doGet(config.webAPIRoot + 'conceptset/' + (conceptSetId || '-1'))
			.catch(authApi.handleAccessDenied);
	}

	function getCopyName(id) {
		return httpService.doGet(config.webAPIRoot + 'conceptset/' + (id || "") + "/copy-name")
			.then(({ data }) => data);
	}

	async function loadSourcecodes() {
		sharedState.loadingSourcecodes(true);

		// load mapped
		let identifiers = [];
		let concepts = sharedState.includedConcepts();
		for (var i = 0; i < concepts.length; i++) {
			identifiers.push(concepts[i].CONCEPT_ID);
		}
		try {
			const { data } = await httpService.doPost(`${sharedState.vocabularyUrl()}lookup/mapped`, identifiers);
			sharedState.includedSourcecodes(data);
			return data;
		} catch (err) {
			console.error(err);
		} finally {
			sharedState.loadingSourcecodes(false);
		}
	}

	async function onCurrentConceptSetModeChanged(newMode) {
		let hashcode;
		const loadIncludedWithHash = async function() {
			hashcode = hash(sharedState.conceptSetInclusionIdentifiers());
			if (hashcode !== sharedState.includedHash()) {
				await loadIncluded();
				sharedState.includedHash(hashcode);
			}
		};
		switch (newMode) {
			case 'included-conceptsets':
			case 'included':
				await loadIncludedWithHash();
				break;
			case 'included-sourcecodes':
				await loadIncludedWithHash();
				if (sharedState.includedSourcecodes().length === 0) {
					await loadSourcecodes();
				}
				break;
		}
	}

	async function loadAncestors(ancestors, descendants) {
		const data = { ancestors, descendants };
		return httpService.doPost(sharedState.vocabularyUrl() + 'lookup/identifiers/ancestors', data);
	}

	function loadAndApplyAncestors(data) {
		const selectedConceptIds = sharedState.selectedConcepts().filter(v => !v.isExcluded()).map(v => v.concept.CONCEPT_ID);
		const ids = [];
		$.each(data, idx => {
			const element = data[idx];
			if (_.isEmpty(element.ANCESTORS) && sharedState.selectedConceptsIndex[element.CONCEPT_ID] !== 1) {
				ids.push(element.CONCEPT_ID);
			}
		});
		return new Promise((resolve, reject) => {
			if (!_.isEmpty(selectedConceptIds) && !_.isEmpty(ids)) {
				loadAncestors(selectedConceptIds, ids).then(({ data: ancestors }) => {
					const map = sharedState.includedConceptsMap();
					$.each(data, idx => {
						const line = data[idx];
						const ancArray = ancestors[line.CONCEPT_ID];
						if (!_.isEmpty(ancArray) && _.isEmpty(line.ANCESTORS)) {
							line.ANCESTORS = ancArray.map(conceptId => map[conceptId]);
						}
					});
					resolve();
				});
			} else {
				resolve();
			}
		});
	};

	async function loadIncluded(identifiers) {
		const data = identifiers || sharedState.conceptSetInclusionIdentifiers();
		try {
			sharedState.loadingIncluded(true);
			const response = await httpService.doPost(`${sharedState.vocabularyUrl()}lookup/identifiers`, data);
			await vocabularyService.loadDensity(response.data);
			sharedState.includedConcepts((response.data || []).map(v => ({...v, ANCESTORS: []})));
			const map = response.data.reduce((result, item) => {
				result[item.CONCEPT_ID] = item;
				return result;
			}, {});
			sharedState.includedConceptsMap(map);
			await loadAndApplyAncestors(sharedState.includedConcepts());
		} catch (err) {
			console.error(err);
		} finally {
			sharedState.loadingIncluded(false);
		}
	}

	function setConceptSet(conceptset, expressionItems) {
		var conceptSetItemsToAdd = [];
		expressionItems.forEach((conceptSet) => {
			const conceptSetItem = enhanceConceptSet(conceptSet);

			sharedState.selectedConceptsIndex[conceptSetItem.concept.CONCEPT_ID] = 1;
			conceptSetItemsToAdd.push(conceptSetItem);
		});

		sharedState.selectedConcepts(conceptSetItemsToAdd);
		sharedState.ConceptSet.current({
			name: ko.observable(conceptset.name),
			id: conceptset.id,
			createdBy: conceptset.createdBy,
			createdDate: conceptset.createdDate,
			modifiedBy: conceptset.modifiedBy,
			modifiedDate: conceptset.modifiedDate,
		});
	}

	function setConceptSetExpressionExportItems() {
		var highlightedJson = commonUtils.syntaxHighlight(sharedState.conceptSetExpression());
		sharedState.currentConceptSetExpressionJson(highlightedJson);
		var conceptIdentifierList = [];
		for (var i = 0; i < sharedState.selectedConcepts().length; i++) {
			conceptIdentifierList.push(sharedState.selectedConcepts()[i].concept.CONCEPT_ID);
		}
		sharedState.currentConceptIdentifierList(conceptIdentifierList.join(','));
	}

	// for the current selected concepts:
	// update the export panel
	// resolve the included concepts and update the include concept set identifier list
	function resolveConceptSetExpression(resolveAgainstServer = true) {
		let hashCode = hash(sharedState.conceptSetInclusionIdentifiers());
		if (hashCode !== sharedState.includedHash()) {
			sharedState.includedConcepts.removeAll();
			sharedState.includedSourcecodes.removeAll();
			sharedState.conceptSetInclusionIdentifiers.removeAll();
			sharedState.currentConceptIdentifierList(null);
			sharedState.currentIncludedConceptIdentifierList(null);
		}
		setConceptSetExpressionExportItems(sharedState.conceptSetExpression());
		return resolveAgainstServer ? resolveConceptSetExpressionSimple(sharedState.conceptSetExpression()) : null;
	}

	function resolveConceptSetExpressionSimple(expression, success) {
		const callback = typeof success === 'function'
			? success
			: ({ data }) => {
				let info = data;
				if (!Array.isArray(info)) {
					throw new Error();
				}
				sharedState.conceptSetInclusionIdentifiers(info);
				sharedState.currentIncludedConceptIdentifierList(info.join(','));
			};
		sharedState.resolvingConceptSetExpression(true);
		const resolvingPromise = httpService.doPost(sharedState.vocabularyUrl() + 'resolveConceptSetExpression', expression)
			.then(callback)
			.then(() => sharedState.resolvingConceptSetExpression(false))

		return resolvingPromise;
	}

	function clearConceptSet() {
		sharedState.ConceptSet.current(null);
		sharedState.clearSelectedConcepts();
		resolveConceptSetExpression(false);
		sharedState.ConceptSet.dirtyFlag().reset();
	}

	const api = {
		getIncludedConceptSetDrawCallback: getIncludedConceptSetDrawCallback,
		getAncestorsModalHandler: getAncestorsModalHandler,
		getAncestorsRenderFunction: getAncestorsRenderFunction,
		enhanceConceptSet,
		loadConceptSet,
		loadConceptSetExpression,
		lookupIdentifiers,
		getInclusionCount,
		getCopyName: getCopyName,
		getConceptSet: getConceptSet,
		getGenerationInfo: getGenerationInfo,
		deleteConceptSet: deleteConceptSet,
		exists: exists,
		saveConceptSet,
		saveConceptSetItems,
		loadSourcecodes,
		onCurrentConceptSetModeChanged,
		loadIncluded,
		setConceptSet,
		setConceptSetExpressionExportItems,
		resolveConceptSetExpression,
		resolveConceptSetExpressionSimple,
		clearConceptSet,
	};

	return api;
});<|endoftext|>


<commit_before>var gulp            = require('gulp'),
    // this is an arbitrary object that loads all gulp plugins in package.json.
    $         = require("gulp-load-plugins")(),
    express   = require('express'),
    path      = require('path'),
    tinylr    = require('tiny-lr'),
    app       = express(),
    server    = tinylr();

gulp.task('compass', function() {
    gulp.src('./src/stylesheets/*.scss')
        .pipe($.plumber())
        .pipe($.compass({
            css: 'dist/stylesheets',
            sass: 'src/stylesheets'
        }))
        .pipe(gulp.dest('dist/stylesheets'))
        .pipe( $.livereload( server ));
});

gulp.task('coffee', function() {
  return gulp.src('src/scripts/main.coffee', { read: false })
    .pipe($.plumber())
    .pipe($.browserify({
      debug: false,
      insertGlobals: false,
      transform: ['coffeeify'],
      extensions: ['.coffee']
    }))
    .pipe( $.rename('app.js') )
    .pipe( gulp.dest('dist/scripts') )
    .pipe( $.livereload( server ) );
});

gulp.task('images', function() {
  return gulp.src('./src/images/*')
    .pipe(gulp.dest('./dist/images'))
})

gulp.task('templates', function() {
  return gulp.src('src/*.jade')
    .pipe($.plumber())
    .pipe($.jade({
      pretty: true
    }))
    .pipe( gulp.dest('dist/') )
    .pipe( $.livereload( server ));
});

gulp.task('express', function() {
  app.use(express.static(path.resolve('./dist')));
  app.listen(1337);
  $.util.log('Listening on port: 1337');
});

gulp.task('watch', function () {
  server.listen(35729, function (err) {
    if (err) {
      return console.log(err);
    }

    gulp.watch('src/stylesheets/*.scss',['compass']);

    gulp.watch('src/scripts/*.coffee',['coffee']);

    gulp.watch('src/*.jade',['templates']);

  });
});

// Default Task
gulp.task('default', ['coffee','compass','templates', 'images', 'express','watch']);<commit_msg>disable sass comments<commit_after>var gulp            = require('gulp'),
    // this is an arbitrary object that loads all gulp plugins in package.json.
    $         = require("gulp-load-plugins")(),
    express   = require('express'),
    path      = require('path'),
    tinylr    = require('tiny-lr'),
    app       = express(),
    server    = tinylr();

gulp.task('compass', function() {
    gulp.src('./src/stylesheets/*.scss')
        .pipe($.plumber())
        .pipe($.compass({
            css: 'dist/stylesheets',
            sass: 'src/stylesheets',
            comments: false
        }))
        .pipe(gulp.dest('dist/stylesheets'))
        .pipe( $.livereload( server ));
});

gulp.task('coffee', function() {
  return gulp.src('src/scripts/main.coffee', { read: false })
    .pipe($.plumber())
    .pipe($.browserify({
      debug: false,
      insertGlobals: false,
      transform: ['coffeeify'],
      extensions: ['.coffee']
    }))
    .pipe( $.rename('app.js') )
    .pipe( gulp.dest('dist/scripts') )
    .pipe( $.livereload( server ) );
});

gulp.task('images', function() {
  return gulp.src('./src/images/*')
    .pipe(gulp.dest('./dist/images'))
})

gulp.task('templates', function() {
  return gulp.src('src/*.jade')
    .pipe($.plumber())
    .pipe($.jade({
      pretty: true
    }))
    .pipe( gulp.dest('dist/') )
    .pipe( $.livereload( server ));
});

gulp.task('express', function() {
  app.use(express.static(path.resolve('./dist')));
  app.listen(1337);
  $.util.log('Listening on port: 1337');
});

gulp.task('watch', function () {
  server.listen(35729, function (err) {
    if (err) {
      return console.log(err);
    }

    gulp.watch('src/stylesheets/*.scss',['compass']);

    gulp.watch('src/scripts/*.coffee',['coffee']);

    gulp.watch('src/*.jade',['templates']);

  });
});

// Default Task
gulp.task('default', ['coffee','compass','templates', 'images', 'express','watch']);<|endoftext|>


<commit_before>'use strict';
var express = require('express'),
    specifications = require('base.specifications'),
    logger = require('base.logger')('components/application/embodier'),
// create the application
    app = express();
module.exports = specifications.components.ApplicationProvider.extend(
    /**
     * @lends components/application-rest.prototype
     */
    {
        /**
         * @classDesc embodier is an application that is used to create and manage other applications built on top of
         * soul
         * @exports components/application-rest
         * @extends components/ApplicationProvider
         * @constructor
         * @abstract
         */
        init: function (settings, resolver) {
            logger.info('adding 404 error handlers...');
            app.use(function (req, res, next) {
                var err = new Error('Not Found');
                err.status = 404;
                next(err);
            });
            // save the settings as a process variable for later use
            process.SOUL_APPLICATION_EMBODIER = settings;
            // enable long stack support for q. This option enables you can see the function that triggered the async
            // operation in the stack trace! This is very helpful for debugging, as otherwise you end up getting only
            // the first line, plus a bunch of Q internals, with no sign of where the operation started.
            require('q').longStackSupport = true;
        },
        run: function () {
            var httpServer, httpsServer;
            logger.info('starting the embodier server');
            // we start the server here listening to the port specified in config
            if (process.SOUL_APPLICATION_EMBODIER['http-port']) {
                httpServer = require('http').createServer(app).listen(
                    process.SOUL_APPLICATION_EMBODIER['http-port']
                );
                httpServer.on('listening', function () {
                    logger.info('server listening to http port: ' + httpServer.address().port);
                });
            }
            if (process.SOUL_APPLICATION_EMBODIER['https-port']) {
                httpsServer = require('https').createServer(app).listen(
                    process.SOUL_APPLICATION_EMBODIER['https-port']
                );
                httpsServer.on('listening', function () {
                    logger.info('server listening to https port: ' + httpsServer.address().port);
                });
            }
        },
        serialize: specifications.base.Class.abstract,
        deserialize: specifications.base.Class.abstract
    }
);
<commit_msg>fxed documentation after rename<commit_after>'use strict';
var express = require('express'),
    specifications = require('base.specifications'),
    logger = require('base.logger')('components/application/embodier'),
// create the application
    app = express();
module.exports = specifications.components.ApplicationProvider.extend(
    /**
     * @lends components/application-rest.prototype
     */
    {
        /**
         * @classDesc embodier is an application that is used to create and manage other applications built on top of
         * soul
         * @exports components/application-rest
         * @extends components/ApplicationProvider
         * @constructor
         * @abstract
         */
        init: function (settings, resolver) {
            logger.info('adding 404 error handlers...');
            app.use(function (req, res, next) {
                var err = new Error('Not Found');
                err.status = 404;
                next(err);
            });
            // save the settings as a process variable for later use
            process.SOUL_APPLICATION_EMBODIER = settings;
            // enable long stack support for q. This option enables you can see the function that triggered the async
            // operation in the stack trace! This is very helpful for debugging, as otherwise you end up getting only
            // the first line, plus a bunch of Q internals, with no sign of where the operation started.
            require('q').longStackSupport = true;
        },
        run: function () {
            var httpServer, httpsServer;
            logger.info('starting the embodier server');
            // we start the server here listening to the port specified in config
            if (process.SOUL_APPLICATION_EMBODIER['http-port']) {
                httpServer = require('http').createServer(app).listen(
                    process.SOUL_APPLICATION_EMBODIER['http-port']
                );
                httpServer.on('listening', function () {
                    logger.info('server listening to http port: ' + httpServer.address().port);
                });
            }
            if (process.SOUL_APPLICATION_EMBODIER['https-port']) {
                httpsServer = require('https').createServer(app).listen(
                    process.SOUL_APPLICATION_EMBODIER['https-port']
                );
                httpsServer.on('listening', function () {
                    logger.info('server listening to https port: ' + httpsServer.address().port);
                });
            }
        },
        serialize: specifications.base.Class.abstract,
        deserialize: specifications.base.Class.abstract
    },
    {
        describe: function () {
            return {
                dummy: 'dummy'
            };
        }
    }
);
<|endoftext|>


<commit_before>'use strict'
import getProjectImage from './../assets/*.png'
import getColleaguePicture from './../assets/colleagues/*.(jpg|png)'
import { getTechnologiesList, getWorkplaceHighlights } from './utils'

export function getProjectsCards (path) {
    let [projectsListing, project] = [``]
    const spotlight = `

Projects

${path[0].name}

${path[0].year}

            ${getTechnologiesList(path[0].technologies)}

             ${path[0].role}

             ${path[0].location}

            ${path[0].description}
            ${getWorkplaceHighlights(path[0].highlights)}

    `
    for (project = 1; project < path.length; project++) {
        projectsListing += `

${path[project].name}

${path[project].year}

        ${getTechnologiesList(path[project].technologies)}

             ${path[project].role}

             ${path[project].location}

            ${path[project].description}
            ${getWorkplaceHighlights(path[project].highlights)}

    `
    }
    return spotlight + projectsListing
}

export function getTestimonialCards () {
    const testimonialsArray = [
        // {
        //     avatarUrl: getColleaguePicture[],
        //     fullName: 'Danielius A.',
        //     role: 'Implementation Engineer',
        //     testimonial: 'Thank you for being super fast and responsive!',
        //     year: '2018'
        // },
        {
            avatarUrl: getColleaguePicture['elvyraS'].png,
            fullName: 'Elvyra S.',
            role: 'Certification Specialist',
            testimonial: 'Thanks for sharing your superpowers! :))',
            year: '2018'
        },
        {
            avatarUrl: getColleaguePicture['tomasS'].jpg,
            fullName: 'Tomas S.',
            role: 'Implementation Manager',
            testimonial: 'Thank you for your help on building QA Automation tool.',
            year: 2018
        },
        {
            avatarUrl: getColleaguePicture['gintareS'].jpg,
            fullName: 'Gintare S.',
            role: 'QA Analyst',
            testimonial: 'Thanks for everyday cooperation and all the work with dashboards that make our life more colourful!',
            year: 2018
        },
        {
            avatarUrl: getColleaguePicture['dovileM'].png,
            fullName: 'Dovile M.',
            role: 'QA Analyst',
            testimonial: 'Thank you Mindaugas for your help! You\'re are so smart! GitHub was easy only because you helped :).',
            year: 2018
        },
        {
            avatarUrl: getColleaguePicture['marthaY'].jpg,
            fullName: 'Martha Y.',
            role: 'Senior Engagement Manager',
            testimonial: 'I think your formal title should be QA Master, QA Wizard.',
            year: 2018
        },
        {
            avatarUrl: getColleaguePicture['karolisN'].png,
            fullName: 'Karolis N.',
            role: 'QA Specialist',
            testimonial: 'Thanks for all the improvements, amazing work on internal tool and constant technical help!',
            year: 2018
        }
    ]

    const testimonialsData = testimonialsArray
        .map(obj => {
            const testimonialsObj = {}
            testimonialsObj[obj.key] = obj.value
            return `

 ${obj.fullName}

 ${obj.role}

   ${obj.testimonial}

`}).join('')
    document.getElementsByTagName('testimonials')[0].innerHTML = `

Testimonials

${testimonialsData}

`
}
<commit_msg>added lazy loading to testimonials section<commit_after>'use strict'
import getProjectImage from './../assets/*.png'
import getColleaguePicture from './../assets/colleagues/*.(jpg|png)'
import { getTechnologiesList, getWorkplaceHighlights } from './utils'

export function getProjectsCards (path) {
    let [projectsListing, project] = [``]
    const spotlight = `

Projects

${path[0].name}

${path[0].year}

            ${getTechnologiesList(path[0].technologies)}

             ${path[0].role}

             ${path[0].location}

            ${path[0].description}
            ${getWorkplaceHighlights(path[0].highlights)}

    `
    for (project = 1; project < path.length; project++) {
        projectsListing += `

${path[project].name}

${path[project].year}

        ${getTechnologiesList(path[project].technologies)}

             ${path[project].role}

             ${path[project].location}

            ${path[project].description}
            ${getWorkplaceHighlights(path[project].highlights)}

    `
    }
    return spotlight + projectsListing
}

export function getTestimonialCards () {
    const testimonialsArray = [
        // {
        //     avatarUrl: getColleaguePicture[],
        //     fullName: 'Danielius A.',
        //     role: 'Implementation Engineer',
        //     testimonial: 'Thank you for being super fast and responsive!',
        //     year: '2018'
        // },
        {
            avatarUrl: getColleaguePicture['elvyraS'].png,
            fullName: 'Elvyra S.',
            role: 'Certification Specialist',
            testimonial: 'Thanks for sharing your superpowers! :))',
            year: '2018'
        },
        {
            avatarUrl: getColleaguePicture['tomasS'].jpg,
            fullName: 'Tomas S.',
            role: 'Implementation Manager',
            testimonial: 'Thank you for your help on building QA Automation tool.',
            year: 2018
        },
        {
            avatarUrl: getColleaguePicture['gintareS'].jpg,
            fullName: 'Gintare S.',
            role: 'QA Analyst',
            testimonial: 'Thanks for everyday cooperation and all the work with dashboards that make our life more colourful!',
            year: 2018
        },
        {
            avatarUrl: getColleaguePicture['dovileM'].png,
            fullName: 'Dovile M.',
            role: 'QA Analyst',
            testimonial: 'Thank you Mindaugas for your help! You\'re are so smart! GitHub was easy only because you helped :).',
            year: 2018
        },
        {
            avatarUrl: getColleaguePicture['marthaY'].jpg,
            fullName: 'Martha Y.',
            role: 'Senior Engagement Manager',
            testimonial: 'I think your formal title should be QA Master, QA Wizard.',
            year: 2018
        },
        {
            avatarUrl: getColleaguePicture['karolisN'].png,
            fullName: 'Karolis N.',
            role: 'QA Specialist',
            testimonial: 'Thanks for all the improvements, amazing work on internal tool and constant technical help!',
            year: 2018
        }
    ]

    const testimonialsData = testimonialsArray
        .map(obj => {
            const testimonialsObj = {}
            testimonialsObj[obj.key] = obj.value
            return `

 ${obj.fullName}

 ${obj.role}

   ${obj.testimonial}

`}).join('')
    document.getElementsByTagName('testimonials')[0].innerHTML = `

Testimonials

${testimonialsData}

`
}
<|endoftext|>


<commit_before>const cv = global.dut;
const {
  funcShouldRequireArgs,
  generateAPITests,
  assertMetaData
} = global.utils;
const { expect } = require('chai');

let asyncHooks = null

try {
  asyncHooks = require('async_hooks')
} catch (e) {
  //
}

const partitionTests = (createInstance) => {
  it('should return labels and numLabels', () => {
    const { labels, numLabels } = cv.partition([createInstance(), createInstance()], () => true);

    expect(labels).to.be.an('array').lengthOf(2);
    expect(numLabels).be.a('number');
  });

  it('should assign every point to same cluster', () => {
    const num = 5;
    const instances = Array(num).fill(0).map(() => createInstance());
    const { labels, numLabels } = cv.partition(instances, () => true);

    expect(numLabels).to.equal(1);
    expect(new Set(labels).size).to.equal(1);
  });

  it('should assign every point to different cluster', () => {
    const num = 5;
    const instances = Array(num).fill(0).map(() => createInstance());
    const { labels, numLabels } = cv.partition(instances, () => false);

    expect(numLabels).to.equal(num);
    expect(new Set(labels).size).to.equal(num);
  });
};

describe('core', () => {
  describe('getBuildInformation', () => {
    generateAPITests({
      getDut: () => cv,
      methodName: 'getBuildInformation',
      hasAsync: false,
      expectOutput: () => {}
    });
  });

  describe('partition', () => {
    funcShouldRequireArgs(() => cv.partition());

    describe('Point2 input', () => {
      partitionTests(() => new cv.Point(0, 0));
    });

    describe('Point3 input', () => {
      partitionTests(() => new cv.Point(0, 0, 0));
    });

    describe('Vec2 input', () => {
      partitionTests(() => new cv.Vec(0, 0));
    });

    describe('Vec3 input', () => {
      partitionTests(() => new cv.Vec(0, 0, 0));
    });

    describe('Vec4 input', () => {
      partitionTests(() => new cv.Vec(0, 0, 0, 0));
    });

    describe('Mat input', () => {
      partitionTests(() => new cv.Mat());
    });
  });

  describe('kmeans', () => {
    funcShouldRequireArgs(() => cv.kmeans());
    const points = [
      [0, 0], [1000, 900], [-1000, -900], [-1100, -1000], [1100, 1000], [10, 10]
    ].map(([x, y]) => new cv.Point(x, y));
    const k = 3;
    const termCriteria = new cv.TermCriteria(cv.termCriteria.COUNT, 100, 0.8);
    const attempts = 10;
    const flags = cv.KMEANS_RANDOM_CENTERS;

    it('should return labels and centers', () => {
      const ret = cv.kmeans(points, k, termCriteria, attempts, flags);

      expect(ret).to.have.property('labels').to.be.an('array').lengthOf(6);
      expect(ret).to.have.property('centers').to.be.an('array').lengthOf(k);
    });

    it('should return correct labels', () => {
      const ret = cv.kmeans(points, k, termCriteria, attempts, flags);

      const l0 = ret.labels[0];
      const l1 = ret.labels[1];
      const l2 = ret.labels[2];
      expect(ret.labels).to.have.ordered.members([l0, l1, l2, l2, l1, l0]);
    });

    it('should return correct centers', () => {
      const ret = cv.kmeans(points, k, termCriteria, attempts, flags);

      const l0 = ret.labels[0];
      const l1 = ret.labels[1];
      const l2 = ret.labels[2];
      expect(ret.centers[l0].x).to.equal(5);
      expect(ret.centers[l0].y).to.equal(5);
      expect(ret.centers[l1].x).to.equal(1050);
      expect(ret.centers[l1].y).to.equal(950);
      expect(ret.centers[l2].x).to.equal(-1050);
      expect(ret.centers[l2].y).to.equal(-950);
    });
  });

  describe('cartToPolar', () => {
    const x = new cv.Mat([[0, 1, 100]], cv.CV_32F);
    const y = new cv.Mat([[0, 1, 100]], cv.CV_32F);
    const angleInDegrees = true;

    const expectOutput = (res) => {
      expect(res).to.have.property('magnitude').to.be.instanceOf(cv.Mat);
      expect(res).to.have.property('angle').to.be.instanceOf(cv.Mat);
      assertMetaData(res.magnitude)(1, 3, cv.CV_32F);
      assertMetaData(res.angle)(1, 3, cv.CV_32F);
    };

    generateAPITests({
      getDut: () => cv,
      methodName: 'cartToPolar',
      getRequiredArgs: () => ([
        x, y
      ]),
      getOptionalArgs: () => ([
        angleInDegrees
      ]),
      expectOutput
    });
  });

  describe('polarToCart', () => {
    const magnitude = new cv.Mat([[0, 1, 100]], cv.CV_32F);
    const angle = new cv.Mat([[0, Math.PI / 2, Math.PI]], cv.CV_32F);
    const angleInDegrees = true;

    const expectOutput = (res) => {
      expect(res).to.have.property('x').to.be.instanceOf(cv.Mat);
      expect(res).to.have.property('y').to.be.instanceOf(cv.Mat);
      assertMetaData(res.x)(1, 3, cv.CV_32F);
      assertMetaData(res.y)(1, 3, cv.CV_32F);
    };

    generateAPITests({
      getDut: () => cv,
      methodName: 'polarToCart',
      getRequiredArgs: () => ([
        magnitude, angle
      ]),
      getOptionalArgs: () => ([
        angleInDegrees
      ]),
      expectOutput
    });
  });

  describe('getNumThreads', () => {
    it('should return the number of threads that used by OpenCV', () => {
      expect(cv.getNumThreads()).to.be.an('number');
    });
  });

  describe('setNumThreads', () => {
    it('should try to set the number of threads'
        + ' that used by OpenCV', () => {
      const number = 2;
      cv.setNumThreads(number);
      // OpenCV will **try** to set the number of threads for the
      // next parallel region so that `cv.getNumThreads()` don't react
      // to this immediately.
      // expect(cv.getNumThreads()).to.be.equal(number);
    });

    it('should throw when the argument is not integer', () => {
      let err;

      const expectError = (fn, msg) => {
        try {
          fn();
        } catch (e) {
          err = e;
        }

        expect(err.message).to.be
          .equal(msg);
      };

      expectError(() => cv.setNumThreads('hello'),
        'Core::SetNumThreads expected arg0 to an int');
      expectError(() => cv.setNumThreads(1.1),
        'Core::SetNumThreads expected arg0 to an int');
    });
  });

  describe('GetThreadNum', () => {
    it('should returns the index of the currently executed thread', () => {
      expect(cv.getThreadNum()).to.be.an('number');
    });
  });

  describe('class constructor call', () => {
    it('should throw errors if we call a constructor without "new"', () => {
      let err;

      try {
        cv.Mat();
      } catch (e) {
        err = e;
      }

      expect(err.message).to.be.equal(
        'Mat::New -  expect to be called with "new"');
    });
  });

  if (asyncHooks) {
    describe('async_hooks', () => {
      it('should trigger `init` callback in async_hooks', () => {
        let typeFound = false
        const hook = asyncHooks.createHook({
          init: (asyncId, type, triggerAsyncId, resource) => {
            if (type.indexOf('opencv4nodejs') === 0) {
              typeFound = true
              hook.disable()
            }
          },
        })
        hook.enable()

        const createInstance = () => new cv.Point(0, 0)
        const num = 5;
        const instances = Array(num).fill(0).map(() => createInstance());
        const { labels, numLabels } = cv.partition(instances, () => true);
        expect(typeFound).to.be.equal(true)
      })
    })
  }
});
<commit_msg>kmeans: add unit test for #379<commit_after>const cv = global.dut;
const {
  funcShouldRequireArgs,
  generateAPITests,
  assertMetaData
} = global.utils;
const { expect } = require('chai');

let asyncHooks = null

try {
  asyncHooks = require('async_hooks')
} catch (e) {
  //
}

const partitionTests = (createInstance) => {
  it('should return labels and numLabels', () => {
    const { labels, numLabels } = cv.partition([createInstance(), createInstance()], () => true);

    expect(labels).to.be.an('array').lengthOf(2);
    expect(numLabels).be.a('number');
  });

  it('should assign every point to same cluster', () => {
    const num = 5;
    const instances = Array(num).fill(0).map(() => createInstance());
    const { labels, numLabels } = cv.partition(instances, () => true);

    expect(numLabels).to.equal(1);
    expect(new Set(labels).size).to.equal(1);
  });

  it('should assign every point to different cluster', () => {
    const num = 5;
    const instances = Array(num).fill(0).map(() => createInstance());
    const { labels, numLabels } = cv.partition(instances, () => false);

    expect(numLabels).to.equal(num);
    expect(new Set(labels).size).to.equal(num);
  });
};

describe('core', () => {
  describe('getBuildInformation', () => {
    generateAPITests({
      getDut: () => cv,
      methodName: 'getBuildInformation',
      hasAsync: false,
      expectOutput: () => {}
    });
  });

  describe('partition', () => {
    funcShouldRequireArgs(() => cv.partition());

    describe('Point2 input', () => {
      partitionTests(() => new cv.Point(0, 0));
    });

    describe('Point3 input', () => {
      partitionTests(() => new cv.Point(0, 0, 0));
    });

    describe('Vec2 input', () => {
      partitionTests(() => new cv.Vec(0, 0));
    });

    describe('Vec3 input', () => {
      partitionTests(() => new cv.Vec(0, 0, 0));
    });

    describe('Vec4 input', () => {
      partitionTests(() => new cv.Vec(0, 0, 0, 0));
    });

    describe('Mat input', () => {
      partitionTests(() => new cv.Mat());
    });
  });

  describe('kmeans', () => {
    funcShouldRequireArgs(() => cv.kmeans());
    const points2 = [
      [0, 0], [1000, 900], [-1000, -900], [-1100, -1000], [1100, 1000], [10, 10]
    ].map(([x, y]) => new cv.Point(x, y));

    const k = 3;
    const termCriteria = new cv.TermCriteria(cv.termCriteria.COUNT, 100, 0.8);
    const attempts = 10;
    const flags = cv.KMEANS_RANDOM_CENTERS;

    it('should return labels and centers', () => {
      const ret = cv.kmeans(points2, k, termCriteria, attempts, flags);

      expect(ret).to.have.property('labels').to.be.an('array').lengthOf(6);
      expect(ret).to.have.property('centers').to.be.an('array').lengthOf(k);
    });

    it('should return correct labels', () => {
      const ret = cv.kmeans(points2, k, termCriteria, attempts, flags);

      const l0 = ret.labels[0];
      const l1 = ret.labels[1];
      const l2 = ret.labels[2];
      expect(ret.labels).to.have.ordered.members([l0, l1, l2, l2, l1, l0]);
    });

    it('should return correct centers', () => {
      const ret = cv.kmeans(points2, k, termCriteria, attempts, flags);

      const l0 = ret.labels[0];
      const l1 = ret.labels[1];
      const l2 = ret.labels[2];
      expect(ret.centers[l0].x).to.equal(5);
      expect(ret.centers[l0].y).to.equal(5);
      expect(ret.centers[l1].x).to.equal(1050);
      expect(ret.centers[l1].y).to.equal(950);
      expect(ret.centers[l2].x).to.equal(-1050);
      expect(ret.centers[l2].y).to.equal(-950);
    });

    // related to https://github.com/justadudewhohacks/opencv4nodejs/issues/379
    const points3 = [
      [255, 0, 0], [255, 0, 0], [255, 0, 255], [255, 0, 255], [255, 255, 255]
    ].map(([r, g, b]) => new cv.Vec3(r, g, b));

    it('should return correct centers with Vec3', () => {
      const ret = cv.kmeans(points3, k, termCriteria, attempts, flags);

      const l0 = ret.labels[0];
      const l1 = ret.labels[1];
      const l2 = ret.labels[2];
      expect(ret.centers[l0].x).to.equal(255);
      expect(ret.centers[l0].y).to.equal(0);
      expect(ret.centers[l0].z).to.equal(0);
      expect(ret.centers[l1].x).to.equal(255);
      expect(ret.centers[l1].y).to.equal(0);
      expect(ret.centers[l1].z).to.equal(255);
      expect(ret.centers[l2].x).to.equal(255);
      expect(ret.centers[l2].y).to.equal(255);
      expect(ret.centers[l2].y).to.equal(255);
    });
  });

  describe('cartToPolar', () => {
    const x = new cv.Mat([[0, 1, 100]], cv.CV_32F);
    const y = new cv.Mat([[0, 1, 100]], cv.CV_32F);
    const angleInDegrees = true;

    const expectOutput = (res) => {
      expect(res).to.have.property('magnitude').to.be.instanceOf(cv.Mat);
      expect(res).to.have.property('angle').to.be.instanceOf(cv.Mat);
      assertMetaData(res.magnitude)(1, 3, cv.CV_32F);
      assertMetaData(res.angle)(1, 3, cv.CV_32F);
    };

    generateAPITests({
      getDut: () => cv,
      methodName: 'cartToPolar',
      getRequiredArgs: () => ([
        x, y
      ]),
      getOptionalArgs: () => ([
        angleInDegrees
      ]),
      expectOutput
    });
  });

  describe('polarToCart', () => {
    const magnitude = new cv.Mat([[0, 1, 100]], cv.CV_32F);
    const angle = new cv.Mat([[0, Math.PI / 2, Math.PI]], cv.CV_32F);
    const angleInDegrees = true;

    const expectOutput = (res) => {
      expect(res).to.have.property('x').to.be.instanceOf(cv.Mat);
      expect(res).to.have.property('y').to.be.instanceOf(cv.Mat);
      assertMetaData(res.x)(1, 3, cv.CV_32F);
      assertMetaData(res.y)(1, 3, cv.CV_32F);
    };

    generateAPITests({
      getDut: () => cv,
      methodName: 'polarToCart',
      getRequiredArgs: () => ([
        magnitude, angle
      ]),
      getOptionalArgs: () => ([
        angleInDegrees
      ]),
      expectOutput
    });
  });

  describe('getNumThreads', () => {
    it('should return the number of threads that used by OpenCV', () => {
      expect(cv.getNumThreads()).to.be.an('number');
    });
  });

  describe('setNumThreads', () => {
    it('should try to set the number of threads'
        + ' that used by OpenCV', () => {
      const number = 2;
      cv.setNumThreads(number);
      // OpenCV will **try** to set the number of threads for the
      // next parallel region so that `cv.getNumThreads()` don't react
      // to this immediately.
      // expect(cv.getNumThreads()).to.be.equal(number);
    });

    it('should throw when the argument is not integer', () => {
      let err;

      const expectError = (fn, msg) => {
        try {
          fn();
        } catch (e) {
          err = e;
        }

        expect(err.message).to.be
          .equal(msg);
      };

      expectError(() => cv.setNumThreads('hello'),
        'Core::SetNumThreads expected arg0 to an int');
      expectError(() => cv.setNumThreads(1.1),
        'Core::SetNumThreads expected arg0 to an int');
    });
  });

  describe('GetThreadNum', () => {
    it('should returns the index of the currently executed thread', () => {
      expect(cv.getThreadNum()).to.be.an('number');
    });
  });

  describe('class constructor call', () => {
    it('should throw errors if we call a constructor without "new"', () => {
      let err;

      try {
        cv.Mat();
      } catch (e) {
        err = e;
      }

      expect(err.message).to.be.equal(
        'Mat::New -  expect to be called with "new"');
    });
  });

  if (asyncHooks) {
    describe('async_hooks', () => {
      it('should trigger `init` callback in async_hooks', () => {
        let typeFound = false
        const hook = asyncHooks.createHook({
          init: (asyncId, type, triggerAsyncId, resource) => {
            if (type.indexOf('opencv4nodejs') === 0) {
              typeFound = true
              hook.disable()
            }
          },
        })
        hook.enable()

        const createInstance = () => new cv.Point(0, 0)
        const num = 5;
        const instances = Array(num).fill(0).map(() => createInstance());
        const { labels, numLabels } = cv.partition(instances, () => true);
        expect(typeFound).to.be.equal(true)
      })
    })
  }
});
<|endoftext|>