<commit_before>"use strict";

var events = require('events');
var EventEmitter = events.EventEmitter;

var Wrappers = require('./wrappers');

var exports = {};

// Only define Node-style usage using sync I/O if in node.
(function () {
    var dirname = require('path').dirname;
    var resolve = require('path').resolve;
    var existsSync = require('fs').existsSync || require('path').existsSync;
    var realpathSync = require('fs').realpathSync;
    var packagePathCache = {};

    exports.loadConfig = loadConfig;
    exports.resolveConfig = resolveConfig;

    // This is assumed to be used at startup and uses sync I/O as well as can
    // throw exceptions.  It loads and parses a config file.
    function loadConfig(configPath, callback) {
      var config = require(configPath);
      var base = dirname(configPath);

      var ext_config = resolveDefaultWrappers(config, base, callback);
      return resolveConfig(ext_config, base, callback);
    }

    function resolveConfig(config, base) {
        config.forEach(function (plugin, index) {
            // Shortcut where string is used for plugin without any options.
            if (typeof plugin === "string") {
                plugin = config[index] = { packagePath: plugin };
            }

            // The plugin is a package on the disk.  We need to load it.
            if (plugin.hasOwnProperty("packagePath")
                  && !(plugin.hasOwnProperty("setup") || plugin.hasOwnProperty("provides"))) {
                var defaults = resolveModule(base, plugin.packagePath);
                Object.keys(defaults).forEach(function (key) {
                    if (!plugin.hasOwnProperty(key)) {
                        plugin[key] = defaults[key];
                    }
                });

                // if no, don't load setup function, etc and create hooks
                plugin.packagePath = defaults.packagePath; // now has the file to load
                plugin.provides = defaults.provides;
                plugin.consumes = defaults.consumes;

                // not all packages have a main entry point
                // in which case require fails.
                try{
                    plugin.setup = require(plugin.packagePath);
                } catch(e){}

                resolveWrappedServices(base, plugin);
            }
        });
        return config;
    }

    // Loads a module, getting metadata from either it's package.json or export
    // object.
    function resolveModule(base, modulePath) {
        var packagePath;
        try {
            packagePath = resolvePackage(base, modulePath + "/package.json");
        }
        catch (err) {
            if (err.code !== "ENOENT") throw err;
        }
        var packageJson = packagePath && require(packagePath) || {};
        if (packageJson && !packageJson.plugin){ // user friendly message
            console.warn("WARNING from " + modulePath);
            console.warn("NOTE: plugin:{...} key is missing in package.json");
        }

        var metadata = packagePath && packageJson.plugin || {};

       if (packagePath) {
            modulePath = dirname(packagePath);
        } else {
            try {
                modulePath = resolvePackage(base, modulePath);
            } catch(e) {}
        }

        // pacakgeJson - may not have a main entry point
        // in which case these functions are not needed.
        var module = {};
        if(packageJson.main){
            module = require(modulePath);
        }
        metadata.provides = metadata.provides || module.provides || [];
        metadata.consumes = metadata.consumes || module.consumes || [];
        metadata.packagePath = modulePath;
        return metadata;
    }

    // Node style package resolving so that plugins' package.json can be found relative to the config file
    // It's not the full node require system algorithm, but it's the 99% case
    // This throws, make sure to wrap in try..catch
    function resolvePackage(base, packagePath) {
        var originalBase = base;
        if (!(base in packagePathCache)) {
            packagePathCache[base] = {};
        }
        var cache = packagePathCache[base];
        if (packagePath in cache) {
            return cache[packagePath];
        }
        var newPath, newBase;
        if (packagePath[0] === "." || packagePath[0] === "/") {
            newPath = resolve(base, packagePath);
            if (existsSync(newPath)) {
                newPath = realpathSync(newPath);
                cache[packagePath] = newPath;
                return newPath;
            }
        }
        else {
            while (base) {
                newPath = resolve(base, "node_modules", packagePath);
                if (existsSync(newPath)) {
                    newPath = realpathSync(newPath);
                    cache[packagePath] = newPath;
                    return newPath;
                }
                newBase = resolve(base, '..');
                if (base === newBase) {
                    break;
                }
                base = newBase;
            }
        }
        var err = new Error("Can't find '" + packagePath + "' relative to '" + originalBase + "'");
        err.code = "ENOENT";
        throw err;
    }

    // Load all objects that are provided by the module (they will be consumed by wrapper)
    function resolveWrappedServices(base, plugin){
        if(!plugin.packageWrapper){
            plugin.packageWrapper = Wrappers.defaultWrapperName;
        }
        var wrapperInst = Wrappers.newWrapper(plugin.packageWrapper);
        if(!wrapperInst){
            var errmsg = "No registered wrapper with the name " + plugin.packageWrapper;
            throw new Error(errmsg);
        }
        wrapperInst.resolveConfig(plugin, base);
        plugin.packageWrapper = wrapperInst;
    }
}());

exports.createApp = createApp;
exports.Archie = Archie;

// Check a plugin config list for bad dependencies and throw on error
function checkConfig(config) {

    // Check for the required fields in each plugin.
    config.forEach(function (plugin) {
        if (plugin.checked) { return; }
        // legacy: not all packages have setup functions
        //if (!plugin.hasOwnProperty("setup")) {
        //    throw new Error("Plugin is missing the setup function " + JSON.stringify(plugin));
        //}
        if (!plugin.hasOwnProperty("provides")) {
            throw new Error("Plugin is missing the provides array " + JSON.stringify(plugin));
        }
        if (!plugin.hasOwnProperty("consumes")) {
            throw new Error("Plugin is missing the consumes array " + JSON.stringify(plugin));
        }
    });

    return checkCycles(config);
}

function checkCycles(config) {
    var plugins = [];
    config.forEach(function(pluginConfig, index) {
        plugins.push({
            packagePath: pluginConfig.packagePath,
            provides: pluginConfig.provides.concat(),
            consumes: pluginConfig.consumes.concat(),
            i: index
        });
    });

    var resolved = {
        hub: true
    };
    var changed = true;
    var sorted = [];

    while(plugins.length && changed) {
        changed = false;

        plugins.concat().forEach(function(plugin) {
            var consumes = plugin.consumes.concat();

            var resolvedAll = true;
            for (var i=0; i<consumes.length; i++) {
                var service = consumes[i];
                if (!resolved[service]) {
                    resolvedAll = false;
                } else {
                    plugin.consumes.splice(plugin.consumes.indexOf(service), 1);
                }
            }

            if (!resolvedAll)
                return;

            plugins.splice(plugins.indexOf(plugin), 1);
            plugin.provides.forEach(function(service) {
                resolved[service] = true;
            });
            sorted.push(config[plugin.i]);
            changed = true;
        });
    }

    if (plugins.length) {
        var unresolved = {};
        plugins.forEach(function(plugin) {
            delete plugin.config;
            plugin.consumes.forEach(function(name) {
                if (unresolved[name] == false)
                    return;
                if (!unresolved[name])
                    unresolved[name] = [];
                unresolved[name].push(plugin.packagePath);
            });
            plugin.provides.forEach(function(name) {
                unresolved[name] = false;
            });
        });

        Object.keys(unresolved).forEach(function(name) {
            if (unresolved[name] == false)
                delete unresolved[name];
        });

        console.error("Could not resolve dependencies of these plugins:", plugins);
        console.error("Resolved services:", Object.keys(resolved));
        console.error("Missing services:", unresolved);
        throw new Error("Could not resolve dependencies");
    }

    return sorted;
}

function Archie(config) {
    var app = this;
    app.config = [];
    app.destructors = [];
    app.services = {
        hub: {
            on: function (name, callback) {
                app.on(name, callback);
            }
        }
    };

    // Give createApp some time to subscribe to our "ready" event
    (typeof process === "object" ? process.nextTick : setTimeout)(function() {
        app.loadPlugins(config, function(err) {
            if (err) {
                throw err;
            }
            app.emit("ready", app);
        });
    });
}

Archie.prototype = Object.create(EventEmitter.prototype, {constructor:{value:Archie}});

Archie.prototype.destroy = function() {
    var app = this;

    app.destructors.forEach(function(destroy) {
        destroy();
    });

    app.destructors = [];
};

Archie.prototype.loadPlugins = function(config, callback) {
    var app = this;

    var sortedConfig;
    try {
        sortedConfig = checkConfig(config.concat(app.config));
    }
    catch(ex) {
        return callback(ex);
    }

    // prevent double loading of plugins
    sortedConfig = sortedConfig.filter(function(c) {
        return config.indexOf(c) > -1;
    });

    var p;
    function next(err) {
        if (err) {
            return callback(err);
        }
        if (p && app.config.indexOf(p) === -1) {
            app.config.push(p);
        }

        p = sortedConfig.shift();
        if (!p) {
            return callback();
        }
        app.registerPlugin(p, next);
    }
    next();
};

/**
 * Register a plugin in the service
 */
Archie.prototype.registerPlugin = function(plugin, next) {
    var app = this;
    var services = app.services;

    var imports = {};
    if (plugin.consumes) {
        plugin.consumes.forEach(function (name) {
            imports[name] = services[name];
        });
    }

    try {
        // this should be called from the wrapper
        plugin.packageWrapper.setupPlugin(plugin, imports, register);
    } catch(e) {
        return app.emit("error", e);
    }

    function register(err, provided) {
        if (err) {
            return app.emit("error", err);
        }

        plugin.provides.forEach(function (name) {
            if (!provided.hasOwnProperty(name)) {
                var err = new Error("Plugin failed to provide " + name + " service. " + JSON.stringify(plugin));
                return app.emit("error", err);
            }
            services[name] = provided[name];

            // check for user mistake - forgot module.exports.
            if( isEmpty(services[name]) ){
                console.warn("Warning! looks like service '" + name + "' does not exports or module.exports any objects.");
            }

            if (typeof provided[name] != "function")
                provided[name].name = name;

            app.emit("service", name, services[name]);
        });
        if (provided && provided.hasOwnProperty("onDestroy")) {
            app.destructors.push(provided.onDestroy);
        }

        plugin.destroy = function() {
            if (plugin.provides.length) {
                // @todo, make it possible if all consuming plugins are also dead
                var err = new Error("Plugins that provide services cannot be destroyed. " + JSON.stringify(plugin));
                return app.emit("error", err);
            }

            if (provided && provided.hasOwnProperty("onDestroy")) {
                app.destructors.splice(app.destructors.indexOf(provided.onDestroy), 1);
                provided.onDestroy();
            }

            // delete from config
            app.config.splice(app.config.indexOf(plugin), 1);
            app.emit("destroyed", plugin);
        };

        app.emit("plugin", plugin);
        next();
    }
};

Archie.prototype.getService = function(name) {
    if (!this.services[name]) {
        throw new Error("Service '" + name + "' not found in archie app!");
    }
    return this.services[name];
};

// Returns an event emitter that represents the app.  It can emit events.
// event: ("service" name, service) emitted when a service is ready to be consumed.
// event: ("plugin", plugin) emitted when a plugin registers.
// event: ("ready", app) emitted when all plugins are ready.
// event: ("error", err) emitted when something goes wrong.
// app.services - a hash of all the services in this app
// app.config - the plugin config that was passed in.
function createApp(config, callback) {
    var app;
    try {
        app = new Archie(config);
    } catch(err) {
        if (!callback) throw err;
        return callback(err, app);
    }
    if (callback) {
        app.on("error", done);
        app.on("ready", onReady);
    }
    return app;

    function onReady(app) {
        done();
    }

    function done(err) {
        if (err) {
            app.destroy();
        }
        app.removeListener("error", done);
        app.removeListener("ready", onReady);
        callback(err, app);
    }

}

function isEmpty(obj){
    for(var prop in obj){
        return false;
    }
    return true;
}

module.exports = exports;
<commit_msg>look for plugins in user specified directory first (priority) followed by node_modules directory<commit_after>"use strict";

var events = require('events');
var EventEmitter = events.EventEmitter;

var Wrappers = require('./wrappers');

var exports = {};

// Only define Node-style usage using sync I/O if in node.
(function () {
    var dirname = require('path').dirname;
    var resolve = require('path').resolve;
    var existsSync = require('fs').existsSync || require('path').existsSync;
    var realpathSync = require('fs').realpathSync;
    var packagePathCache = {};

    exports.loadConfig = loadConfig;
    exports.resolveConfig = resolveConfig;

    // This is assumed to be used at startup and uses sync I/O as well as can
    // throw exceptions.  It loads and parses a config file.
    function loadConfig(configPath, callback) {
      var config = require(configPath);
      var base = dirname(configPath);

      var ext_config = resolveDefaultWrappers(config, base, callback);
      return resolveConfig(ext_config, base, callback);
    }

    function resolveConfig(config, base) {
        config.forEach(function (plugin, index) {
            // Shortcut where string is used for plugin without any options.
            if (typeof plugin === "string") {
                plugin = config[index] = { packagePath: plugin };
            }

            // The plugin is a package on the disk.  We need to load it.
            if (plugin.hasOwnProperty("packagePath")
                  && !(plugin.hasOwnProperty("setup") || plugin.hasOwnProperty("provides"))) {
                var defaults = resolveModule(base, plugin.packagePath);
                Object.keys(defaults).forEach(function (key) {
                    if (!plugin.hasOwnProperty(key)) {
                        plugin[key] = defaults[key];
                    }
                });

                // if no, don't load setup function, etc and create hooks
                plugin.packagePath = defaults.packagePath; // now has the file to load
                plugin.provides = defaults.provides;
                plugin.consumes = defaults.consumes;

                // not all packages have a main entry point
                // in which case require fails.
                try{
                    plugin.setup = require(plugin.packagePath);
                } catch(e){}

                resolveWrappedServices(base, plugin);
            }
        });
        return config;
    }

    // Loads a module, getting metadata from either it's package.json or export
    // object.
    function resolveModule(base, modulePath) {
        var packagePath;
        try {
            packagePath = resolvePackage(base, modulePath + "/package.json");
        }
        catch (err) {
            if (err.code !== "ENOENT") throw err;
        }
        var packageJson = packagePath && require(packagePath) || {};
        if (packageJson && !packageJson.plugin){ // user friendly message
            console.warn("WARNING from " + modulePath);
            console.warn("NOTE: plugin:{...} is missing in package.json");
        }

        var metadata = packagePath && packageJson.plugin || {};

       if (packagePath) {
            modulePath = dirname(packagePath);
        } else {
            try {
                modulePath = resolvePackage(base, modulePath);
            } catch(e) {}
        }

        // pacakgeJson - may not have a main entry point
        // in which case these functions are not needed.
        var module = {};
        if(packageJson.main){
            module = require(modulePath);
        }
        metadata.provides = metadata.provides || module.provides || [];
        metadata.consumes = metadata.consumes || module.consumes || [];
        metadata.packagePath = modulePath;
        return metadata;
    }

    // Node style package resolving so that plugins' package.json can be found relative to the config file
    // It's not the full node require system algorithm, but it's the 99% case
    // This throws, make sure to wrap in try..catch
    function resolvePackage(base, packagePath) {
        var originalBase = base;
        if (!(base in packagePathCache)) {
            packagePathCache[base] = {};
        }
        var cache = packagePathCache[base];
        if (packagePath in cache) {
            return cache[packagePath];
        }
        var newPath, newBase;

        newPath = resolve(base, packagePath);
        if (existsSync(newPath)) {
            newPath = realpathSync(newPath);
            cache[packagePath] = newPath;
            return newPath;
        }
        else { // if we did not find the package, look for it in node_modules
            while (base) {
                newPath = resolve(base, "node_modules", packagePath);
                if (existsSync(newPath)) {
                    newPath = realpathSync(newPath);
                    cache[packagePath] = newPath;
                    return newPath;
                }
                newBase = resolve(base, '..');
                if (base === newBase) {
                    break;
                }
                base = newBase;
            }
        }
        var err = new Error("Can't find '" + packagePath + "' relative to '" + originalBase + "'");
        err.code = "ENOENT";
        throw err;
    }

    // Load all objects that are provided by the module (they will be consumed by wrapper)
    function resolveWrappedServices(base, plugin){
        if(!plugin.packageWrapper){
            plugin.packageWrapper = Wrappers.defaultWrapperName;
        }
        var wrapperInst = Wrappers.newWrapper(plugin.packageWrapper);
        if(!wrapperInst){
            var errmsg = "No registered wrapper with the name " + plugin.packageWrapper;
            throw new Error(errmsg);
        }
        wrapperInst.resolveConfig(plugin, base);
        plugin.packageWrapper = wrapperInst;
    }
}());

exports.createApp = createApp;
exports.Archie = Archie;

// Check a plugin config list for bad dependencies and throw on error
function checkConfig(config) {

    // Check for the required fields in each plugin.
    config.forEach(function (plugin) {
        if (plugin.checked) { return; }
        // legacy: not all packages have setup functions
        //if (!plugin.hasOwnProperty("setup")) {
        //    throw new Error("Plugin is missing the setup function " + JSON.stringify(plugin));
        //}
        if (!plugin.hasOwnProperty("provides")) {
            throw new Error("Plugin is missing the provides array " + JSON.stringify(plugin));
        }
        if (!plugin.hasOwnProperty("consumes")) {
            throw new Error("Plugin is missing the consumes array " + JSON.stringify(plugin));
        }
    });

    return checkCycles(config);
}

function checkCycles(config) {
    var plugins = [];
    config.forEach(function(pluginConfig, index) {
        plugins.push({
            packagePath: pluginConfig.packagePath,
            provides: pluginConfig.provides.concat(),
            consumes: pluginConfig.consumes.concat(),
            i: index
        });
    });

    var resolved = {
        hub: true
    };
    var changed = true;
    var sorted = [];

    while(plugins.length && changed) {
        changed = false;

        plugins.concat().forEach(function(plugin) {
            var consumes = plugin.consumes.concat();

            var resolvedAll = true;
            for (var i=0; i<consumes.length; i++) {
                var service = consumes[i];
                if (!resolved[service]) {
                    resolvedAll = false;
                } else {
                    plugin.consumes.splice(plugin.consumes.indexOf(service), 1);
                }
            }

            if (!resolvedAll)
                return;

            plugins.splice(plugins.indexOf(plugin), 1);
            plugin.provides.forEach(function(service) {
                resolved[service] = true;
            });
            sorted.push(config[plugin.i]);
            changed = true;
        });
    }

    if (plugins.length) {
        var unresolved = {};
        plugins.forEach(function(plugin) {
            delete plugin.config;
            plugin.consumes.forEach(function(name) {
                if (unresolved[name] == false)
                    return;
                if (!unresolved[name])
                    unresolved[name] = [];
                unresolved[name].push(plugin.packagePath);
            });
            plugin.provides.forEach(function(name) {
                unresolved[name] = false;
            });
        });

        Object.keys(unresolved).forEach(function(name) {
            if (unresolved[name] == false)
                delete unresolved[name];
        });

        console.error("Could not resolve dependencies of these plugins:", plugins);
        console.error("Resolved services:", Object.keys(resolved));
        console.error("Missing services:", unresolved);
        throw new Error("Could not resolve dependencies");
    }

    return sorted;
}

function Archie(config) {
    var app = this;
    app.config = [];
    app.destructors = [];
    app.services = {
        hub: {
            on: function (name, callback) {
                app.on(name, callback);
            }
        }
    };

    // Give createApp some time to subscribe to our "ready" event
    (typeof process === "object" ? process.nextTick : setTimeout)(function() {
        app.loadPlugins(config, function(err) {
            if (err) {
                throw err;
            }
            app.emit("ready", app);
        });
    });
}

Archie.prototype = Object.create(EventEmitter.prototype, {constructor:{value:Archie}});

Archie.prototype.destroy = function() {
    var app = this;

    app.destructors.forEach(function(destroy) {
        destroy();
    });

    app.destructors = [];
};

Archie.prototype.loadPlugins = function(config, callback) {
    var app = this;

    var sortedConfig;
    try {
        sortedConfig = checkConfig(config.concat(app.config));
    }
    catch(ex) {
        return callback(ex);
    }

    // prevent double loading of plugins
    sortedConfig = sortedConfig.filter(function(c) {
        return config.indexOf(c) > -1;
    });

    var p;
    function next(err) {
        if (err) {
            return callback(err);
        }
        if (p && app.config.indexOf(p) === -1) {
            app.config.push(p);
        }

        p = sortedConfig.shift();
        if (!p) {
            return callback();
        }
        app.registerPlugin(p, next);
    }
    next();
};

/**
 * Register a plugin in the service
 */
Archie.prototype.registerPlugin = function(plugin, next) {
    var app = this;
    var services = app.services;

    var imports = {};
    if (plugin.consumes) {
        plugin.consumes.forEach(function (name) {
            imports[name] = services[name];
        });
    }

    try {
        // this should be called from the wrapper
        plugin.packageWrapper.setupPlugin(plugin, imports, register);
    } catch(e) {
        return app.emit("error", e);
    }

    function register(err, provided) {
        if (err) {
            return app.emit("error", err);
        }

        plugin.provides.forEach(function (name) {
            if (!provided.hasOwnProperty(name)) {
                var err = new Error("Plugin failed to provide " + name + " service. " + JSON.stringify(plugin));
                return app.emit("error", err);
            }
            services[name] = provided[name];

            // check for user mistake - forgot module.exports.
            if( isEmpty(services[name]) ){
                console.warn("Warning! looks like service '" + name + "' does not exports or module.exports any objects.");
            }

            if (typeof provided[name] != "function")
                provided[name].name = name;

            app.emit("service", name, services[name]);
        });
        if (provided && provided.hasOwnProperty("onDestroy")) {
            app.destructors.push(provided.onDestroy);
        }

        plugin.destroy = function() {
            if (plugin.provides.length) {
                // @todo, make it possible if all consuming plugins are also dead
                var err = new Error("Plugins that provide services cannot be destroyed. " + JSON.stringify(plugin));
                return app.emit("error", err);
            }

            if (provided && provided.hasOwnProperty("onDestroy")) {
                app.destructors.splice(app.destructors.indexOf(provided.onDestroy), 1);
                provided.onDestroy();
            }

            // delete from config
            app.config.splice(app.config.indexOf(plugin), 1);
            app.emit("destroyed", plugin);
        };

        app.emit("plugin", plugin);
        next();
    }
};

Archie.prototype.getService = function(name) {
    if (!this.services[name]) {
        throw new Error("Service '" + name + "' not found in archie app!");
    }
    return this.services[name];
};

// Returns an event emitter that represents the app.  It can emit events.
// event: ("service" name, service) emitted when a service is ready to be consumed.
// event: ("plugin", plugin) emitted when a plugin registers.
// event: ("ready", app) emitted when all plugins are ready.
// event: ("error", err) emitted when something goes wrong.
// app.services - a hash of all the services in this app
// app.config - the plugin config that was passed in.
function createApp(config, callback) {
    var app;
    try {
        app = new Archie(config);
    } catch(err) {
        if (!callback) throw err;
        return callback(err, app);
    }
    if (callback) {
        app.on("error", done);
        app.on("ready", onReady);
    }
    return app;

    function onReady(app) {
        done();
    }

    function done(err) {
        if (err) {
            app.destroy();
        }
        app.removeListener("error", done);
        app.removeListener("ready", onReady);
        callback(err, app);
    }

}

function isEmpty(obj){
    for(var prop in obj){
        return false;
    }
    return true;
}

module.exports = exports;
<|endoftext|>


<commit_before>;(function(){ 'use strict';

  // registers the extension on a cytoscape lib ref
  var register = function( cytoscape ){

    if( !cytoscape ){ return; } // can't register if cytoscape unspecified

    var defaults = {
      // define the default options for your layout here
      refreshInterval: 16, // in ms
      refreshIterations: 10, // iterations until thread sends an update
      fit: true
    };

    var extend = Object.assign || function( tgt ){
      for( var i = 1; i < arguments.length; i++ ){
        var obj = arguments[i];

        for( var k in obj ){ tgt[k] = obj[k]; }
      }

      return tgt;
    };

    function Layout( options ){
      this.options = extend( {}, defaults, options );
    }

    Layout.prototype.run = function(){
      var layout = this;
      var options = this.options;
      var cy = options.cy;
      var eles = options.eles;
      var nodes = eles.nodes();
      var edges = eles.edges();

      var positions = [];

      (function klayinit(){
        var properties = function(){
          var temp = {
            "addUnnecessaryBendpoints": "de.cau.cs.kieler.klay.layered.unnecessaryBendpoints",
            "alignment": "de.cau.cs.kieler.alignment",
            "aspectRatio": "de.cau.cs.kieler.aspectRatio",
						"borderSpacing": "borderSpacing",
						"compactComponents": "de.cau.cs.kieler.klay.layered.components.compact",
						"compactionStrategy": "de.cau.cs.kieler.klay.layered.nodeplace.compactionStrategy",
						"contentAlignment": "de.cau.cs.kieler.klay.layered.contentAlignment",
						"crossingMinimization": "de.cau.cs.kieler.klay.layered.crossMin",
						"cycleBreaking": "de.cau.cs.kieler.klay.layered.cycleBreaking",
						"debugMode": "de.cau.cs.kieler.debugMode",
						"direction": "de.cau.cs.kieler.direction",
						"edgeLabelSideSelection": "de.cau.cs.kieler.klay.layered.edgeLabelSideSelection",
						// <broken> "de.cau.cs.kieler.klay.layered.edgeNodeSpacingFactor": options.edgeNodeSpacingFactor,
						"edgeRouting": "de.cau.cs.kieler.edgeRouting",
						"edgeSpacingFactor": "de.cau.cs.kieler.klay.layered.edgeSpacingFactor",
						"feedbackEdges": "de.cau.cs.kieler.klay.layered.feedBackEdges",
						"fixedAlignment": "de.cau.cs.kieler.klay.layered.fixedAlignment",
						"greedySwitchCrossingMinimization": "de.cau.cs.kieler.klay.layered.greedySwitch",
						"hierarchyHandling": "de.cau.cs.kieler.hierarchyHandling",
						"inLayerSpacingFactor": "de.cau.cs.kieler.klay.layered.inLayerSpacingFactor",
						"interactiveReferencePoint": "de.cau.cs.kieler.klay.layered.interactiveReferencePoint",
						"layerConstraint": "de.cau.cs.kieler.klay.layered.layerConstraint",
						"layoutHierarchy": "de.cau.cs.kieler.layoutHierarchy",
						"linearSegmentsDeflectionDampening": "de.cau.cs.kieler.klay.layered.linearSegmentsDeflectionDampening",
						"mergeEdges": "de.cau.cs.kieler.klay.layered.mergeEdges",
						"mergeHierarchyCrossingEdges": "de.cau.cs.kieler.klay.layered.mergeHierarchyEdges",
						"noLayout": "de.cau.cs.kieler.noLayout",
						"nodeLabelPlacement": "de.cau.cs.kieler.nodeLabelPlacement",
						"nodeLayering": "de.cau.cs.kieler.klay.layered.nodeLayering",
						"nodePlacement": "de.cau.cs.kieler.klay.layered.nodePlace",
						"portAlignment": "de.cau.cs.kieler.portAlignment",
						"portAlignmentEastern": "de.cau.cs.kieler.portAlignment.east",
						"portAlignmentNorth": "de.cau.cs.kieler.portAlignment.north",
						"portAlignmentSouth": "de.cau.cs.kieler.portAlignment.south",
						"portAlignmentWest": "de.cau.cs.kieler.portAlignment.west",
						"portConstraints": "de.cau.cs.kieler.portConstraints",
						"portLabelPlacement": "de.cau.cs.kieler.portLabelPlacement",
						"portOffset": "de.cau.cs.kieler.offset",
						"portSide": "de.cau.cs.kieler.portSide",
						"portSpacing": "de.cau.cs.kieler.portSpacing",
						"postCompaction": "de.cau.cs.kieler.klay.layered.postCompaction",
						"priority": "de.cau.cs.kieler.priority",
						"randomizationSeed": "de.cau.cs.kieler.randomSeed",
						"routeSelfLoopInside": "de.cau.cs.kieler.selfLoopInside",
						"separateConnectedComponents": "de.cau.cs.kieler.separateConnComp",
						"sizeConstraint": "de.cau.cs.kieler.sizeConstraint",
						"sizeOptions": "de.cau.cs.kieler.sizeOptions",
						"spacing": "de.cau.cs.kieler.spacing",
						"splineSelfLoopPlacement": "de.cau.cs.kieler.klay.layered.splines.selfLoopPlacement",
						"thoroughness": "de.cau.cs.kieler.klay.layered.thoroughness",
						"wideNodesOnMultipleLayers": "de.cau.cs.kieler.klay.layered.wideNodesOnMultipleLayers"
          };
          // to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion you must learn how to understand recursion
          var optionsOut = {};
          var i = 0;
          for(i in options){
            if(options[i] !== 'undefined'){
              var j = 0;
              for(j in temp){
                if(j === i){
                  optionsOut[temp[j]] = options[i];
                }
              }
            }
          }
          return optionsOut;
        };

        var children = function(){
          var temp = [];
          for(var i = 0; i < nodes.length; i++){
            if(nodes[i].data().parent === undefined){
              temp.push({
                "id": nodes[i].data().id,
                "width": 4,
                "height": 4,
                "children": [],
              });
            }else{
              var j;
              for(j = 0; j < temp.length; j++){
                if(temp[j].id === nodes[i].data().parent){
                  temp[j].children.push({
                    "id": nodes[i].data().id,
                    "width": 4,
                    "height": 4,
                    "children": []
                  });
                }
              }
            }
          }
          return temp;
        };

        var kedges = function(){
          var temp = [];
          var i;
          for(i = 0; i < edges.length; i++){
            temp[i] ={
              "id": edges[i].data().id,
              "source": edges[i].data().source,
              "target": edges[i].data().target
            }
          }
          return temp;
        };

        var graph = {
          "id": "root",
          properties: properties(),
          "children": children(),
          "edges": kedges()
        };

        $klay.layout({
          graph:graph,
          options:{
            spacing: 50
          },
          success: function(layouted){
            //console.log(layouted);
          },
          error: function(){
            //console.log(error);
          }

        });

        function recordPositions(nodesIn){
          for(var i=0; i < nodesIn.length; i++){
            positions.push({
              "id": nodesIn[i].id,
              "x": nodesIn[i].x,
              "y": nodesIn[i].y
            });
            if(nodesIn[i].children !== undefined){
              recordPositions(nodesIn[i].children);
            }
          }
        }

        recordPositions(graph.children);

        function recordEdges(edgesIn){
          for(var i = 0; i < edgesIn.length; i++){
            //console.log(edgesIn);
            if(edgesIn[i].bendPoints !== undefined){
              //console.log(edgesIn[i]);
              for(var j = 0; j < edges.length; j++){
                //console.log(edges[j].data().id);
                //console.log(edgesIn[i].id);
                if(edges[j].data().id === edgesIn[i].id){
                  edges[j].rscratch = edgesIn[i].bendPoints;
                }
              }
            }
          }
        }
        recordEdges(graph.edges);

      })();

      var getPos = function( i, ele ){
        var j = 0;
        for(j = 0; j < positions.length; j++){
          if(positions[j].id === ele.data().id){
            return {
              x: positions[i].x,
              y: positions[i].y
            };
          }
        }
        /*if(ele.data().parent === undefined){
          return {
            x: positions[i].x,
            y: positions[i].y
          };
        }else{
          var j;
          for(j = 0; j < temp.length; j++){
            if(temp[j].id === nodes[i].data().parent){
              temp[j].children.push({
                "id": nodes[i].data().id,
                "width": 4,
                "height": 4
              });
            }
          }
        }*/
      };
      nodes.layoutPositions( layout, options, getPos );

      return this; // or...

      // continuous/asynchronous layouts need to do things manually:
      // (this example uses a thread, but you could use a fabric to get even
      // better performance if your algorithm allows for it)

      var thread = this.thread = cytoscape.thread();
      thread.require( getPos, 'getPos' );

      // to indicate we've started
      layout.trigger('layoutstart');

      // for thread updates
      var firstUpdate = true;
      var id2pos = {};
      var updateTimeout;

      // update node positions
      var update = function(){
        nodes.positions(function( i, node ){
          return id2pos[ node.id() ];
        });

        // maybe we fit each iteration
        if( options.fit ){
          cy.fit( options.padding );
        }

        if( firstUpdate ){
          // indicate the initial positions have been set
          layout.trigger('layoutready');
          firstUpdate = false;
        }
      };

      // update the node positions when notified from the thread but
      // rate limit it a bit (don't want to overwhelm the main/ui thread)
      thread.on('message', function( e ){
        var nodeJsons = e.message;
        nodeJsons.forEach(function( n ){ id2pos[n.data.id] = n.position; });

        if( !updateTimeout ){
          updateTimeout = setTimeout( function(){
            update();
            updateTimeout = null;
          }, options.refreshInterval );
        }
      });

      // we want to keep the json sent to threads slim and fast
      var eleAsJson = function( ele ){
        return {
          data: {
            id: ele.data('id'),
            source: ele.data('source'),
            target: ele.data('target'),
            parent: ele.data('parent')
          },
          group: ele.group(),
          position: ele.position()

          // maybe add calculated data for the layout, like edge length or node mass
        };
      };

      // data to pass to thread
      var pass = {
        eles: eles.map( eleAsJson ),
        refreshIterations: options.refreshIterations
        // maybe some more options that matter to the calculations here ...
      };

      // then we calculate for a while to get the final positions
      thread.pass( pass ).run(function( pass ){
        var getRandomPos = _ref_('getRandomPos');
        var broadcast = _ref_('broadcast');
        var nodeJsons = pass.eles.filter(function(e){ return e.group === 'nodes'; });

        // calculate for a while (you might use the edges here)
        for( var i = 0; i < 100000; i++ ){
          nodeJsons.forEach(function( nodeJson, j ){
            nodeJson.position = getRandomPos( j, nodeJson );
          });

          if( i % pass.refreshIterations === 0 ){ // cheaper to not broadcast all the time
            broadcast( nodeJsons ); // send new positions outside the thread
          }
        }
      }).then(function(){
        // to indicate we've finished
        layout.trigger('layoutstop');
      });

      return this; // chaining
    };

    Layout.prototype.stop = function(){
      // continuous/asynchronous layout may want to set a flag etc to let
      // run() know to stop

      if( this.thread ){
        this.thread.stop();
      }

      this.trigger('layoutstop');

      return this; // chaining
    };

    Layout.prototype.destroy = function(){
      // clean up here if you create threads etc

      if( this.thread ){
        this.thread.stop();
      }

      return this; // chaining
    };

    cytoscape( 'layout', 'klayjs', Layout ); // register with cytoscape.js

  };

  if( typeof module !== 'undefined' && module.exports ){ // expose as a commonjs module
    module.exports = register;
  }

  if( typeof define !== 'undefined' && define.amd ){ // expose as an amd/requirejs module
    define('cytoscape-klayjs', function(){
      return register;
    });
  }

  if( typeof cytoscape !== 'undefined' ){ // expose to global cytoscape (i.e. window.cytoscape)
    register( cytoscape );
  }

})();
<commit_msg>Removed unnecessary comment<commit_after>;(function(){ 'use strict';

  // registers the extension on a cytoscape lib ref
  var register = function( cytoscape ){

    if( !cytoscape ){ return; } // can't register if cytoscape unspecified

    var defaults = {
      // define the default options for your layout here
      refreshInterval: 16, // in ms
      refreshIterations: 10, // iterations until thread sends an update
      fit: true
    };

    var extend = Object.assign || function( tgt ){
      for( var i = 1; i < arguments.length; i++ ){
        var obj = arguments[i];

        for( var k in obj ){ tgt[k] = obj[k]; }
      }

      return tgt;
    };

    function Layout( options ){
      this.options = extend( {}, defaults, options );
    }

    Layout.prototype.run = function(){
      var layout = this;
      var options = this.options;
      var cy = options.cy;
      var eles = options.eles;
      var nodes = eles.nodes();
      var edges = eles.edges();

      var positions = [];

      (function klayinit(){
        var properties = function(){
          var temp = {
            "addUnnecessaryBendpoints": "de.cau.cs.kieler.klay.layered.unnecessaryBendpoints",
            "alignment": "de.cau.cs.kieler.alignment",
            "aspectRatio": "de.cau.cs.kieler.aspectRatio",
						"borderSpacing": "borderSpacing",
						"compactComponents": "de.cau.cs.kieler.klay.layered.components.compact",
						"compactionStrategy": "de.cau.cs.kieler.klay.layered.nodeplace.compactionStrategy",
						"contentAlignment": "de.cau.cs.kieler.klay.layered.contentAlignment",
						"crossingMinimization": "de.cau.cs.kieler.klay.layered.crossMin",
						"cycleBreaking": "de.cau.cs.kieler.klay.layered.cycleBreaking",
						"debugMode": "de.cau.cs.kieler.debugMode",
						"direction": "de.cau.cs.kieler.direction",
						"edgeLabelSideSelection": "de.cau.cs.kieler.klay.layered.edgeLabelSideSelection",
						// <broken> "de.cau.cs.kieler.klay.layered.edgeNodeSpacingFactor": options.edgeNodeSpacingFactor,
						"edgeRouting": "de.cau.cs.kieler.edgeRouting",
						"edgeSpacingFactor": "de.cau.cs.kieler.klay.layered.edgeSpacingFactor",
						"feedbackEdges": "de.cau.cs.kieler.klay.layered.feedBackEdges",
						"fixedAlignment": "de.cau.cs.kieler.klay.layered.fixedAlignment",
						"greedySwitchCrossingMinimization": "de.cau.cs.kieler.klay.layered.greedySwitch",
						"hierarchyHandling": "de.cau.cs.kieler.hierarchyHandling",
						"inLayerSpacingFactor": "de.cau.cs.kieler.klay.layered.inLayerSpacingFactor",
						"interactiveReferencePoint": "de.cau.cs.kieler.klay.layered.interactiveReferencePoint",
						"layerConstraint": "de.cau.cs.kieler.klay.layered.layerConstraint",
						"layoutHierarchy": "de.cau.cs.kieler.layoutHierarchy",
						"linearSegmentsDeflectionDampening": "de.cau.cs.kieler.klay.layered.linearSegmentsDeflectionDampening",
						"mergeEdges": "de.cau.cs.kieler.klay.layered.mergeEdges",
						"mergeHierarchyCrossingEdges": "de.cau.cs.kieler.klay.layered.mergeHierarchyEdges",
						"noLayout": "de.cau.cs.kieler.noLayout",
						"nodeLabelPlacement": "de.cau.cs.kieler.nodeLabelPlacement",
						"nodeLayering": "de.cau.cs.kieler.klay.layered.nodeLayering",
						"nodePlacement": "de.cau.cs.kieler.klay.layered.nodePlace",
						"portAlignment": "de.cau.cs.kieler.portAlignment",
						"portAlignmentEastern": "de.cau.cs.kieler.portAlignment.east",
						"portAlignmentNorth": "de.cau.cs.kieler.portAlignment.north",
						"portAlignmentSouth": "de.cau.cs.kieler.portAlignment.south",
						"portAlignmentWest": "de.cau.cs.kieler.portAlignment.west",
						"portConstraints": "de.cau.cs.kieler.portConstraints",
						"portLabelPlacement": "de.cau.cs.kieler.portLabelPlacement",
						"portOffset": "de.cau.cs.kieler.offset",
						"portSide": "de.cau.cs.kieler.portSide",
						"portSpacing": "de.cau.cs.kieler.portSpacing",
						"postCompaction": "de.cau.cs.kieler.klay.layered.postCompaction",
						"priority": "de.cau.cs.kieler.priority",
						"randomizationSeed": "de.cau.cs.kieler.randomSeed",
						"routeSelfLoopInside": "de.cau.cs.kieler.selfLoopInside",
						"separateConnectedComponents": "de.cau.cs.kieler.separateConnComp",
						"sizeConstraint": "de.cau.cs.kieler.sizeConstraint",
						"sizeOptions": "de.cau.cs.kieler.sizeOptions",
						"spacing": "de.cau.cs.kieler.spacing",
						"splineSelfLoopPlacement": "de.cau.cs.kieler.klay.layered.splines.selfLoopPlacement",
						"thoroughness": "de.cau.cs.kieler.klay.layered.thoroughness",
						"wideNodesOnMultipleLayers": "de.cau.cs.kieler.klay.layered.wideNodesOnMultipleLayers"
          };
          var optionsOut = {};
          var i = 0;
          for(i in options){
            if(options[i] !== 'undefined'){
              var j = 0;
              for(j in temp){
                if(j === i){
                  optionsOut[temp[j]] = options[i];
                }
              }
            }
          }
          return optionsOut;
        };

        var children = function(){
          var temp = [];
          for(var i = 0; i < nodes.length; i++){
            if(nodes[i].data().parent === undefined){
              temp.push({
                "id": nodes[i].data().id,
                "width": 4,
                "height": 4,
                "children": [],
              });
            }else{
              var j;
              for(j = 0; j < temp.length; j++){
                if(temp[j].id === nodes[i].data().parent){
                  temp[j].children.push({
                    "id": nodes[i].data().id,
                    "width": 4,
                    "height": 4,
                    "children": []
                  });
                }
              }
            }
          }
          return temp;
        };

        var kedges = function(){
          var temp = [];
          var i;
          for(i = 0; i < edges.length; i++){
            temp[i] ={
              "id": edges[i].data().id,
              "source": edges[i].data().source,
              "target": edges[i].data().target
            }
          }
          return temp;
        };

        var graph = {
          "id": "root",
          properties: properties(),
          "children": children(),
          "edges": kedges()
        };

        $klay.layout({
          graph:graph,
          options:{
            spacing: 50
          },
          success: function(layouted){
            //console.log(layouted);
          },
          error: function(){
            //console.log(error);
          }

        });

        function recordPositions(nodesIn){
          for(var i=0; i < nodesIn.length; i++){
            positions.push({
              "id": nodesIn[i].id,
              "x": nodesIn[i].x,
              "y": nodesIn[i].y
            });
            if(nodesIn[i].children !== undefined){
              recordPositions(nodesIn[i].children);
            }
          }
        }

        recordPositions(graph.children);

        function recordEdges(edgesIn){
          for(var i = 0; i < edgesIn.length; i++){
            //console.log(edgesIn);
            if(edgesIn[i].bendPoints !== undefined){
              //console.log(edgesIn[i]);
              for(var j = 0; j < edges.length; j++){
                //console.log(edges[j].data().id);
                //console.log(edgesIn[i].id);
                if(edges[j].data().id === edgesIn[i].id){
                  edges[j].rscratch = edgesIn[i].bendPoints;
                }
              }
            }
          }
        }
        recordEdges(graph.edges);

      })();

      var getPos = function( i, ele ){
        var j = 0;
        for(j = 0; j < positions.length; j++){
          if(positions[j].id === ele.data().id){
            return {
              x: positions[i].x,
              y: positions[i].y
            };
          }
        }
        /*if(ele.data().parent === undefined){
          return {
            x: positions[i].x,
            y: positions[i].y
          };
        }else{
          var j;
          for(j = 0; j < temp.length; j++){
            if(temp[j].id === nodes[i].data().parent){
              temp[j].children.push({
                "id": nodes[i].data().id,
                "width": 4,
                "height": 4
              });
            }
          }
        }*/
      };
      nodes.layoutPositions( layout, options, getPos );

      return this; // or...

      // continuous/asynchronous layouts need to do things manually:
      // (this example uses a thread, but you could use a fabric to get even
      // better performance if your algorithm allows for it)

      var thread = this.thread = cytoscape.thread();
      thread.require( getPos, 'getPos' );

      // to indicate we've started
      layout.trigger('layoutstart');

      // for thread updates
      var firstUpdate = true;
      var id2pos = {};
      var updateTimeout;

      // update node positions
      var update = function(){
        nodes.positions(function( i, node ){
          return id2pos[ node.id() ];
        });

        // maybe we fit each iteration
        if( options.fit ){
          cy.fit( options.padding );
        }

        if( firstUpdate ){
          // indicate the initial positions have been set
          layout.trigger('layoutready');
          firstUpdate = false;
        }
      };

      // update the node positions when notified from the thread but
      // rate limit it a bit (don't want to overwhelm the main/ui thread)
      thread.on('message', function( e ){
        var nodeJsons = e.message;
        nodeJsons.forEach(function( n ){ id2pos[n.data.id] = n.position; });

        if( !updateTimeout ){
          updateTimeout = setTimeout( function(){
            update();
            updateTimeout = null;
          }, options.refreshInterval );
        }
      });

      // we want to keep the json sent to threads slim and fast
      var eleAsJson = function( ele ){
        return {
          data: {
            id: ele.data('id'),
            source: ele.data('source'),
            target: ele.data('target'),
            parent: ele.data('parent')
          },
          group: ele.group(),
          position: ele.position()

          // maybe add calculated data for the layout, like edge length or node mass
        };
      };

      // data to pass to thread
      var pass = {
        eles: eles.map( eleAsJson ),
        refreshIterations: options.refreshIterations
        // maybe some more options that matter to the calculations here ...
      };

      // then we calculate for a while to get the final positions
      thread.pass( pass ).run(function( pass ){
        var getRandomPos = _ref_('getRandomPos');
        var broadcast = _ref_('broadcast');
        var nodeJsons = pass.eles.filter(function(e){ return e.group === 'nodes'; });

        // calculate for a while (you might use the edges here)
        for( var i = 0; i < 100000; i++ ){
          nodeJsons.forEach(function( nodeJson, j ){
            nodeJson.position = getRandomPos( j, nodeJson );
          });

          if( i % pass.refreshIterations === 0 ){ // cheaper to not broadcast all the time
            broadcast( nodeJsons ); // send new positions outside the thread
          }
        }
      }).then(function(){
        // to indicate we've finished
        layout.trigger('layoutstop');
      });

      return this; // chaining
    };

    Layout.prototype.stop = function(){
      // continuous/asynchronous layout may want to set a flag etc to let
      // run() know to stop

      if( this.thread ){
        this.thread.stop();
      }

      this.trigger('layoutstop');

      return this; // chaining
    };

    Layout.prototype.destroy = function(){
      // clean up here if you create threads etc

      if( this.thread ){
        this.thread.stop();
      }

      return this; // chaining
    };

    cytoscape( 'layout', 'klayjs', Layout ); // register with cytoscape.js

  };

  if( typeof module !== 'undefined' && module.exports ){ // expose as a commonjs module
    module.exports = register;
  }

  if( typeof define !== 'undefined' && define.amd ){ // expose as an amd/requirejs module
    define('cytoscape-klayjs', function(){
      return register;
    });
  }

  if( typeof cytoscape !== 'undefined' ){ // expose to global cytoscape (i.e. window.cytoscape)
    register( cytoscape );
  }

})();
<|endoftext|>


<commit_before>
var config = require("../config/config.js");
var _ = require("lodash");

module.exports = function *(next) {
    var headers = this.req.headers;

    if (config.api_token === "Not-a-real-token") {
        yield next;
***REMOVED***
    else if (_.get(headers, "x-token") === config.api_token) {
        yield next;
***REMOVED***
    ***REMOVED***
        this.response.status  = 401;
        this.response.message = "Please provide the correct Authorization header";
        return;
***REMOVED***

***REMOVED***;<commit_msg>Include old token<commit_after>
var config = require("../config/config.js");
var _ = require("lodash");

module.exports = function *(next) {
    var headers = this.req.headers;

    if (config.api_token === "Not-a-real-token") {
        yield next;
***REMOVED***
    else if (_.get(headers, "x-token") === config.api_token || _.get(headers, "x-token") === "Banananana-ram mystic fleet 3!sixtyfivethousand world") {
        yield next;
***REMOVED***
    ***REMOVED***
        this.response.status  = 401;
        this.response.message = "Please provide the correct Authorization header";
        return;
***REMOVED***

***REMOVED***;<|endoftext|>


<commit_before>/**
 * @requires OpenLayers/Control.js
 * @requires OpenLayers/Util/hideFromOldIE.js
 */
OpenLayers.Control.FullScreen =
    OpenLayers.Class( OpenLayers.Control, {

    is_full_screen_on: false,

    // remember that suffixes are added to this class: ItemActive or ItemInactive
    btnClass: 'olControlButtonFullScreen',

    // css classess of control panels to be hidden/show on toggling fullscreen
    classElemToHide:  ['.selZoom'],

    elemsToHideSelector: '',

    btn: null,

    title: "FullScreen",

    initialize: function(options) {
        var that = this;
        OpenLayers.Control.prototype.initialize.apply(this,[options]);
        $(document).bind("keydown", function (e) {
            var code = e.keyCode || e.which;
            if (code === 122) { //F11
                that.is_full_screen_on = ! that.is_full_screen_on;
                that.toggleControls();
            } else if (code === 27) {// Escape
                // escape button can be used for leaving FS enabled by our button
                if (that.is_full_screen_on === true) {
                    that.is_full_screen_on = false;
                    that.toggleControls();
                } // endif
            } // endif
        }); // bind

        //listen to fullscreen change and if exiting fullscreen and property is_full_screen_on is still true
        //e.g. when clicking esc button -> make sure to set correct value and show controls
        $(document).on("fullscreenchange mozfullscreenchange webkitfullscreenchange", function(){
            if(that.fullScreenStatus === false && that.is_full_screen_on === true) {
                that.is_full_screen_on = false;
                this.showControls();
            }
        });

        this.elemsToHideSelector = this.classElemToHide.join(',');
        this.type = OpenLayers.Control.TYPE_BUTTON;
    }, // initialize
    fullScreenStatus: function() {
        return document.fullscreen ||
            document.mozFullScreen ||
            document.webkitIsFullScreen ||
            false;
    },
    draw: function () {
        var position,
            size,
            imgLocation,
            btn,
            className = "fullscreen-button";

        btn = OpenLayers.Util.createButton(
                'OpenLayers_Control_FullScreen' + this.map.id,
                null,
                null,
                null,
                "static");

        OpenLayers.Event.observe(btn, 'click',
            OpenLayers.Function.bind(this.toggleFullScreen, this)
        );

        btn.title = this.title;
        btn.className = btn.className === "" ? className : btn.className + " " + className;
        btn.innerHTML = OpenLayers.Util.hideFromOldIE('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" preserveAspectRatio="xMidYMid meet" viewBox="0 0 20 20" class="icon fullscreen"><path d="M14.949,3.661l1.429,1.428l1.539-1.54l1.612,1.612V0.485h-4.676l1.636,1.636L14.949,3.661z M17.894,16.6l-1.54-1.539l-1.428,1.428l1.539,1.54l-1.611,1.612h4.676v-4.676L17.894,16.6z M4.895,16.465l-1.428-1.428l-1.54,1.539l-1.612-1.611v4.676h4.675l-1.636-1.637L4.895,16.465z M3.491,5.064l1.428-1.428l-1.54-1.539l1.612-1.612H0.315v4.675l1.636-1.635L3.491,5.064zM15.769,12.033V8.199c0-1.587-1.288-2.875-2.875-2.875H6.907c-1.588,0-2.875,1.287-2.875,2.875v3.834c0,1.588,1.287,2.875,2.875,2.875h5.987C14.48,14.908,15.769,13.621,15.769,12.033z" /></svg><svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewBox="0 0 20 20" preserveAspectRatio="xMidYMid meet" class="icon windowed"><path d="M19.877,1.61l-1.523-1.533l-1.642,1.653L14.992,0v5.021h4.987l-1.745-1.756L19.877,1.61z M16.737,18.253l1.643,1.653l1.522-1.533l-1.642-1.653l1.719-1.73h-4.987v5.02L16.737,18.253z M0.103,18.399l1.523,1.533l1.642-1.654l1.719,1.731v-5.021H0l1.745,1.756L0.103,18.399z M1.6,0.104L0.077,1.637L1.719,3.29L0,5.021h4.987V0L3.243,1.756L1.6,0.104z M15.759,12.038V8.204c0-1.587-1.288-2.875-2.875-2.875H6.897c-1.588,0-2.875,1.287-2.875,2.875v3.834c0,1.588,1.287,2.875,2.875,2.875h5.987C14.471,14.913,15.759,13.626,15.759,12.038z" /></svg>');

        this.btn = btn;

        if (this.div == null) {
            this.div = btn;
        } else {
            this.div.appendChild(btn);
        }

        return this.div;
    }, // draw

    hideControls: function () {
        $(this.elemsToHideSelector).not("." + this.panelClass).hide();
        OpenLayers.Element.addClass(document.body, "fullscreen");
        OpenLayers.Element.addClass(this.btn, "fullscreen-active");
    }, //hideControls

    showControls: function () {
        $(this.elemsToHideSelector).show();
        OpenLayers.Element.removeClass(document.body, "fullscreen");
        OpenLayers.Element.removeClass(this.btn, "fullscreen-active");
    }, // showControls

    enable: function () {
        var el = document.documentElement,
            rfs = // for newer Webkit and Firefox
                   el.requestFullscreen
                || el.webkitRequestFullScreen
                || el.mozRequestFullScreen
                || el.msRequestFullScreen;
        if (rfs !== "undefined" && rfs) {
            rfs.call(el);
        } else if (typeof window.ActiveXObject !== "undefined") {
            // for Internet Explorer
            try {
                var wscript = new ActiveXObject("WScript.Shell");
                if (wscript !== null) {
                    wscript.SendKeys("{F11}");
                }
            } catch (e) {
                // proceed with minimized control panels. Full screen activation prohibited by browser security settings.
            }
        } // endif
    }, // enable

    disable: function () {
        // cancel method belongs to document directly
        var cfs = // for newer Webkit and Firefox
                   document.cancelFullScreen
                || document.webkitCancelFullScreen
                || document.mozCancelFullScreen
                || document.exitFullscreen
                || document.msCancelFullScreen;
        if (cfs !== "undefined" && cfs) {
            cfs.call(document);
        } else if (typeof window.ActiveXObject !== "undefined") {
            // for Internet Explorer
            try {
                var wscript = new ActiveXObject("WScript.Shell");
                if (wscript !== null) {
                    wscript.SendKeys("{F11}");
                }
            } catch (e) {
            }
        } // endif
    }, // disable

    toggleFullScreen: function () {
        if (this.is_full_screen_on === true ) {
            this.disable();
            this.showControls();
            this.is_full_screen_on = false;
        } else {
            this.enable();
            this.hideControls();
            this.is_full_screen_on = true;
        } // endif
    }, // toggleFullScreen

    toggleControls: function () {
        if (this.is_full_screen_on === true ) {
            this.hideControls();
            //this.hideControls();
        } else {
            this.showControls();
            //this.showControls();
        } // endif
    },//togglecontrols

    CLASS_NAME: "OpenLayers.Control.FullScreen"
}); // OpenLayers.Control.FullScreen
<commit_msg>when exiting fullscreen with esc btn it should now show the side bar - fix 2<commit_after>/**
 * @requires OpenLayers/Control.js
 * @requires OpenLayers/Util/hideFromOldIE.js
 */
OpenLayers.Control.FullScreen =
    OpenLayers.Class( OpenLayers.Control, {

    is_full_screen_on: false,

    // remember that suffixes are added to this class: ItemActive or ItemInactive
    btnClass: 'olControlButtonFullScreen',

    // css classess of control panels to be hidden/show on toggling fullscreen
    classElemToHide:  ['.selZoom'],

    elemsToHideSelector: '',

    btn: null,

    title: "FullScreen",

    initialize: function(options) {
        var that = this;
        OpenLayers.Control.prototype.initialize.apply(this,[options]);
        $(document).bind("keydown", function (e) {
            var code = e.keyCode || e.which;
            if (code === 122) { //F11
                that.is_full_screen_on = ! that.is_full_screen_on;
                that.toggleControls();
            } else if (code === 27) {// Escape
                // escape button can be used for leaving FS enabled by our button
                if (that.is_full_screen_on === true) {
                    that.is_full_screen_on = false;
                    that.toggleControls();
                } // endif
            } // endif
        }); // bind
;
        //listen to fullscreen change and if exiting fullscreen and property is_full_screen_on is still true
        //e.g. when clicking esc button -> make sure to set correct value and show controls
        $(document).on("fullscreenchange mozfullscreenchange webkitfullscreenchange", function() {
            if(that.fullScreenStatus() === false && that.is_full_screen_on === true) {
                that.is_full_screen_on = false;
                that.showControls();
            }
        });

        this.elemsToHideSelector = this.classElemToHide.join(',');
        this.type = OpenLayers.Control.TYPE_BUTTON;
    }, // initialize
    fullScreenStatus: function() {
        if (document.fullscreenElement || document.webkitIsFullScreen || document.mozFullScreenElement) {
            return true;
        } else {
            return false;
        }
    },
    draw: function () {
        var position,
            size,
            imgLocation,
            btn,
            className = "fullscreen-button";

        btn = OpenLayers.Util.createButton(
                'OpenLayers_Control_FullScreen' + this.map.id,
                null,
                null,
                null,
                "static");

        OpenLayers.Event.observe(btn, 'click',
            OpenLayers.Function.bind(this.toggleFullScreen, this)
        );

        btn.title = this.title;
        btn.className = btn.className === "" ? className : btn.className + " " + className;
        btn.innerHTML = OpenLayers.Util.hideFromOldIE('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" preserveAspectRatio="xMidYMid meet" viewBox="0 0 20 20" class="icon fullscreen"><path d="M14.949,3.661l1.429,1.428l1.539-1.54l1.612,1.612V0.485h-4.676l1.636,1.636L14.949,3.661z M17.894,16.6l-1.54-1.539l-1.428,1.428l1.539,1.54l-1.611,1.612h4.676v-4.676L17.894,16.6z M4.895,16.465l-1.428-1.428l-1.54,1.539l-1.612-1.611v4.676h4.675l-1.636-1.637L4.895,16.465z M3.491,5.064l1.428-1.428l-1.54-1.539l1.612-1.612H0.315v4.675l1.636-1.635L3.491,5.064zM15.769,12.033V8.199c0-1.587-1.288-2.875-2.875-2.875H6.907c-1.588,0-2.875,1.287-2.875,2.875v3.834c0,1.588,1.287,2.875,2.875,2.875h5.987C14.48,14.908,15.769,13.621,15.769,12.033z" /></svg><svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewBox="0 0 20 20" preserveAspectRatio="xMidYMid meet" class="icon windowed"><path d="M19.877,1.61l-1.523-1.533l-1.642,1.653L14.992,0v5.021h4.987l-1.745-1.756L19.877,1.61z M16.737,18.253l1.643,1.653l1.522-1.533l-1.642-1.653l1.719-1.73h-4.987v5.02L16.737,18.253z M0.103,18.399l1.523,1.533l1.642-1.654l1.719,1.731v-5.021H0l1.745,1.756L0.103,18.399z M1.6,0.104L0.077,1.637L1.719,3.29L0,5.021h4.987V0L3.243,1.756L1.6,0.104z M15.759,12.038V8.204c0-1.587-1.288-2.875-2.875-2.875H6.897c-1.588,0-2.875,1.287-2.875,2.875v3.834c0,1.588,1.287,2.875,2.875,2.875h5.987C14.471,14.913,15.759,13.626,15.759,12.038z" /></svg>');

        this.btn = btn;

        if (this.div == null) {
            this.div = btn;
        } else {
            this.div.appendChild(btn);
        }

        return this.div;
    }, // draw

    hideControls: function () {
        $(this.elemsToHideSelector).not("." + this.panelClass).hide();
        OpenLayers.Element.addClass(document.body, "fullscreen");
        OpenLayers.Element.addClass(this.btn, "fullscreen-active");
    }, //hideControls

    showControls: function () {
        $(this.elemsToHideSelector).show();
        OpenLayers.Element.removeClass(document.body, "fullscreen");
        OpenLayers.Element.removeClass(this.btn, "fullscreen-active");
    }, // showControls

    enable: function () {
        var el = document.documentElement,
            rfs = // for newer Webkit and Firefox
                   el.requestFullscreen
                || el.webkitRequestFullScreen
                || el.mozRequestFullScreen
                || el.msRequestFullScreen;
        if (rfs !== "undefined" && rfs) {
            rfs.call(el);
        } else if (typeof window.ActiveXObject !== "undefined") {
            // for Internet Explorer
            try {
                var wscript = new ActiveXObject("WScript.Shell");
                if (wscript !== null) {
                    wscript.SendKeys("{F11}");
                }
            } catch (e) {
                // proceed with minimized control panels. Full screen activation prohibited by browser security settings.
            }
        } // endif
    }, // enable

    disable: function () {
        // cancel method belongs to document directly
        var cfs = // for newer Webkit and Firefox
                   document.cancelFullScreen
                || document.webkitCancelFullScreen
                || document.mozCancelFullScreen
                || document.exitFullscreen
                || document.msCancelFullScreen;
        if (cfs !== "undefined" && cfs) {
            cfs.call(document);
        } else if (typeof window.ActiveXObject !== "undefined") {
            // for Internet Explorer
            try {
                var wscript = new ActiveXObject("WScript.Shell");
                if (wscript !== null) {
                    wscript.SendKeys("{F11}");
                }
            } catch (e) {
            }
        } // endif
    }, // disable

    toggleFullScreen: function () {
        if (this.is_full_screen_on === true ) {
            this.disable();
            this.showControls();
            this.is_full_screen_on = false;
        } else {
            this.enable();
            this.hideControls();
            this.is_full_screen_on = true;
        } // endif
    }, // toggleFullScreen

    toggleControls: function () {
        if (this.is_full_screen_on === true ) {
            this.hideControls();
            //this.hideControls();
        } else {
            this.showControls();
            //this.showControls();
        } // endif
    },//togglecontrols

    CLASS_NAME: "OpenLayers.Control.FullScreen"
}); // OpenLayers.Control.FullScreen
<|endoftext|>


<commit_before>(function() {
  var extractProps = function(start) {
    var props = {}, a, keys;
    for (var i = start, al = arguments.length; i < al; ++i) {
      a = arguments[i];
      if( (typeof a === "object") && (a !== null) )
        keys = Object.keys(a);
        for (var j = 0, kl = keys.length; j < kl; ++j) props[keys[j]] = true;
      {
    }
    return props;
  };
  var copyEnabled = function(agent) {
    return agent != null && typeof agent === "object" && typeof agent.constructor === "function" && !agent.nodeType;
  };
  var mergeObjects = function(deep, newonly, i, objects) {
    if (!deep && !newonly && typeof Object.assign === "function") {
      for (;objects[i] == null; ++i) ;
      return Object.assign.apply(Object, i == 0 ? objects : Array.prototype.slice.call(objects, i));
    }
    var obj = objects[i], ol = objects.length, merge = function(target, src) {
      if (src == null) return; else if (target == null) {
        target = src;
        return;
      }
      for (var p in src) {
        if (target[p] === src[p]) continue;
        if (target[p] !== undefined && newonly) continue; else if (!deep || typeof src[p] !== "object" || !src.hasOwnProperty(p) || !copyEnabled(src[p])) target[p] = src[p]; else try {
          if (target[p] == null) target[p] = asSys.mimic(src[p]);
          merge(target[p], src[p]);
        } catch (e) {
          target[p] = src[p];
        }
      }
    };
    while (++i < ol) merge(obj, objects[i]);
    return obj;
  };
  var twinScan = function(arr, start, callback) {
    var ai, j;
    for (var i = start, al = arr.length; i < al; ++i) {
      ai = arr[i];
      for (j = i + 1; j < al; ++j) {
        if (callback(ai, arr[j]) === false) return false;
      }
    }
    return true;
  };
  var asSys = function() {
    var skillmap = [], expected = null, missing, skills = Array.prototype.slice.call(arguments, 0), A = function() {
      var agent = this, args = arguments;
      if (!agent.__initializing) {
        agent.__initializing = true;
        asSys.each(agent.__skills, function(s) {
          s.apply(agent, args);
        });
        delete agent.__initializing;
      }
    };
    for (var i = 0, a; i < skills.length; ++i) {
      a = skills[i];
      if (typeof a === "function" && a.prototype !== undefined) {
        if (skillmap.indexOf(a) > -1) continue;
        if (a.prototype.__depends != null) {
          missing = [ i, 0 ];
          for (var s, j = 0, el = a.prototype.__depends.length; j < el; ++j) {
            s = a.prototype.__depends[j];
            if (skills.indexOf(s) == -1) missing.push(s);
          }
          if (missing.length > 2) {
            Array.prototype.splice.apply(skills, missing);
            --i;
            continue;
          }
        }
        if (a.prototype.__expects != null) {
          if (expected == null) expected = {};
          for (var j = 0, el = a.prototype.__expects.length; j < el; ++j) expected[a.prototype.__expects[j]] = true;
        }
        skillmap.push(a);
        if (A.prototype === undefined) A.prototype = Object.create(a.prototype); else mergeObjects(true, false, 0, [ A.prototype, a.prototype ]);
        if (a.prototype.__skills !== undefined) {
          for (var j = 0, ssl = a.prototype.__skills.length, ss; j < ssl; ++j) {
            ss = a.prototype.__skills[j];
            if (skillmap.indexOf(ss) == -1) skillmap.push(ss);
          }
        }
      }
    }
    asSys.each(expected, function(v, m) {
      if (A.prototype[m] == null) throw {
        name: "Unmatched skill expectation",
        message: "The expected method [" + m + "] was not found among provided skills.",
        method: m
      };
    });
    Object.defineProperties(A.prototype, {
      __skills: {
        enumerable: false,
        writable: false,
        value: skillmap
      }
    });
    return A;
  };
  asSys.version = "0.10.0";
  asSys.equal = function(deepCompare) {
    var deep = deepCompare, start = 0, match = function(a, b, dig) {
      if (typeof a !== "object" || typeof b !== "object") return a === b; else if (dig !== false) {
        for (var p in extractProps(0, a, b)) {
          if (!match(a[p], b[p], deep)) return false;
        }
        return true;
      }
    };
    if (typeof deep !== "boolean") deep = false; else start = 1;
    return twinScan(arguments, start, match);
  };
  asSys.similar = function(deepCompare) {
    var deep = deepCompare, start = 0;
    match = function(a, b, dig) {
      if (a instanceof RegExp) return typeof b === "string" && b.match(a) != null; else if (b instanceof RegExp) return typeof a === "string" && a.match(b) != null; else if (typeof a !== "object" || typeof b !== "object") return a == b; else if (dig !== false) {
        for (var p in a) {
          if (b[p] !== undefined && !match(a[p], b[p], deep)) return false;
        }
        return true;
      }
    };
    if (typeof deep !== "boolean") deep = false; else start = 1;
    return twinScan(arguments, start, match);
  };
  asSys.common = function(equal) {
    var eq = equal, idx = 0, res = null, argl = arguments.length, extract = function(a, b) {
      if (Array.isArray(a) && Array.isArray(b)) {
        if (res == null) res = [];
        for (var i = 0, al = a.length; i < al; ++i) {
          if (b.indexOf(a[i]) > -1) res.push(a[i]);
        }
      } else {
        if (res == null) res = {};
        for (var p in a) {
          if (b.hasOwnProperty(p) && (!eq || a[p] == b[p])) res[p] = a[p];
        }
      }
    };
    if (typeof equal !== "boolean") eq = false; else idx = 1;
    while (++idx < argl) extract(res == null ? arguments[idx - 1] : res, arguments[idx]);
    return res;
  };
  asSys.extend = function(deep) {
    var d = deep, start = 0;
    if (typeof d !== "boolean") d = false; else start = 1;
    return mergeObjects(d, false, start, arguments);
  };
  asSys.mixin = function(deep) {
    var d = deep, start = 0;
    if (typeof d !== "boolean") d = false; else start = 1;
    return mergeObjects(d, true, start, arguments);
  };
  asSys.filter = function(agent, selector) {
    if (typeof agent.filter === "function") return agent.filter(selector);
    var res = asSys.mimic(agent), p, keys = Object.keys(agent);
    for (var i = 0, kl = keys.length; i < kl; ++i) {
      p = keys[i];
      if (selector(agent[p], p, agent)) res[p] = agent[p];
    }
    return res;
  };
  asSys.each = function(agent, actor) {
    if (agent == null) ; else if (typeof agent.forEach === "function") agent.forEach(actor); else if (typeof agent !== "object") {
      actor(agent);
    } else {
      var k = Object.keys(agent), p;
      for (var i = 0, kl = k.length; i < kl; ++i) {
        p = k[i];
        actor(agent[p], p, agent);
      }
    }
  };
  asSys.weight = function(agent) {
    if (typeof agent !== "object") return 1; else if (agent.hasOwnProperty("length") && typeof agent.length == "number") return agent.length; else return Object.keys(agent).length;
  };
  asSys.name = function(fn) {
    if (typeof fn !== "function") return skill.toString(); else if (fn.name !== undefined) return fn.name; else {
      var s = fn.toString().match(/function ([^\(]+)/);
      return s != null ? s[1] : "";
    }
  };
  asSys.mimic = function(agent) {
    if (copyEnabled(agent)) {
      var o = Object.create(Object.getPrototypeOf(agent));
      try {
        return agent.constructor.apply(o, Array.prototype.slice(arguments, 1)) || o;
      } catch (e) {}
    }
  };
  asSys.path = function(agent, path, value) {
    if (path == null) return;
    if (!Array.isArray(path)) {
      try {
        if (value === undefined) eval("value = agent." + path); else eval("agent." + path + " = value");
        return value;
      } catch (e) {
        path = path.split(".");
      }
    }
    for (var i = 0, pl = path.length; i < pl - 1; ++i) agent = agent[path[i]] = agent[path[i]] || {};
    if (value !== undefined) agent[path[i]] = value; else value = agent[path[i]];
    return value;
  };
  asSys.act = function(agent, activity) {
    if (agent != null && typeof activity === "function") {
      return activity.apply(agent, Array.prototype.slice.call(arguments, 2));
    }
  };
  asSys.broadcast = function(agent, activity) {
    var args = Array.prototype.slice.call(arguments, 2);
    asSys.each(agent.__skills, function(s) {
      if (typeof s.prototype[activity] === "function") s.prototype[activity].apply(agent, args);
    });
    return agent;
  };
  asSys.pass = function(agent, skill, activity) {
    var i = agent.__skills && agent.__skills.indexOf(skill), s;
    if (i > -1) {
      while (--i >= 0) {
        s = agent.__skills[i];
        if (typeof s.prototype[activity] === "function") return s.prototype[activity].apply(agent, Array.prototype.slice.call(arguments, 3));
      }
    }
  };
  asSys.can = function(agent, activity) {
    return typeof agent === "object" && agent[activity] != null && typeof agent[activity] === "function";
  };
  asSys.aware = function(agent, prop) {
    return typeof agent === "object" && agent[prop] !== undefined;
  };
  asSys.capable = function(agent, allskills) {
    var all = allskills, s, w, proto = Object.getPrototypeOf(agent), i = 1;
    if (typeof all !== "boolean") all = true; else i = 2;
    for (var cnt = 0, start = i, al = arguments.length; i < al; ++i) {
      s = arguments[i];
      if (agent instanceof s) ++cnt; else {
        w = asSys.weight(s.prototype);
        if (w > 0 && asSys.weight(asSys.common(true, proto, s.prototype)) == w) ++cnt;
      }
    }
    return cnt > 0 && (all ? arguments.length - start == cnt : true);
  };
  asSys.group = function(pool, full, selector) {
    if (typeof full !== "boolean") {
      selector = full;
      full = false;
    }
    var res = this.mimic(pool), skills = {}, e;
    for (var k in pool) {
      var e = pool[k];
      if (!selector.call(e, e, k, pool)) continue;
      if (full) mergeObjects(false, false, 0, [ skills, Object.getPrototypeOf(e) ]);
      res.push(e);
    }
    if (full) {
      var sks = Object.keys(skills), p, props = {};
      for (var i = 0, sl = sks.length; i < sl; ++i) {
        p = sks[i];
        props[p] = {
          enumerable: false,
          writable: false,
          value: typeof skills[p] !== "function" ? skills[p] : function(key) {
            return function() {
              var r = undefined;
              for (var i in this) {
                var o = this[i];
                if (typeof o[key] === "function") r = o[key].apply(o, arguments);
              }
              return r;
            };
          }(p)
        };
      }
      Object.defineProperties(res, props);
    }
    return res;
  };
  if (typeof module === "object" && module && typeof module.exports === "object") module.exports = asSys; else if (typeof define === "function" && define.amd) {
    define(asSys);
    this.asSys = asSys;
  } else {
    this.asSys = this.a$ = asSys;
  }
})();<commit_msg>validate the arguments of extractProps method.<commit_after>(function() {
  var extractProps = function(start) {
    var props = {}, a, keys;
    for (var i = start, al = arguments.length; i < al; ++i) {
      a = arguments[i];
      if( (typeof a === "object") && (q !== null) ){
        keys = Object.keys(a);
        for (var j = 0, kl = keys.length; j < kl; ++j) props[keys[j]] = true;
      }
    }
    return props;
  };
  var copyEnabled = function(agent) {
    return agent != null && typeof agent === "object" && typeof agent.constructor === "function" && !agent.nodeType;
  };
  var mergeObjects = function(deep, newonly, i, objects) {
    if (!deep && !newonly && typeof Object.assign === "function") {
      for (;objects[i] == null; ++i) ;
      return Object.assign.apply(Object, i == 0 ? objects : Array.prototype.slice.call(objects, i));
    }
    var obj = objects[i], ol = objects.length, merge = function(target, src) {
      if (src == null) return; else if (target == null) {
        target = src;
        return;
      }
      for (var p in src) {
        if (target[p] === src[p]) continue;
        if (target[p] !== undefined && newonly) continue; else if (!deep || typeof src[p] !== "object" || !src.hasOwnProperty(p) || !copyEnabled(src[p])) target[p] = src[p]; else try {
          if (target[p] == null) target[p] = asSys.mimic(src[p]);
          merge(target[p], src[p]);
        } catch (e) {
          target[p] = src[p];
        }
      }
    };
    while (++i < ol) merge(obj, objects[i]);
    return obj;
  };
  var twinScan = function(arr, start, callback) {
    var ai, j;
    for (var i = start, al = arr.length; i < al; ++i) {
      ai = arr[i];
      for (j = i + 1; j < al; ++j) {
        if (callback(ai, arr[j]) === false) return false;
      }
    }
    return true;
  };
  var asSys = function() {
    var skillmap = [], expected = null, missing, skills = Array.prototype.slice.call(arguments, 0), A = function() {
      var agent = this, args = arguments;
      if (!agent.__initializing) {
        agent.__initializing = true;
        asSys.each(agent.__skills, function(s) {
          s.apply(agent, args);
        });
        delete agent.__initializing;
      }
    };
    for (var i = 0, a; i < skills.length; ++i) {
      a = skills[i];
      if (typeof a === "function" && a.prototype !== undefined) {
        if (skillmap.indexOf(a) > -1) continue;
        if (a.prototype.__depends != null) {
          missing = [ i, 0 ];
          for (var s, j = 0, el = a.prototype.__depends.length; j < el; ++j) {
            s = a.prototype.__depends[j];
            if (skills.indexOf(s) == -1) missing.push(s);
          }
          if (missing.length > 2) {
            Array.prototype.splice.apply(skills, missing);
            --i;
            continue;
          }
        }
        if (a.prototype.__expects != null) {
          if (expected == null) expected = {};
          for (var j = 0, el = a.prototype.__expects.length; j < el; ++j) expected[a.prototype.__expects[j]] = true;
        }
        skillmap.push(a);
        if (A.prototype === undefined) A.prototype = Object.create(a.prototype); else mergeObjects(true, false, 0, [ A.prototype, a.prototype ]);
        if (a.prototype.__skills !== undefined) {
          for (var j = 0, ssl = a.prototype.__skills.length, ss; j < ssl; ++j) {
            ss = a.prototype.__skills[j];
            if (skillmap.indexOf(ss) == -1) skillmap.push(ss);
          }
        }
      }
    }
    asSys.each(expected, function(v, m) {
      if (A.prototype[m] == null) throw {
        name: "Unmatched skill expectation",
        message: "The expected method [" + m + "] was not found among provided skills.",
        method: m
      };
    });
    Object.defineProperties(A.prototype, {
      __skills: {
        enumerable: false,
        writable: false,
        value: skillmap
      }
    });
    return A;
  };
  asSys.version = "0.10.0";
  asSys.equal = function(deepCompare) {
    var deep = deepCompare, start = 0, match = function(a, b, dig) {
      if (typeof a !== "object" || typeof b !== "object") return a === b; else if (dig !== false) {
        for (var p in extractProps(0, a, b)) {
          if (!match(a[p], b[p], deep)) return false;
        }
        return true;
      }
    };
    if (typeof deep !== "boolean") deep = false; else start = 1;
    return twinScan(arguments, start, match);
  };
  asSys.similar = function(deepCompare) {
    var deep = deepCompare, start = 0;
    match = function(a, b, dig) {
      if (a instanceof RegExp) return typeof b === "string" && b.match(a) != null; else if (b instanceof RegExp) return typeof a === "string" && a.match(b) != null; else if (typeof a !== "object" || typeof b !== "object") return a == b; else if (dig !== false) {
        for (var p in a) {
          if (b[p] !== undefined && !match(a[p], b[p], deep)) return false;
        }
        return true;
      }
    };
    if (typeof deep !== "boolean") deep = false; else start = 1;
    return twinScan(arguments, start, match);
  };
  asSys.common = function(equal) {
    var eq = equal, idx = 0, res = null, argl = arguments.length, extract = function(a, b) {
      if (Array.isArray(a) && Array.isArray(b)) {
        if (res == null) res = [];
        for (var i = 0, al = a.length; i < al; ++i) {
          if (b.indexOf(a[i]) > -1) res.push(a[i]);
        }
      } else {
        if (res == null) res = {};
        for (var p in a) {
          if (b.hasOwnProperty(p) && (!eq || a[p] == b[p])) res[p] = a[p];
        }
      }
    };
    if (typeof equal !== "boolean") eq = false; else idx = 1;
    while (++idx < argl) extract(res == null ? arguments[idx - 1] : res, arguments[idx]);
    return res;
  };
  asSys.extend = function(deep) {
    var d = deep, start = 0;
    if (typeof d !== "boolean") d = false; else start = 1;
    return mergeObjects(d, false, start, arguments);
  };
  asSys.mixin = function(deep) {
    var d = deep, start = 0;
    if (typeof d !== "boolean") d = false; else start = 1;
    return mergeObjects(d, true, start, arguments);
  };
  asSys.filter = function(agent, selector) {
    if (typeof agent.filter === "function") return agent.filter(selector);
    var res = asSys.mimic(agent), p, keys = Object.keys(agent);
    for (var i = 0, kl = keys.length; i < kl; ++i) {
      p = keys[i];
      if (selector(agent[p], p, agent)) res[p] = agent[p];
    }
    return res;
  };
  asSys.each = function(agent, actor) {
    if (agent == null) ; else if (typeof agent.forEach === "function") agent.forEach(actor); else if (typeof agent !== "object") {
      actor(agent);
    } else {
      var k = Object.keys(agent), p;
      for (var i = 0, kl = k.length; i < kl; ++i) {
        p = k[i];
        actor(agent[p], p, agent);
      }
    }
  };
  asSys.weight = function(agent) {
    if (typeof agent !== "object") return 1; else if (agent.hasOwnProperty("length") && typeof agent.length == "number") return agent.length; else return Object.keys(agent).length;
  };
  asSys.name = function(fn) {
    if (typeof fn !== "function") return skill.toString(); else if (fn.name !== undefined) return fn.name; else {
      var s = fn.toString().match(/function ([^\(]+)/);
      return s != null ? s[1] : "";
    }
  };
  asSys.mimic = function(agent) {
    if (copyEnabled(agent)) {
      var o = Object.create(Object.getPrototypeOf(agent));
      try {
        return agent.constructor.apply(o, Array.prototype.slice(arguments, 1)) || o;
      } catch (e) {}
    }
  };
  asSys.path = function(agent, path, value) {
    if (path == null) return;
    if (!Array.isArray(path)) {
      try {
        if (value === undefined) eval("value = agent." + path); else eval("agent." + path + " = value");
        return value;
      } catch (e) {
        path = path.split(".");
      }
    }
    for (var i = 0, pl = path.length; i < pl - 1; ++i) agent = agent[path[i]] = agent[path[i]] || {};
    if (value !== undefined) agent[path[i]] = value; else value = agent[path[i]];
    return value;
  };
  asSys.act = function(agent, activity) {
    if (agent != null && typeof activity === "function") {
      return activity.apply(agent, Array.prototype.slice.call(arguments, 2));
    }
  };
  asSys.broadcast = function(agent, activity) {
    var args = Array.prototype.slice.call(arguments, 2);
    asSys.each(agent.__skills, function(s) {
      if (typeof s.prototype[activity] === "function") s.prototype[activity].apply(agent, args);
    });
    return agent;
  };
  asSys.pass = function(agent, skill, activity) {
    var i = agent.__skills && agent.__skills.indexOf(skill), s;
    if (i > -1) {
      while (--i >= 0) {
        s = agent.__skills[i];
        if (typeof s.prototype[activity] === "function") return s.prototype[activity].apply(agent, Array.prototype.slice.call(arguments, 3));
      }
    }
  };
  asSys.can = function(agent, activity) {
    return typeof agent === "object" && agent[activity] != null && typeof agent[activity] === "function";
  };
  asSys.aware = function(agent, prop) {
    return typeof agent === "object" && agent[prop] !== undefined;
  };
  asSys.capable = function(agent, allskills) {
    var all = allskills, s, w, proto = Object.getPrototypeOf(agent), i = 1;
    if (typeof all !== "boolean") all = true; else i = 2;
    for (var cnt = 0, start = i, al = arguments.length; i < al; ++i) {
      s = arguments[i];
      if (agent instanceof s) ++cnt; else {
        w = asSys.weight(s.prototype);
        if (w > 0 && asSys.weight(asSys.common(true, proto, s.prototype)) == w) ++cnt;
      }
    }
    return cnt > 0 && (all ? arguments.length - start == cnt : true);
  };
  asSys.group = function(pool, full, selector) {
    if (typeof full !== "boolean") {
      selector = full;
      full = false;
    }
    var res = this.mimic(pool), skills = {}, e;
    for (var k in pool) {
      var e = pool[k];
      if (!selector.call(e, e, k, pool)) continue;
      if (full) mergeObjects(false, false, 0, [ skills, Object.getPrototypeOf(e) ]);
      res.push(e);
    }
    if (full) {
      var sks = Object.keys(skills), p, props = {};
      for (var i = 0, sl = sks.length; i < sl; ++i) {
        p = sks[i];
        props[p] = {
          enumerable: false,
          writable: false,
          value: typeof skills[p] !== "function" ? skills[p] : function(key) {
            return function() {
              var r = undefined;
              for (var i in this) {
                var o = this[i];
                if (typeof o[key] === "function") r = o[key].apply(o, arguments);
              }
              return r;
            };
          }(p)
        };
      }
      Object.defineProperties(res, props);
    }
    return res;
  };
  if (typeof module === "object" && module && typeof module.exports === "object") module.exports = asSys; else if (typeof define === "function" && define.amd) {
    define(asSys);
    this.asSys = asSys;
  } else {
    this.asSys = this.a$ = asSys;
  }
})();<|endoftext|>