view js/clustergrammerIPG.js @ 0:fee56ee2f7ac draft

"planemo upload for repository https://github.com/ImmPortDB/immport-galaxy-tools/tree/master/flowtools/clustergrammer_flow commit b11dfcf10d287c1da91ffb1d5d0148c7f8f61356"
author azomics
date Fri, 31 Jul 2020 19:06:45 -0400
parents
children
line wrap: on
line source

var Clustergrammer =
/******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};

/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {

/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId])
/******/ 			return installedModules[moduleId].exports;

/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			exports: {},
/******/ 			id: moduleId,
/******/ 			loaded: false
/******/ 		};

/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

/******/ 		// Flag the module as loaded
/******/ 		module.loaded = true;

/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}


/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;

/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;

/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";

/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {

	var make_config = __webpack_require__(1);
	var make_params = __webpack_require__(9);
	var make_viz = __webpack_require__(37);
	var resize_viz = __webpack_require__(124);
	var play_demo = __webpack_require__(165);
	var ini_demo = __webpack_require__(205);
	var filter_viz_using_nodes = __webpack_require__(208);
	var filter_viz_using_names = __webpack_require__(209);
	var update_cats = __webpack_require__(210);
	var reset_cats = __webpack_require__(211);
	var two_translate_zoom = __webpack_require__(116);
	var external_update_view = __webpack_require__(213);
	var save_matrix = __webpack_require__(216);
	var brush_crop_matrix = __webpack_require__(220);
	var run_zoom = __webpack_require__(125);
	var d3_tip_custom = __webpack_require__(48);
	var all_reorder = __webpack_require__(115);
	var make_matrix_string = __webpack_require__(218);

	// moved d3.slider to src
	d3.slider = __webpack_require__(222);

	/* eslint-disable */

	var awesomplete = __webpack_require__(224);
	// getting css from src
	__webpack_require__(225);
	__webpack_require__(229);

	/* clustergrammer v1.19.2
	 * Nicolas Fernandez, Ma'ayan Lab, Icahn School of Medicine at Mount Sinai
	 * (c) 2017
	 */
	function Clustergrammer(args) {

	  /* Main program
	   * ----------------------------------------------------------------------- */
	  // consume and validate user input
	  // build giant config object
	  // visualize based on config object
	  // handle user events

	  // consume and validate user arguments, produce configuration object
	  var config = make_config(args);

	  var cgm = {};

	  // make visualization parameters using configuration object
	  cgm.params = make_params(config);
	  cgm.config = config;

	  // set up zoom
	  cgm.params.zoom_behavior = d3.behavior.zoom().scaleExtent([1, cgm.params.viz.square_zoom * cgm.params.viz.zoom_ratio.x]).on('zoom', function () {
	    run_zoom(cgm);
	  });

	  cgm.params.zoom_behavior.translate([cgm.params.viz.clust.margin.left, cgm.params.viz.clust.margin.top]);

	  if (cgm.params.use_sidebar) {
	    var make_sidebar = __webpack_require__(231);
	    make_sidebar(cgm);
	  }

	  // make visualization using parameters
	  make_viz(cgm);

	  function external_resize() {

	    d3.select(cgm.params.viz.viz_svg).style('opacity', 0.5);

	    var wait_time = 500;
	    if (this.params.viz.run_trans === true) {
	      wait_time = 2500;
	    }

	    setTimeout(resize_fun, wait_time, this);
	  }

	  function resize_fun(cgm) {
	    resize_viz(cgm);
	  }

	  function run_update_cats(cat_data) {
	    update_cats(this, cat_data);
	  }

	  function zoom_api(pan_dx, pan_dy, fin_zoom) {
	    two_translate_zoom(this, pan_dx, pan_dy, fin_zoom);
	  }

	  function expose_d3_tip_custom() {
	    // this allows external modules to have access to d3_tip
	    return d3_tip_custom;
	  }

	  function api_reorder(inst_rc, inst_order) {
	    if (inst_order === 'sum') {
	      inst_order = 'rank';
	    }
	    if (inst_order === 'var') {
	      inst_order = 'rankvar';
	    }
	    all_reorder(this, inst_order, inst_rc);
	  }

	  function export_matrix_string() {
	    return make_matrix_string(this.params);
	  }

	  // add more API endpoints
	  cgm.update_view = external_update_view;
	  cgm.resize_viz = external_resize;
	  cgm.play_demo = play_demo;
	  cgm.ini_demo = ini_demo;
	  cgm.filter_viz_using_nodes = filter_viz_using_nodes;
	  cgm.filter_viz_using_names = filter_viz_using_names;
	  cgm.update_cats = run_update_cats;
	  cgm.reset_cats = reset_cats;
	  cgm.zoom = zoom_api;
	  cgm.save_matrix = save_matrix;
	  cgm.brush_crop_matrix = brush_crop_matrix;
	  cgm.d3_tip_custom = expose_d3_tip_custom;
	  cgm.reorder = api_reorder;
	  cgm.export_matrix_string = export_matrix_string;

	  return cgm;
	}

	module.exports = Clustergrammer;

/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {

	var utils = __webpack_require__(2);
	var transpose_network = __webpack_require__(3);
	var get_available_filters = __webpack_require__(4);
	var get_filter_default_state = __webpack_require__(5);
	var set_defaults = __webpack_require__(6);
	var check_sim_mat = __webpack_require__(7);
	var check_nodes_for_categories = __webpack_require__(8);

	module.exports = function make_config(args) {

	  var defaults = set_defaults();

	  // Mixin defaults with user-defined arguments.
	  var config = utils.extend(defaults, args);

	  config.network_data = args.network_data;

	  var super_string = ': ';

	  // replace undersores with space in row/col names
	  _.each(['row', 'col'], function (inst_rc) {

	    var inst_nodes = config.network_data[inst_rc + '_nodes'];

	    var has_cats = check_nodes_for_categories(inst_nodes);

	    inst_nodes.forEach(function (d, i) {

	      // add index to row_nodes and col_nodes
	      d[inst_rc + '_index'] = i;

	      if (has_cats) {
	        config.super_labels = true;
	        config.super[inst_rc] = d.name.split(super_string)[0];
	        d.name = d.name.split(super_string)[1];
	      }

	      d.name = String(d.name);

	      d.name = d.name.replace(/_/g, ' ');
	    });
	  });

	  config.network_data.row_nodes_names = utils.pluck(config.network_data.row_nodes, 'name');
	  config.network_data.col_nodes_names = utils.pluck(config.network_data.col_nodes, 'name');

	  config.sim_mat = check_sim_mat(config);

	  var filters = get_available_filters(config.network_data.views);

	  var default_states = {};
	  _.each(_.keys(filters.possible_filters), function (inst_filter) {
	    var tmp_state = get_filter_default_state(filters.filter_data, inst_filter);

	    default_states[inst_filter] = tmp_state;
	  });

	  // process view
	  if (_.has(config.network_data, 'views')) {
	    config.network_data.views.forEach(function (inst_view) {

	      _.each(_.keys(filters.possible_filters), function (inst_filter) {
	        if (!_.has(inst_view, inst_filter)) {
	          inst_view[inst_filter] = default_states[inst_filter];
	        }
	      });

	      var inst_nodes = inst_view.nodes;

	      // proc row/col nodes names in views
	      _.each(['row', 'col'], function (inst_rc) {

	        var has_cats = check_nodes_for_categories(inst_nodes[inst_rc + '_nodes']);

	        inst_nodes[inst_rc + '_nodes'].forEach(function (d, i) {

	          // add index to row_nodes and col_nodes
	          d[inst_rc + '_index'] = i;

	          if (has_cats) {
	            d.name = d.name.split(super_string)[1];
	          }

	          d.name = String(d.name);
	          d.name = d.name.replace(/_/g, ' ');
	        });
	      });
	    });
	  }

	  var col_nodes = config.network_data.col_nodes;
	  var row_nodes = config.network_data.row_nodes;

	  // console.log( config.network_data.links[0] )
	  // console.log( config.network_data.links[1] )
	  // console.log( config.network_data.links[2] )

	  // console.log(_.has(config.network_data,'mat'));

	  ///////////////////////////
	  // convert 'mat' to links
	  ///////////////////////////

	  if (_.has(config.network_data, 'mat')) {

	    var links = [];
	    var mat = config.network_data.mat;
	    var inst_link = {};

	    // console.log('found mat')
	    for (var i = 0; i < mat.length; i++) {
	      for (var j = 0; j < mat[0].length; j++) {
	        // console.log(mat[i][j])

	        inst_link = {};
	        inst_link.source = i;
	        inst_link.target = j;
	        inst_link.value = mat[i][j];
	        links.push(inst_link);
	      }
	    }

	    // save to network_data
	    config.network_data.links = links;
	  }

	  // add names and instantaneous positions to links
	  config.network_data.links.forEach(function (d) {
	    d.name = row_nodes[d.source].name + '_' + col_nodes[d.target].name;
	    d.row_name = row_nodes[d.source].name;
	    d.col_name = col_nodes[d.target].name;
	  });

	  // transpose network if necessary
	  if (config.transpose) {
	    config.network_data = transpose_network(config.network_data);
	    var tmp_col_label = args.col_label;
	    var tmp_row_label = args.row_label;
	    args.row_label = tmp_col_label;
	    args.col_label = tmp_row_label;
	  }

	  // super-row/col labels
	  if (!utils.is_undefined(args.row_label) && !utils.is_undefined(args.col_label)) {
	    config.super_labels = true;
	    config.super = {};
	    config.super.row = args.row_label;
	    config.super.col = args.col_label;
	  }

	  // initialize cluster ordering - both rows and columns
	  config.inst_order = {};
	  if (!utils.is_undefined(args.order) && utils.is_supported_order(args.order)) {
	    config.inst_order.row = args.order;
	    config.inst_order.col = args.order;
	  } else {
	    config.inst_order.row = 'clust';
	    config.inst_order.col = 'clust';
	  }

	  // set row or column order directly -- note that row/col are swapped
	  // !! need to swap row/col orderings
	  if (!utils.is_undefined(args.row_order) && utils.is_supported_order(args.row_order)) {
	    // !! row and col orderings are swapped, need to fix
	    config.inst_order.col = args.row_order;
	  }

	  if (!utils.is_undefined(args.col_order) && utils.is_supported_order(args.col_order)) {
	    // !! row and col orderings are swapped, need to fix
	    config.inst_order.row = args.col_order;
	  }

	  var row_has_group = utils.has(config.network_data.row_nodes[0], 'group');
	  var col_has_group = utils.has(config.network_data.col_nodes[0], 'group');

	  config.show_dendrogram = row_has_group || col_has_group;

	  if (utils.has(config.network_data.links[0], 'value_orig')) {
	    config.keep_orig = true;
	  } else {
	    config.keep_orig = false;
	  }

	  return config;
	};

/***/ },
/* 2 */
/***/ function(module, exports) {


	/* Utility functions
	 * ----------------------------------------------------------------------- */
	module.exports = {
	  normal_name: function (d) {
	    var inst_name = d.name.replace(/_/g, ' ').split('#')[0];
	    return inst_name;
	  },
	  is_supported_order: function (order) {
	    return order === 'ini' || order === 'clust' || order === 'rank_var' || order === 'rank' || order === 'class' || order == 'alpha';
	  },

	  /* Returns whether or not an object has a certain property.
	   */
	  has: function (obj, key) {
	    return obj != null && hasOwnProperty.call(obj, key);
	  },

	  property: function (key) {
	    return function (obj) {
	      return obj == null ? void 0 : obj[key];
	    };
	  },

	  // Convenience version of a common use case of `map`: fetching a property.
	  pluck: function (arr, key) {
	    var self = this;
	    // Double check that we have lodash or underscore available
	    if (window._) {
	      // Underscore provides a _.pluck function. Use that.
	      if (typeof _.pluck === 'function') {
	        return _.pluck(arr, key);
	      } else if (typeof _.map === 'function') {
	        // Lodash does not have a pluck function.
	        // Use _.map with the property function defined above.
	        return _.map(arr, self.property(key));
	      }
	    } else if (arr.map && typeof arr.map === 'function') {
	      // If lodash or underscore not available, check to see if the native arr.map is available.
	      // If so, use it with the property function defined above.
	      return arr.map(self.property(key));
	    }
	  },

	  /* Returns true if the object is undefined.
	   */
	  is_undefined: function (obj) {
	    return obj === void 0;
	  },

	  /* Mixes two objects in together, overwriting a target with a source.
	   */
	  extend: function (target, source) {
	    target = target || {};
	    for (var prop in source) {
	      if (typeof source[prop] === 'object') {
	        target[prop] = this.extend(target[prop], source[prop]);
	      } else {
	        target[prop] = source[prop];
	      }
	    }
	    return target;
	  }
		};

/***/ },
/* 3 */
/***/ function(module, exports, __webpack_require__) {

	var utils = __webpack_require__(2);
	/* Transpose network.
	 */
	module.exports = function (net) {
	  var tnet = {},
	      inst_link,
	      i;

	  tnet.row_nodes = net.col_nodes;
	  tnet.col_nodes = net.row_nodes;
	  tnet.links = [];

	  for (i = 0; i < net.links.length; i++) {
	    inst_link = {};
	    inst_link.source = net.links[i].target;
	    inst_link.target = net.links[i].source;
	    inst_link.value = net.links[i].value;

	    // Optional highlight.
	    if (utils.has(net.links[i], 'highlight')) {
	      inst_link.highlight = net.links[i].highlight;
	    }
	    if (utils.has(net.links[i], 'value_up')) {
	      inst_link.value_up = net.links[i].value_up;
	    }
	    if (utils.has(net.links[i], 'value_dn')) {
	      inst_link.value_dn = net.links[i].value_dn;
	    }
	    if (utils.has(net.links[i], 'info')) {
	      inst_link.info = net.links[i].info;
	    }
	    tnet.links.push(inst_link);
	  }

	  return tnet;
	};

/***/ },
/* 4 */
/***/ function(module, exports) {

	module.exports = function get_available_filters(views) {

	  var possible_filters = {};
	  var filter_data = {};

	  _.each(views, function (inst_view) {
	    var inst_keys = _.keys(inst_view);

	    _.each(inst_keys, function (inst_key) {

	      if (inst_key != 'nodes') {

	        if (!_.has(filter_data, inst_key)) {
	          filter_data[inst_key] = [];
	        }

	        filter_data[inst_key].push(inst_view[inst_key]);

	        filter_data[inst_key] = _.uniq(filter_data[inst_key]);
	      }
	    });
	  });

	  var tmp_filters = _.keys(filter_data);

	  _.each(tmp_filters, function (inst_filter) {

	    var options = filter_data[inst_filter];
	    var num_options = options.length;

	    var filter_type = 'categorical';
	    _.each(options, function (inst_option) {
	      if (typeof inst_option === 'number') {
	        filter_type = 'numerical';
	      }
	    });

	    if (num_options > 1) {
	      possible_filters[inst_filter] = filter_type;
	    }
	  });

	  var filters = {};
	  filters.possible_filters = possible_filters;
	  filters.filter_data = filter_data;

	  return filters;
		};

/***/ },
/* 5 */
/***/ function(module, exports) {

	module.exports = function get_filter_default_state(filter_data, filter_type) {

	  var default_state = filter_data[filter_type].sort(function (a, b) {
	    return b - a;
	  })[0];

	  default_state = String(default_state);

	  return default_state;
	};

/***/ },
/* 6 */
/***/ function(module, exports) {

	module.exports = function set_defaults() {

	  var defaults = {
	    // Label options
	    row_label_scale: 1,
	    col_label_scale: 1,
	    super_labels: false,
	    super: {},
	    show_label_tooltips: true,
	    show_tile_tooltips: true,
	    // matrix options
	    transpose: false,
	    tile_colors: ['#FF0000', '#1C86EE'],
	    bar_colors: ['#FF0000', '#1C86EE'],
	    // value-cat colors
	    // cat_value_colors: ['#2F4F4F', '#8A2BE2'],
	    cat_value_colors: ['#2F4F4F', '#9370DB'],
	    outline_colors: ['orange', 'black'],
	    highlight_color: '#FFFF00',
	    tile_title: false,
	    // Default domain is set to 0: the domain will be set automatically
	    input_domain: 0,
	    opacity_scale: 'linear',
	    do_zoom: true,
	    is_zoom: 0,
	    is_slider_drag: false,
	    is_cropping: false,
	    background_color: '#FFFFFF',
	    super_border_color: '#F5F5F5',
	    outer_margins: {
	      top: 0,
	      bottom: 0,
	      left: 0,
	      right: 0
	    },
	    ini_expand: false,
	    grey_border_width: 2,
	    tile_click_hlight: false,
	    super_label_scale: 1,
	    make_tile_tooltip: function (d) {
	      return d.info;
	    },
	    // initialize view, e.g. initialize with row filtering
	    ini_view: null,
	    // record of requested views
	    requested_view: null,
	    use_sidebar: true,
	    title: null,
	    about: null,
	    sidebar_width: 160,
	    sidebar_icons: true,
	    row_search_placeholder: 'Row',
	    buffer_width: 10,
	    show_sim_mat: false,
	    cat_colors: null,
	    resize: true,
	    clamp_opacity: 0.85,
	    expand_button: true,
	    max_allow_fs: 20,
	    dendro_filter: { 'row': false, 'col': false },
	    cat_filter: { 'row': false, 'col': false },
	    crop_filter_nodes: { 'row': false, 'col': false },
	    row_tip_callback: null,
	    col_tip_callback: null,
	    tile_tip_callback: null,
	    matrix_update_callback: null,
	    cat_update_callback: null,
	    dendro_callback: null,
	    dendro_click_callback: null,
	    new_row_cats: null,
	    make_modals: true,
	    show_viz_border: false
	  };

	  return defaults;
	};

/***/ },
/* 7 */
/***/ function(module, exports) {

	module.exports = function check_sim_mat(config) {

	  var sim_mat = false;

	  var num_rows = config.network_data.row_nodes_names.length;
	  var num_cols = config.network_data.col_nodes_names.length;

	  if (num_rows == num_cols) {

	    // the sort here was causing errors
	    var rows = config.network_data.row_nodes_names;
	    var cols = config.network_data.col_nodes_names;
	    sim_mat = true;

	    _.each(rows, function (inst_row) {
	      var inst_index = rows.indexOf(inst_row);
	      if (inst_row !== cols[inst_index]) {
	        sim_mat = false;
	      }
	    });
	  }

	  if (sim_mat) {
	    config.expand_button = false;
	  }

	  return sim_mat;
	};

/***/ },
/* 8 */
/***/ function(module, exports) {

	module.exports = function check_nodes_for_categories(nodes) {

	  var super_string = ': ';
	  var has_cat = true;

	  _.each(nodes, function (inst_node) {
	    var inst_name = String(inst_node.name);
	    if (inst_name.indexOf(super_string) < 0) {
	      has_cat = false;
	    }
	  });

	  return has_cat;
		};

/***/ },
/* 9 */
/***/ function(module, exports, __webpack_require__) {

	var make_network_using_view = __webpack_require__(10);
	var ini_sidebar_params = __webpack_require__(13);
	var make_requested_view = __webpack_require__(14);
	var get_available_filters = __webpack_require__(4);
	var calc_viz_params = __webpack_require__(15);
	var ini_zoom_info = __webpack_require__(36);

	/*
	Params: calculates the size of all the visualization elements in the
	clustergram.
	 */

	module.exports = function make_params(input_config) {

	  var config = $.extend(true, {}, input_config);
	  var params = config;

	  // keep a copy of inst_view
	  params.inst_nodes = {};
	  params.inst_nodes.row_nodes = params.network_data.row_nodes;
	  params.inst_nodes.col_nodes = params.network_data.col_nodes;

	  // when pre-loading the visualization using a view
	  if (params.ini_view !== null) {

	    var requested_view = params.ini_view;

	    var filters = get_available_filters(params.network_data.views);

	    params.viz = {};
	    params.viz.possible_filters = filters.possible_filters;
	    params.viz.filter_data = filters.filter_data;

	    requested_view = make_requested_view(params, requested_view);
	    params.network_data = make_network_using_view(config, params, requested_view);

	    // save ini_view as requested_view
	    params.requested_view = requested_view;
	  }

	  params = calc_viz_params(params);

	  if (params.use_sidebar) {
	    params.sidebar = ini_sidebar_params(params);
	  }

	  params.zoom_info = ini_zoom_info();

	  return params;
	};

/***/ },
/* 10 */
/***/ function(module, exports, __webpack_require__) {

	var filter_network_using_new_nodes = __webpack_require__(11);
	var get_subset_views = __webpack_require__(12);

	module.exports = function make_network_using_view(config, params, requested_view) {

	  var orig_views = config.network_data.views;

	  var is_enr = false;
	  if (_.has(orig_views[0], 'enr_score_type')) {
	    is_enr = true;
	  }

	  var sub_views = get_subset_views(params, orig_views, requested_view);

	  //////////////////////////////
	  // Enrichr specific rules
	  //////////////////////////////
	  if (is_enr && sub_views.length == 0) {
	    requested_view = { 'N_row_sum': 'all', 'N_col_sum': '10' };
	    sub_views = get_subset_views(params, orig_views, requested_view);
	  }

	  var inst_view = sub_views[0];

	  var new_network_data;

	  // get new_network_data or default back to old_network_data
	  if (typeof inst_view !== 'undefined') {
	    var new_nodes = inst_view.nodes;
	    new_network_data = filter_network_using_new_nodes(config, new_nodes);
	  } else {
	    new_network_data = config.network_data;
	  }

	  return new_network_data;
	};

/***/ },
/* 11 */
/***/ function(module, exports, __webpack_require__) {

	var utils = __webpack_require__(2);

	module.exports = function filter_network_using_new_nodes(config, new_nodes) {

	  var links = config.network_data.links;

	  // get new names of rows and cols
	  var row_names = utils.pluck(new_nodes.row_nodes, 'name');
	  var col_names = utils.pluck(new_nodes.col_nodes, 'name');

	  var new_links = _.filter(links, function (d) {
	    var inst_row = d.name.split('_')[0];
	    var inst_col = d.name.split('_')[1];

	    var row_index = _.indexOf(row_names, inst_row);
	    var col_index = _.indexOf(col_names, inst_col);

	    if (row_index > -1 & col_index > -1) {
	      // redefine source and target
	      d.source = row_index;
	      d.target = col_index;
	      return d;
	    }
	  });

	  // set up new_network_data
	  var new_network_data = {};
	  // rows
	  new_network_data.row_nodes = new_nodes.row_nodes;
	  new_network_data.row_nodes_names = row_names;
	  // cols
	  new_network_data.col_nodes = new_nodes.col_nodes;
	  new_network_data.col_nodes_names = col_names;
	  // links
	  new_network_data.links = new_links;
	  // save all links
	  new_network_data.all_links = links;
	  // add back all views
	  new_network_data.views = config.network_data.views;

	  // add cat_colors if necessary
	  if (_.has(config.network_data, 'cat_colors')) {
	    new_network_data.cat_colors = config.network_data.cat_colors;
	  }

	  return new_network_data;
	};

/***/ },
/* 12 */
/***/ function(module, exports, __webpack_require__) {

	var utils = __webpack_require__(2);
	var get_filter_default_state = __webpack_require__(5);

	module.exports = function get_subset_views(params, views, requested_view) {

	  var inst_value;
	  var found_filter;

	  var request_filters = _.keys(requested_view);

	  // find a view that matches all of the requested view/filter-attributes
	  _.each(request_filters, function (inst_filter) {

	    inst_value = requested_view[inst_filter];

	    // if the value is a number, then convert it to an integer
	    if (/[^a-z_]/i.test(inst_value)) {
	      inst_value = parseInt(inst_value, 10);
	    }

	    // only run filtering if any of the views has the filter
	    found_filter = false;
	    _.each(views, function (tmp_view) {
	      if (utils.has(tmp_view, inst_filter)) {
	        found_filter = true;
	      }
	    });

	    if (found_filter) {
	      views = _.filter(views, function (d) {
	        return d[inst_filter] == inst_value;
	      });
	    }
	  });

	  // remove duplicate complete default states
	  var export_views = [];
	  var found_default = false;
	  var check_default;
	  var inst_default_state;

	  // check if each view is a default state: all filters are at default
	  // there can only be one of these
	  _.each(views, function (inst_view) {

	    check_default = true;

	    // check each filter in a view to see if it is in the default state
	    _.each(_.keys(params.viz.possible_filters), function (inst_filter) {

	      inst_default_state = get_filter_default_state(params.viz.filter_data, inst_filter);

	      if (inst_view[inst_filter] != inst_default_state) {
	        check_default = false;
	      }
	    });

	    // found defaule view, only append if you have not already found a default
	    if (check_default) {
	      if (found_default === false) {
	        found_default = true;
	        export_views.push(inst_view);
	      }
	    } else {
	      export_views.push(inst_view);
	    }
	  });

	  // if (export_views.length > 1){
	  //   console.log('found more than one view in get_subset_views')
	  //   console.log(requested_view)
	  //   console.log(export_views)
	  // } else {
	  //   console.log('found single view in get_subset_views')
	  //   console.log(requested_view)
	  //   console.log(export_views[0])
	  //   console.log('\n')
	  // }

	  return export_views;
		};

/***/ },
/* 13 */
/***/ function(module, exports) {

	module.exports = function ini_sidebar_params(params) {
	  var sidebar = {};

	  sidebar.wrapper = {};
	  // sidebar.wrapper.width = 170;

	  sidebar.row_search = {};
	  sidebar.row_search.box = {};
	  sidebar.row_search.box.height = 34;
	  sidebar.row_search.box.width = 95;
	  sidebar.row_search.placeholder = params.row_search_placeholder;
	  sidebar.row_search.margin_left = 7;

	  sidebar.slider = {};
	  sidebar.slider.width = params.sidebar_width - 30;
	  sidebar.slider.margin_left = 15;

	  sidebar.key_cat = {};
	  sidebar.key_cat.width = params.sidebar_width - 15;
	  sidebar.key_cat.margin_left = 5;
	  sidebar.key_cat.max_height = 100;

	  sidebar.title = params.title;
	  sidebar.title_margin_left = 7;
	  sidebar.about = params.about;
	  sidebar.width = params.sidebar_width;

	  sidebar.buttons = {};
	  sidebar.buttons.width = params.sidebar_width - 15;

	  sidebar.text = {};

	  sidebar.icons = params.sidebar_icons;
	  sidebar.icon_margin_left = -5;

	  return sidebar;
	};

/***/ },
/* 14 */
/***/ function(module, exports) {

	module.exports = function make_view_request(params, requested_view) {

	  // this will add all necessary information to a view request
	  // it will grab necessary view information from the sliders

	  // only one component will be changed at a time
	  var changed_component = _.keys(requested_view)[0];

	  // add additional filter information from othe possible filters
	  _.each(_.keys(params.viz.possible_filters), function (inst_filter) {

	    if (inst_filter != changed_component) {

	      if (!d3.select(params.root + ' .slider_' + inst_filter).empty()) {

	        var inst_state = d3.select(params.root + ' .slider_' + inst_filter).attr('current_state');

	        requested_view[inst_filter] = inst_state;
	      }
	    }
	  });

	  return requested_view;
		};

/***/ },
/* 15 */
/***/ function(module, exports, __webpack_require__) {

	var ini_label_params = __webpack_require__(16);
	var set_viz_wrapper_size = __webpack_require__(17);
	var get_svg_dim = __webpack_require__(19);
	var calc_label_params = __webpack_require__(20);
	var calc_clust_width = __webpack_require__(21);
	var calc_clust_height = __webpack_require__(22);
	var calc_val_max = __webpack_require__(23);
	var calc_matrix_params = __webpack_require__(24);
	var set_zoom_params = __webpack_require__(29);
	var calc_default_fs = __webpack_require__(31);
	var utils = __webpack_require__(2);
	var get_available_filters = __webpack_require__(4);
	var make_cat_params = __webpack_require__(32);

	module.exports = function calc_viz_params(params, predefined_cat_colors = true) {

	  params.labels = ini_label_params(params);
	  params.viz = ini_viz_params(params, predefined_cat_colors);

	  set_viz_wrapper_size(params);

	  params = get_svg_dim(params);
	  params.viz = calc_label_params(params.viz);
	  params.viz = calc_clust_width(params.viz);
	  params.viz = calc_clust_height(params.viz);

	  if (params.sim_mat) {
	    if (params.viz.clust.dim.width <= params.viz.clust.dim.height) {
	      params.viz.clust.dim.height = params.viz.clust.dim.width;
	    } else {
	      params.viz.clust.dim.width = params.viz.clust.dim.height;
	    }
	  }

	  params = calc_val_max(params);
	  params = calc_matrix_params(params);
	  params = set_zoom_params(params);
	  params = calc_default_fs(params);

	  function ini_viz_params(params, predefined_cat_colors = true) {

	    var viz = {};

	    viz.root = params.root;

	    viz.root_tips = params.root.replace('#', '.') + '_' + 'd3-tip';

	    viz.viz_wrapper = params.root + ' .viz_wrapper';
	    viz.do_zoom = params.do_zoom;
	    viz.background_color = params.background_color;
	    viz.super_border_color = params.super_border_color;
	    viz.outer_margins = params.outer_margins;
	    viz.is_expand = params.ini_expand;
	    viz.grey_border_width = params.grey_border_width;
	    viz.show_dendrogram = params.show_dendrogram;
	    viz.tile_click_hlight = params.tile_click_hlight;
	    viz.inst_order = params.inst_order;
	    viz.expand_button = params.expand_button;
	    viz.sim_mat = params.sim_mat;
	    viz.dendro_filter = params.dendro_filter;
	    viz.cat_filter = params.cat_filter;
	    viz.cat_value_colors = params.cat_value_colors;

	    viz.viz_svg = viz.viz_wrapper + ' .viz_svg';

	    viz.zoom_element = viz.viz_wrapper + ' .viz_svg';

	    viz.uni_duration = 1000;
	    // extra space below the clustergram (was 5)
	    // will increase this to accomidate dendro slider
	    viz.bottom_space = 10;
	    viz.run_trans = false;
	    viz.duration = 1000;

	    viz.resize = params.resize;
	    if (utils.has(params, 'size')) {
	      viz.fixed_size = params.size;
	    } else {
	      viz.fixed_size = false;
	    }

	    // width is 1 over this value
	    viz.border_fraction = 65;
	    viz.uni_margin = 5;

	    viz.super_labels = {};
	    viz.super_labels.margin = {};
	    viz.super_labels.dim = {};
	    viz.super_labels.margin.left = viz.grey_border_width;
	    viz.super_labels.margin.top = viz.grey_border_width;
	    viz.super_labels.dim.width = 0;
	    if (params.labels.super_labels) {
	      viz.super_labels.dim.width = 15 * params.labels.super_label_scale;
	    }

	    viz.triangle_opacity = 0.6;

	    viz.norm_labels = {};
	    viz.norm_labels.width = {};

	    viz.dendro_room = {};
	    if (viz.show_dendrogram) {
	      viz.dendro_room.symbol_width = 10;
	    } else {
	      viz.dendro_room.symbol_width = 0;
	    }

	    viz.cat_colors = params.cat_colors;

	    // console.log('ini_viz_params -> make_cat_params')
	    // console.log('predefined_cat_colors outside function ' + String(predefined_cat_colors))

	    viz = make_cat_params(params, viz, predefined_cat_colors);

	    if (_.has(params, 'group_level') == false) {
	      if (viz.show_dendrogram) {
	        params.group_level = {};
	      }
	      params.group_level.row = 5;
	      params.group_level.col = 5;
	    }

	    viz.dendro_opacity = 0.35;

	    viz.spillover_col_slant = viz.norm_labels.width.col;

	    var filters = get_available_filters(params.network_data.views);

	    viz.possible_filters = filters.possible_filters;
	    viz.filter_data = filters.filter_data;

	    viz.viz_nodes = {};

	    // nodes that should be visible based on visible area
	    viz.viz_nodes.row = params.network_data.row_nodes_names;
	    viz.viz_nodes.col = params.network_data.col_nodes_names;

	    // nodes that are currently visible
	    viz.viz_nodes.curr_row = params.network_data.row_nodes_names;
	    viz.viz_nodes.curr_col = params.network_data.col_nodes_names;

	    // correct panning in x direction
	    viz.x_offset = 0;

	    return viz;
	  }

	  return params;
	};

/***/ },
/* 16 */
/***/ function(module, exports) {

	module.exports = function ini_label_params(params) {

	  var labels = {};
	  labels.super_label_scale = params.super_label_scale;
	  labels.super_labels = params.super_labels;
	  labels.super_label_fs = 20;

	  if (labels.super_labels) {
	    labels.super = {};
	    labels.super.row = params.super.row;
	    labels.super.col = params.super.col;
	  }

	  labels.show_label_tooltips = params.show_label_tooltips;

	  labels.row_max_char = _.max(params.network_data.row_nodes, function (inst) {
	    return inst.name.length;
	  }).name.length;

	  labels.col_max_char = _.max(params.network_data.col_nodes, function (inst) {
	    return inst.name.length;
	  }).name.length;

	  labels.max_allow_fs = params.max_allow_fs;

	  return labels;
	};

/***/ },
/* 17 */
/***/ function(module, exports, __webpack_require__) {

	var calc_viz_dimensions = __webpack_require__(18);

	module.exports = function set_viz_wrapper_size(params) {

	  // Create wrapper around SVG visualization
	  if (d3.select(params.root + ' .viz_wrapper').empty()) {

	    d3.select(params.root).append('div').classed('sidebar_wrapper', true);

	    d3.select(params.root).append('div').classed('viz_wrapper', true);
	  }

	  var cont_dim = calc_viz_dimensions(params);

	  d3.select(params.root + ' .sidebar_wrapper').style('float', 'left').style('width', params.sidebar_width + 'px').style('height', cont_dim.height + 'px').style('overflow', 'hidden');

	  d3.select(params.viz.viz_wrapper).style('float', 'left').style('width', cont_dim.width + 'px').style('height', cont_dim.height + 'px');
		};

/***/ },
/* 18 */
/***/ function(module, exports) {

	module.exports = function calc_viz_dimensions(params) {

	  var cont_dim = {};
	  var extra_space = params.buffer_width;

	  // var screen_width = window.innerWidth;
	  // var screen_height = window.innerHeight;

	  // // resize container, then resize visualization within container
	  // d3.select(params.root)
	  //   .style('width', screen_width+'px')
	  //   .style('height', screen_height+'px');

	  var container_width = d3.select(params.root).style('width').replace('px', '');
	  var container_height = d3.select(params.root).style('height').replace('px', '');

	  // get outer_margins
	  var outer_margins;
	  if (params.viz.is_expand === false) {
	    outer_margins = params.viz.outer_margins;
	    cont_dim.width = container_width - params.sidebar_width - extra_space;
	  } else {
	    outer_margins = params.viz.outer_margins;
	    cont_dim.width = container_width - extra_space;
	  }

	  cont_dim.top = outer_margins.top;
	  cont_dim.left = outer_margins.left;

	  if (params.viz.resize) {

	    cont_dim.height = container_height;
	  } else {

	    if (params.viz.is_expand) {
	      cont_dim.width = params.viz.fixed_size.width;
	    } else {
	      cont_dim.width = params.viz.fixed_size.width - params.sidebar_width;
	    }

	    cont_dim.height = params.viz.fixed_size.height;
	  }

	  return cont_dim;
		};

/***/ },
/* 19 */
/***/ function(module, exports) {

	module.exports = function get_svg_dim(params) {

	  params.viz.svg_dim = {};
	  params.viz.svg_dim.width = Number(d3.select(params.viz.viz_wrapper).style('width').replace('px', ''));

	  params.viz.svg_dim.height = Number(d3.select(params.viz.viz_wrapper).style('height').replace('px', ''));

	  return params;
	};

/***/ },
/* 20 */
/***/ function(module, exports) {

	module.exports = function calc_label_params(viz) {

	  viz.norm_labels.margin = {};

	  viz.norm_labels.margin.left = viz.super_labels.margin.left + viz.super_labels.dim.width;

	  viz.norm_labels.margin.top = viz.super_labels.margin.top + viz.super_labels.dim.width;

	  viz.label_background = {};

	  viz.label_background.row = viz.norm_labels.width.row + viz.cat_room.row + viz.uni_margin;

	  viz.label_background.col = viz.norm_labels.width.col + viz.cat_room.col + viz.uni_margin;

	  return viz;
	};

/***/ },
/* 21 */
/***/ function(module, exports) {

	module.exports = function calc_clust_width(viz) {

	  viz.clust = {};
	  viz.clust.margin = {};

	  // margin on left/top of the clustergram/matrix
	  // 1) norm_label margin and width
	  // 2) cat_room and uni_margin
	  viz.clust.margin.left = viz.norm_labels.margin.left + viz.norm_labels.width.row + viz.cat_room.row + viz.uni_margin;

	  viz.clust.margin.top = viz.norm_labels.margin.top + viz.norm_labels.width.col + viz.cat_room.col + viz.uni_margin;

	  // the clustergram/matrix width is the svg width minus:
	  // the margin of the clustergram on the left
	  // the room for the spillover on the right
	  // ** the dendro will fit in the spillover room on the right
	  var ini_clust_width = viz.svg_dim.width - viz.clust.margin.left - viz.spillover_col_slant;

	  // make tmp scale to calc height of triangle col labels
	  var tmp_x_scale = d3.scale.ordinal().rangeBands([0, ini_clust_width]).domain(_.range(viz.num_col_nodes));

	  var triangle_height = tmp_x_scale.rangeBand() / 2;

	  // prevent the visualization from being unnecessarily wide
	  if (triangle_height > viz.norm_labels.width.col) {
	    var reduce_width = viz.norm_labels.width.col / triangle_height;
	    ini_clust_width = ini_clust_width * reduce_width;
	  }

	  viz.clust.dim = {};
	  viz.clust.dim.width = ini_clust_width;

	  return viz;
	};

/***/ },
/* 22 */
/***/ function(module, exports) {

	module.exports = function calc_clust_height(viz) {

	  // the clustergram/matrix height is the svg width minus:
	  // the margin of the clustergram on the top
	  // the dendrogram
	  // the bottom_space
	  var ini_clust_height = viz.svg_dim.height - viz.clust.margin.top - viz.dendro_room.col - viz.bottom_space;

	  viz.clust.dim.height = ini_clust_height;

	  return viz;
	};

/***/ },
/* 23 */
/***/ function(module, exports) {

	module.exports = function calc_val_max(params) {

	  var val_max = Math.abs(_.max(params.network_data.col_nodes, function (d) {
	    return Math.abs(d.value);
	  }).value);

	  params.labels.bar_scale_col = d3.scale.linear().domain([0, val_max]).range([0, 0.75 * params.viz.norm_labels.width.col]);

	  val_max = Math.abs(_.max(params.network_data.row_nodes, function (d) {
	    return Math.abs(d.value);
	  }).value);

	  params.labels.bar_scale_row = d3.scale.linear().domain([0, val_max]).range([0, params.viz.norm_labels.width.row]);

	  return params;
	};

/***/ },
/* 24 */
/***/ function(module, exports, __webpack_require__) {

	var ini_matrix_params = __webpack_require__(25);
	var calc_downsampled_levels = __webpack_require__(27);

	module.exports = function calc_matrix_params(params) {

	  params.matrix = ini_matrix_params(params);

	  // X and Y scales: set domains and ranges
	  //////////////////////////////////////////////
	  params.viz.x_scale = d3.scale.ordinal().rangeBands([0, params.viz.clust.dim.width]);

	  params.viz.y_scale = d3.scale.ordinal().rangeBands([0, params.viz.clust.dim.height]);

	  var inst_order;

	  _.each(['row', 'col'], function (inst_rc) {

	    inst_order = params.viz.inst_order[inst_rc];

	    if (inst_order === 'custom') {
	      inst_order = 'clust';
	    }

	    if (inst_rc === 'row') {
	      params.viz.x_scale.domain(params.matrix.orders[inst_order + '_' + inst_rc]);
	    } else {
	      params.viz.y_scale.domain(params.matrix.orders[inst_order + '_' + inst_rc]);
	    }
	  });

	  // border width
	  params.viz.border_width = {};
	  params.viz.border_width.x = params.viz.x_scale.rangeBand() / params.viz.border_fraction;
	  params.viz.border_width.y = params.viz.y_scale.rangeBand() / params.viz.border_fraction;

	  // rect width needs matrix and zoom parameters
	  params.viz.rect_width = params.viz.x_scale.rangeBand() - params.viz.border_width.x;

	  // moved calculateion to calc_matrix_params
	  params.viz.rect_height = params.viz.y_scale.rangeBand() - params.viz.border_width.y;

	  calc_downsampled_levels(params);

	  return params;
		};

/***/ },
/* 25 */
/***/ function(module, exports, __webpack_require__) {

	var utils = __webpack_require__(2);
	var initialize_matrix = __webpack_require__(26);

	module.exports = function ini_matrix_params(params) {

	  var matrix = {};

	  var network_data = params.network_data;

	  matrix.tile_colors = params.tile_colors;
	  matrix.bar_colors = params.bar_colors;
	  matrix.outline_colors = params.outline_colors;
	  matrix.hlight_color = params.highlight_color;
	  matrix.tile_title = params.tile_title;
	  matrix.show_tile_tooltips = params.show_tile_tooltips;
	  matrix.make_tile_tooltip = params.make_tile_tooltip;

	  // initialized clicked tile and rows
	  matrix.click_hlight_x = -666;
	  matrix.click_hlight_y = -666;
	  matrix.click_hlight_row = -666;
	  matrix.click_hlight_col = -666;

	  // definition of a large matrix (num links) determines if transition is run
	  matrix.def_large_matrix = 10000;
	  matrix.opacity_function = params.opacity_scale;

	  matrix.orders = {};

	  _.each(['row', 'col'], function (inst_rc) {

	    // row ordering is based on col info and vice versa
	    var other_rc;
	    if (inst_rc === 'row') {
	      other_rc = 'col';
	    } else {
	      other_rc = 'row';
	    }

	    // the nodes are defined using other_rc
	    var inst_nodes = network_data[other_rc + '_nodes'];
	    var num_nodes = inst_nodes.length;

	    var nodes_names = utils.pluck(inst_nodes, 'name');
	    var tmp = nodes_names.sort();

	    var alpha_index = _.map(tmp, function (d) {
	      return network_data[other_rc + '_nodes_names'].indexOf(d);
	    });

	    matrix.orders['alpha_' + inst_rc] = alpha_index;

	    var possible_orders = ['clust', 'rank'];

	    if (_.has(inst_nodes[0], 'rankvar')) {
	      possible_orders.push('rankvar');
	    }

	    if (params.viz.all_cats[other_rc].length > 0) {
	      _.each(params.viz.all_cats[other_rc], function (inst_cat) {
	        // the index of the category has replaced - with _
	        inst_cat = inst_cat.replace('-', '_');
	        possible_orders.push(inst_cat + '_index');
	      });
	    }

	    _.each(possible_orders, function (inst_order) {

	      var tmp_order_index = d3.range(num_nodes).sort(function (a, b) {
	        return inst_nodes[b][inst_order] - inst_nodes[a][inst_order];
	      });

	      matrix.orders[inst_order + '_' + inst_rc] = tmp_order_index;
	    });
	  });

	  if (utils.has(network_data, 'all_links')) {
	    matrix.max_link = _.max(network_data.all_links, function (d) {
	      return Math.abs(d.value);
	    }).value;
			matrix.true_max=_.max(network_data.all_links, function (d) {
	      return d.value;
	    }).value;
			matrix.true_min=_.min(network_data.all_links, function (d) {
	      return d.value;
	    }).value;
	  } else {
	    matrix.max_link = _.max(network_data.links, function (d) {
	      return Math.abs(d.value);
	    }).value;
			matrix.true_max=_.max(network_data.links, function (d) {
	      return d.value;
	    }).value;
			matrix.true_min=_.min(network_data.links, function (d) {
	      return d.value;
	    }).value;
	  }
		matrix.mid_val = (matrix.true_max + matrix.true_min) / 2;
	  matrix.abs_max_val = Math.abs(matrix.max_link) * params.clamp_opacity;

	  if (params.input_domain === 0) {
	    if (matrix.opacity_function === 'linear') {
	      matrix.opacity_scale = d3.scale.linear().domain([matrix.mid_val, matrix.true_max]).clamp(true).range([0.0, 1.0]);
	    } else if (matrix.opacity_function === 'log') {
	      matrix.opacity_scale = d3.scale.log().domain([0.001, matrix.abs_max_val]).clamp(true).range([0.0, 1.0]);
	    }
	  } else {
	    if (matrix.opacity_function === 'linear') {
	      matrix.opacity_scale = d3.scale.linear().domain([0, params.input_domain]).clamp(true).range([0.0, 1.0]);
	    } else if (matrix.opacity_function === 'log') {
	      matrix.opacity_scale = d3.scale.log().domain([0.001, params.input_domain]).clamp(true).range([0.0, 1.0]);
	    }
	  }

	  var has_val_up = utils.has(network_data.links[0], 'value_up');
	  var has_val_dn = utils.has(network_data.links[0], 'value_dn');

	  if (has_val_up || has_val_dn) {
	    matrix.tile_type = 'updn';
	  } else {
	    matrix.tile_type = 'simple';
	  }

	  if (utils.has(network_data.links[0], 'highlight')) {
	    matrix.highlight = 1;
	  } else {
	    matrix.highlight = 0;
	  }

	  matrix.matrix = initialize_matrix(network_data);

	  matrix.wait_tooltip = 0;

	  return matrix;
	};

/***/ },
/* 26 */
/***/ function(module, exports, __webpack_require__) {

	var utils = __webpack_require__(2);

	module.exports = function (network_data) {
	  var matrix = [];
	  var ini_object;

	  var keep_orig;
	  if (utils.has(network_data.links[0], 'value_orig')) {
	    keep_orig = true;
	  } else {
	    keep_orig = false;
	  }

	  network_data.row_nodes.forEach(function (tmp, row_index) {

	    matrix[row_index] = {};
	    matrix[row_index].name = network_data.row_nodes[row_index].name;
	    matrix[row_index].row_index = row_index;

	    matrix[row_index].row_data = d3.range(network_data.col_nodes.length).map(function (col_index) {

	      if (utils.has(network_data.links[0], 'value_up') || utils.has(network_data.links[0], 'value_dn')) {

	        ini_object = {
	          pos_x: col_index,
	          pos_y: row_index,
	          value: 0,
	          value_up: 0,
	          value_dn: 0,
	          highlight: 0
	        };
	      } else {

	        ini_object = {
	          pos_x: col_index,
	          pos_y: row_index,
	          value: 0,
	          highlight: 0
	        };
	      }

	      if (keep_orig) {
	        ini_object.value_orig = 0;
	      }

	      return ini_object;
	    });
	  });

	  network_data.links.forEach(function (link) {

	    // transfer additional link information is necessary
	    matrix[link.source].row_data[link.target].value = link.value;
	    matrix[link.source].row_data[link.target].row_name = link.row_name;
	    matrix[link.source].row_data[link.target].col_name = link.col_name;

	    if (utils.has(link, 'value_up') || utils.has(link, 'value_dn')) {
	      matrix[link.source].row_data[link.target].value_up = link.value_up;
	      matrix[link.source].row_data[link.target].value_dn = link.value_dn;
	    }

	    if (keep_orig) {
	      matrix[link.source].row_data[link.target].value_orig = link.value_orig;
	    }

	    if (link.highlight) {
	      matrix[link.source].row_data[link.target].highlight = link.highlight;
	    }
	    if (link.info) {
	      matrix[link.source].row_data[link.target].info = link.info;
	    }
	  });

	  return matrix;
	};

/***/ },
/* 27 */
/***/ function(module, exports, __webpack_require__) {

	var calc_downsampled_matrix = __webpack_require__(28);

	module.exports = function calc_downsampled_levels(params) {

	  // console.log('---- before ---------')
	  // console.log(params.matrix.matrix[0].row_data[0].value)

	  // height of downsampled rectangles
	  var ds_height = 3;

	  var min_rect_height = 2;

	  var total_zoom = ds_height / params.viz.rect_height;

	  // amount of zooming that is tolerated for the downsampled rows
	  var inst_zt = 2;
	  params.viz.ds_zt = inst_zt;

	  var num_levels = Math.floor(Math.log(total_zoom) / Math.log(inst_zt));

	  if (params.viz.rect_height < min_rect_height && num_levels > 0) {

	    // increase ds opacity, as more rows are compressed into a single downsampled
	    // row, increase the opacity of the downsampled row. Max increase will be 2x
	    // when 100 or more rows are compressed
	    var max_opacity_scale = 2;
	    params.viz.ds_opacity_scale = d3.scale.linear().domain([1, 100]).range([1, max_opacity_scale]).clamp(true);

	    var ds;

	    params.viz.ds_num_levels = num_levels;

	    // array of downsampled parameters
	    params.viz.ds = [];

	    // array of downsampled matrices at varying levels
	    params.matrix.ds_matrix = [];

	    var inst_order = params.viz.inst_order.row;

	    // cloning
	    var mat = $.extend(true, {}, params.matrix.matrix);

	    // calculate parameters for different levels
	    for (var i = 0; i < num_levels; i++) {

	      // instantaneous ds_level (-1 means no downsampling)
	      params.viz.ds_level = 0;

	      ds = {};

	      ds.height = ds_height;
	      ds.num_levels = num_levels;

	      var inst_zoom_tolerance = Math.pow(inst_zt, i);

	      ds.zt = inst_zoom_tolerance;

	      // the number of downsampled rows is given by the height of the clustergram
	      // divided by the adjusted height of the downsampled rect.
	      // the adjusted height is the height divided by the zooming tolerance of
	      // the downsampled layer

	      // number of downsampled rows
	      ds.num_rows = Math.round(params.viz.clust.dim.height / (ds.height / inst_zoom_tolerance));

	      // x_scale
	      /////////////////////////
	      ds.x_scale = d3.scale.ordinal().rangeBands([0, params.viz.clust.dim.width]);

	      ds.x_scale.domain(params.matrix.orders[inst_order + '_row']);

	      // y_scale
	      /////////////////////////
	      ds.y_scale = d3.scale.ordinal().rangeBands([0, params.viz.clust.dim.height]);
	      ds.y_scale.domain(d3.range(ds.num_rows + 1));

	      ds.rect_height = ds.y_scale.rangeBand() - params.viz.border_width.y;

	      params.viz.ds.push(ds);

	      var matrix = calc_downsampled_matrix(params, mat, i);
	      params.matrix.ds_matrix.push(matrix);
	    }

	    // reset row viz_nodes since downsampling
	    params.viz.viz_nodes.row = d3.range(params.matrix.ds_matrix[0].length).map(String);
	  } else {
	    // set ds to null if no downsampling is done
	    params.viz.ds = null;
	    // instantaneous ds_level (-1 means no downsampling)
	    params.viz.ds_level = -1;
	    params.viz.ds_num_levels = 0;
	  }

	  // console.log('---- after ---------')
	  // console.log(params.matrix.matrix[0].row_data[0].value)
		};

/***/ },
/* 28 */
/***/ function(module, exports) {

	module.exports = function calc_downsampled_matrix(params, mat, ds_level) {

	  var inst_num_rows = params.viz.ds[ds_level].num_rows;

	  var num_compressed_rows = params.network_data.row_nodes.length / inst_num_rows;

	  // increase ds opacity, as more rows are compressed into a single downsampled
	  // row, increase the opacity of the downsampled row.
	  var opacity_factor = params.viz.ds_opacity_scale(num_compressed_rows);

	  var mod_val = params.viz.clust.dim.height / inst_num_rows;

	  var ds_mat = [];
	  var inst_obj;

	  var len_ds_array = inst_num_rows + 1;

	  var i;
	  var x;

	  // initialize array of objects
	  for (i = 0; i < len_ds_array; i++) {

	    inst_obj = {};
	    inst_obj.row_index = i;
	    inst_obj.name = String(i);
	    inst_obj.all_names = [];

	    ds_mat.push(inst_obj);
	  }

	  _.each(mat, function (inst_row) {

	    // row ordering information is contained in y_scale
	    var inst_y = params.viz.y_scale(inst_row.row_index);

	    var ds_index = Math.round(inst_y / mod_val);

	    var inst_row_data = inst_row.row_data;

	    // gather names
	    ds_mat[ds_index].all_names.push(inst_row.name);

	    // gather row_data
	    if (_.has(ds_mat[ds_index], 'row_data')) {

	      for (x = 0; x < inst_row_data.length; x++) {
	        ds_mat[ds_index].row_data[x].value = ds_mat[ds_index].row_data[x].value + inst_row_data[x].value;
	      }
	    } else {

	      var new_data = [];
	      for (x = 0; x < inst_row_data.length; x++) {
	        new_data[x] = inst_row_data[x];
	      }

	      ds_mat[ds_index].row_data = new_data;
	    }
	  });

	  // average the values
	  _.each(ds_mat, function (tmp_ds) {

	    var tmp_row_data = tmp_ds.row_data;

	    var num_names = tmp_ds.all_names.length;

	    _.each(tmp_row_data, function (tmp_obj) {
	      tmp_obj.value = tmp_obj.value / num_names * opacity_factor;
	    });
	  });

	  // all names were found
	  var all_names = [];

	  _.each(ds_mat, function (inst_row) {
	    all_names = all_names.concat(inst_row.all_names);
	  });

	  return ds_mat;
		};

/***/ },
/* 29 */
/***/ function(module, exports, __webpack_require__) {

	var calc_zoom_switching = __webpack_require__(30);

	module.exports = function set_zoom_params(params) {

	  params.viz.zoom_scale_font = {};
	  params.viz.zoom_scale_font.row = 1;
	  params.viz.zoom_scale_font.col = 1;

	  var max_zoom_limit = 0.75;
	  var half_col_height = params.viz.x_scale.rangeBand() / 2;
	  params.viz.square_zoom = params.viz.norm_labels.width.col / half_col_height * max_zoom_limit;

	  params.viz = calc_zoom_switching(params.viz);

	  return params;
	};

/***/ },
/* 30 */
/***/ function(module, exports) {

	module.exports = function calc_zoom_switching(viz) {

	  var width_by_col = viz.clust.dim.width / viz.num_col_nodes;
	  var height_by_row = viz.clust.dim.height / viz.num_row_nodes;

	  viz.zoom_ratio = {};
	  viz.zoom_ratio.x = width_by_col / height_by_row;
	  viz.zoom_ratio.y = 1;

	  if (viz.zoom_ratio.x < 1) {
	    viz.zoom_ratio.y = 1 / viz.zoom_ratio.x;
	    viz.zoom_ratio.x = 1;
	  }

	  return viz;
	};

/***/ },
/* 31 */
/***/ function(module, exports) {

	module.exports = function calc_default_fs(params) {

	  params.labels.default_fs_row = params.viz.y_scale.rangeBand() * 1.01;
	  params.labels.default_fs_col = params.viz.x_scale.rangeBand() * 0.87;

	  if (params.labels.default_fs_row > params.labels.max_allow_fs) {
	    params.labels.default_fs_row = params.labels.max_allow_fs;
	  }

	  if (params.labels.default_fs_col > params.labels.max_allow_fs) {
	    params.labels.default_fs_col = params.labels.max_allow_fs;
	  }

	  return params;
		};

/***/ },
/* 32 */
/***/ function(module, exports, __webpack_require__) {

	var calc_cat_params = __webpack_require__(33);
	var utils = __webpack_require__(2);
	var colors = __webpack_require__(34);
	var check_if_value_cats = __webpack_require__(35);

	module.exports = function make_cat_params(params, viz, predefined_cat_colors = true) {

	  var super_string = ': ';
	  var tmp_super;
	  var inst_info;
	  var inst_color;

	  viz.show_categories = {};
	  viz.all_cats = {};
	  viz.cat_names = {};
	  viz.cat_info = {};

	  // this will hold the information for calculating the opacity of the value
	  // function
	  var ini_val_opacity = {};
	  ini_val_opacity.row = null;
	  ini_val_opacity.col = null;

	  viz.cat_colors = {};
	  viz.cat_colors.value_opacity = ini_val_opacity;

	  var num_colors = 0;
	  _.each(['row', 'col'], function (inst_rc) {

	    viz.show_categories[inst_rc] = false;

	    viz.all_cats[inst_rc] = [];
	    var tmp_keys = _.keys(params.network_data[inst_rc + '_nodes'][0]);

	    tmp_keys = tmp_keys.sort();

	    _.each(tmp_keys, function (d) {
	      if (d.indexOf('cat-') >= 0) {
	        viz.show_categories[inst_rc] = true;
	        viz.all_cats[inst_rc].push(d);
	      }
	    });

	    viz.cat_info[inst_rc] = null;

	    if (viz.show_categories[inst_rc]) {

	      viz.cat_colors[inst_rc] = {};
	      viz.cat_info[inst_rc] = {};
	      viz.cat_names[inst_rc] = {};

	      _.each(viz.all_cats[inst_rc], function (cat_title) {

	        var inst_node = params.network_data[inst_rc + '_nodes'][0];

	        // look for title of category in category name
	        if (typeof inst_node[cat_title] === 'string') {

	          if (inst_node[cat_title].indexOf(super_string) > 0) {
	            tmp_super = inst_node[cat_title].split(super_string)[0];
	            viz.cat_names[inst_rc][cat_title] = tmp_super;
	          } else {
	            viz.cat_names[inst_rc][cat_title] = cat_title;
	          }
	        } else {
	          viz.cat_names[inst_rc][cat_title] = cat_title;
	        }

	        var cat_instances_titles = utils.pluck(params.network_data[inst_rc + '_nodes'], cat_title);
	        var cat_instances = [];

	        _.each(cat_instances_titles, function (inst_cat) {

	          var new_cat;
	          if (inst_cat.indexOf(': ') > 0) {
	            new_cat = inst_cat.split(': ')[1];
	          } else {
	            new_cat = inst_cat;
	          }

	          cat_instances.push(new_cat);
	        });

	        var cat_states = _.uniq(cat_instances_titles).sort();

	        // check whether all the categories are of value type
	        inst_info = check_if_value_cats(cat_states);

	        // add histogram to inst_info
	        if (inst_info.type === 'cat_strings') {
	          // remove titles from categories in hist
	          var cat_hist = _.countBy(cat_instances);
	          inst_info.cat_hist = cat_hist;
	        } else {
	          inst_info.cat_hist = null;
	        }

	        // pass info_info object
	        viz.cat_info[inst_rc][cat_title] = inst_info;

	        viz.cat_colors[inst_rc][cat_title] = {};

	        _.each(cat_states, function (cat_tmp, inst_index) {

	          inst_color = colors.get_random_color(inst_index + num_colors);

	          viz.cat_colors[inst_rc][cat_title][cat_tmp] = inst_color;

	          // hack to get 'Not' categories to not be dark colored
	          // also doing this for false
	          if (typeof cat_tmp === 'string') {
	            if (cat_tmp.indexOf('Not ') >= 0 || cat_tmp.indexOf(': false') > 0) {
	              viz.cat_colors[inst_rc][cat_title][cat_tmp] = '#eee';
	            }
	          }

	          num_colors = num_colors + 1;
	        });
	      });
	    }

	    if (_.has(params.network_data, 'cat_colors') && predefined_cat_colors === true) {
	      viz.cat_colors[inst_rc] = params.network_data.cat_colors[inst_rc];
	    }

	    if (params.sim_mat) {
	      // sending row color info to columns since row color info can be updated
	      viz.cat_colors.col = viz.cat_colors.row;
	    }
	  });

	  viz.cat_colors = viz.cat_colors;

	  viz.cat_colors.opacity = 0.6;
	  viz.cat_colors.active_opacity = 0.9;

	  viz = calc_cat_params(params, viz);

	  return viz;
		};

/***/ },
/* 33 */
/***/ function(module, exports) {

	module.exports = function calc_cat_params(params, viz) {

	  var separtion_room;

	  // increase the width of the label container based on the label length
	  var label_scale = d3.scale.linear().domain([5, 15]).range([85, 120]).clamp('true');

	  viz.cat_room = {};
	  viz.cat_room.symbol_width = 12;
	  viz.cat_room.separation = 3;

	  _.each(['row', 'col'], function (inst_rc) {

	    viz.norm_labels.width[inst_rc] = label_scale(params.labels[inst_rc + '_max_char']) * params[inst_rc + '_label_scale'];

	    viz['num_' + inst_rc + '_nodes'] = params.network_data[inst_rc + '_nodes'].length;

	    // if (_.has(config, 'group_level')){
	    //   config.group_level[inst_rc] = 5;
	    // }

	    if (inst_rc === 'row') {
	      viz.dendro_room[inst_rc] = viz.dendro_room.symbol_width;
	    } else {
	      viz.dendro_room[inst_rc] = viz.dendro_room.symbol_width + 3 * viz.uni_margin;
	    }

	    var num_cats = viz.all_cats[inst_rc].length;

	    if (viz.show_categories[inst_rc]) {

	      separtion_room = (num_cats - 1) * viz.cat_room.separation;

	      var adjusted_cats;
	      if (inst_rc === 'row') {
	        adjusted_cats = num_cats + 1;
	      } else {
	        adjusted_cats = num_cats;
	      }

	      viz.cat_room[inst_rc] = adjusted_cats * viz.cat_room.symbol_width + separtion_room;
	    } else {
	      // no categories
	      if (inst_rc == 'row') {
	        viz.cat_room[inst_rc] = viz.cat_room.symbol_width;
	      } else {
	        viz.cat_room[inst_rc] = 0;
	      }
	    }
	  });

	  return viz;
		};

/***/ },
/* 34 */
/***/ function(module, exports) {

	// colors from http://graphicdesign.stackexchange.com/revisions/3815/8
	var all_colors;

	all_colors = ["#393b79", "#aec7e8", "#ff7f0e", "#ffbb78", "#98df8a", "#bcbd22", "#404040", "#ff9896", "#c5b0d5", "#8c564b", "#1f77b4", "#5254a3", "#FFDB58", "#c49c94", "#e377c2", "#7f7f7f", "#2ca02c", "#9467bd", "#dbdb8d", "#17becf", "#637939", "#6b6ecf", "#9c9ede", "#d62728", "#8ca252", "#8c6d31", "#bd9e39", "#e7cb94", "#843c39", "#ad494a", "#d6616b", "#7b4173", "#a55194", "#ce6dbd", "#de9ed6"];

	// too light colors
	// "#e7969c",
	// "#c7c7c7",
	// "#f7b6d2",
	// "#cedb9c",
	// "#9edae5",

	function get_default_color() {
	  return '#EEE';
	}

	function get_random_color(i) {
	  return all_colors[i % get_num_colors()];
	}

	function get_num_colors() {
	  return all_colors.length;
	}

	module.exports = {
	  get_default_color: get_default_color,
	  get_random_color: get_random_color,
	  get_num_colors: get_num_colors
		};

/***/ },
/* 35 */
/***/ function(module, exports) {

	module.exports = function check_if_value_cats(cat_states) {

	  var tmp_cat = cat_states[0];

	  var has_title = false;
	  var might_have_values = false;
	  var cat_types = 'cat_strings';
	  var max_abs_val = NaN;
	  var all_values = [];
	  var cat_scale = null;

	  var super_string = ': ';

	  if (typeof tmp_cat === 'string') {
	    if (tmp_cat.indexOf(super_string) > -1) {
	      has_title = true;
	      tmp_cat = tmp_cat.split(super_string)[1];
	    }
	  }

	  if (isNaN(tmp_cat) == false) {
	    might_have_values = true;
	  }

	  // check each value for number
	  if (might_have_values) {

	    // the default state is that all are now values, check each one
	    cat_types = 'cat_values';

	    _.each(cat_states, function (inst_cat) {

	      if (has_title) {
	        inst_cat = inst_cat.split(super_string)[1];
	      }

	      // checking whether inst_cat is 'not a number'
	      if (isNaN(inst_cat) === true) {
	        cat_types = 'cat_strings';
	      } else {
	        inst_cat = parseFloat(inst_cat);
	        all_values.push(inst_cat);
	      }
	    });
	  }

	  if (cat_types === 'cat_values') {

	    // get absolute value
	    var max_value = _.max(all_values, function (d) {
	      return Math.abs(d);
	    });

	    max_abs_val = Math.abs(max_value);

	    cat_scale = d3.scale.linear().domain([0, max_abs_val]).range([0, 1]);
	  }

	  var inst_info = {};
	  inst_info.type = cat_types;
	  inst_info.max_abs_val = max_abs_val;
	  inst_info.cat_scale = cat_scale;

	  return inst_info;
		};

/***/ },
/* 36 */
/***/ function(module, exports) {

	module.exports = function ini_zoom_info() {

	  var zoom_info = {};
	  zoom_info.zoom_x = 1;
	  zoom_info.zoom_y = 1;
	  zoom_info.trans_x = 0;
	  zoom_info.trans_y = 0;

	  return zoom_info;
		};

/***/ },
/* 37 */
/***/ function(module, exports, __webpack_require__) {

	var generate_matrix = __webpack_require__(38);
	var make_row_label_container = __webpack_require__(49);
	var make_col_label_container = __webpack_require__(103);
	var generate_super_labels = __webpack_require__(111);
	var spillover = __webpack_require__(112);
	var initialize_resizing = __webpack_require__(123);
	var ini_doubleclick = __webpack_require__(133);
	var make_col_cat = __webpack_require__(152);
	var make_row_cat = __webpack_require__(158);
	var trim_text = __webpack_require__(118);
	var make_row_dendro = __webpack_require__(159);
	var make_col_dendro = __webpack_require__(160);
	var make_svg_dendro_sliders = __webpack_require__(161);
	var make_row_dendro_spillover = __webpack_require__(164);

	module.exports = function make_viz(cgm) {

	  var params = cgm.params;

	  d3.select(params.viz.viz_wrapper + ' svg').remove();

	  var svg_group = d3.select(params.viz.viz_wrapper).append('svg').attr('class', 'viz_svg').attr('id', 'svg_' + params.root.replace('#', '')).attr('width', params.viz.svg_dim.width).attr('height', params.viz.svg_dim.height).attr('is_zoom', 0).attr('stopped_zoom', 1);

	  svg_group.append('rect').attr('class', 'super_background').style('width', params.viz.svg_dim.width).style('height', params.viz.svg_dim.height).style('fill', 'white');

	  generate_matrix(params, svg_group);

	  make_row_label_container(cgm);

	  if (params.viz.show_dendrogram) {
	    make_row_dendro(cgm);
	    make_col_dendro(cgm);
	  }

	  make_row_dendro_spillover(cgm);

	  make_col_label_container(cgm);

	  // initial trim text
	  if (params.viz.ds_level === -1) {
	    _.each(['row', 'col'], function (inst_rc) {

	      var inst_fs = Number(d3.select('.' + inst_rc + '_label_group').select('text').style('font-size').replace('px', ''));

	      var min_trim_fs = 8;
	      if (inst_fs > min_trim_fs) {
	        d3.selectAll(params.root + ' .' + inst_rc + '_label_group').each(function () {
	          trim_text(params, this, inst_rc);
	        });
	      }
	    });
	  }

	  // make category colorbars
	  make_row_cat(cgm);
	  if (params.viz.show_categories.col) {
	    make_col_cat(cgm);
	  }

	  spillover(cgm);

	  if (params.labels.super_labels) {
	    generate_super_labels(params);
	  }

	  // sliders should go above super labels
	  make_svg_dendro_sliders(cgm);

	  function border_colors() {
	    var inst_color = params.viz.super_border_color;
	    if (params.viz.is_expand || params.show_viz_border == false) {
	      inst_color = 'white';
	    }
	    return inst_color;
	  }

	  // left border
	  d3.select(params.viz.viz_svg).append('rect').classed('left_border', true).classed('borders', true).attr('fill', border_colors).attr('width', params.viz.grey_border_width).attr('height', params.viz.svg_dim.height).attr('transform', 'translate(0,0)');

	  // right border
	  d3.select(params.viz.viz_svg).append('rect').classed('right_border', true).classed('borders', true).attr('fill', border_colors).attr('width', params.viz.grey_border_width).attr('height', params.viz.svg_dim.height).attr('transform', function () {
	    var inst_offset = params.viz.svg_dim.width - params.viz.grey_border_width;
	    return 'translate(' + inst_offset + ',0)';
	  });

	  // top border
	  d3.select(params.viz.viz_svg).append('rect').classed('top_border', true).classed('borders', true).attr('fill', border_colors).attr('width', params.viz.svg_dim.width).attr('height', params.viz.grey_border_width).attr('transform', function () {
	    var inst_offset = 0;
	    return 'translate(' + inst_offset + ',0)';
	  });

	  // bottom border
	  d3.select(params.viz.viz_svg).append('rect').classed('bottom_border', true).classed('borders', true).attr('fill', border_colors).attr('width', params.viz.svg_dim.width).attr('height', params.viz.grey_border_width).attr('transform', function () {
	    var inst_offset = params.viz.svg_dim.height - params.viz.grey_border_width;
	    return 'translate(0,' + inst_offset + ')';
	  });

	  initialize_resizing(cgm);

	  ini_doubleclick(cgm);

	  if (params.viz.do_zoom) {
	    d3.select(params.viz.zoom_element).call(params.zoom_behavior);
	  }

	  d3.select(params.viz.zoom_element).on('dblclick.zoom', null);
		};

/***/ },
/* 38 */
/***/ function(module, exports, __webpack_require__) {

	var utils = __webpack_require__(2);
	var draw_gridlines = __webpack_require__(39);
	var add_click_hlight = __webpack_require__(40);
	var make_matrix_rows = __webpack_require__(41);

	module.exports = function (params, svg_elem) {
	  var network_data = params.network_data;

	  var matrix = [];
	  var clust_group;

	  // append a group that will hold clust_group and position it once
	  clust_group = svg_elem.append('g').attr('class', 'clust_container').attr('transform', 'translate(' + params.viz.clust.margin.left + ',' + params.viz.clust.margin.top + ')').append('g').attr('class', 'clust_group').classed('clust_group', true);

	  // clustergram background rect
	  clust_group.append('rect').classed('background', true).classed('grey_background', true).style('fill', '#eee').style('opacity', 0.25).attr('width', params.viz.clust.dim.width).attr('height', params.viz.clust.dim.height);

	  // pass in params and the rows (row_nodes) that need to be made
	  // in this case all row nodes
	  // make_matrix_rows(params, params.matrix.matrix, params.network_data.row_nodes_names);

	  // initialize at ds_level 0
	  if (params.viz.ds === null) {
	    // do not use downsampled matrix
	    make_matrix_rows(params, params.matrix.matrix, 'all', params.viz.ds_level);
	  } else {
	    // use downsampled matrix
	    make_matrix_rows(params, params.matrix.ds_matrix[0], 'all', params.viz.ds_level);
	  }

	  // add callback function to tile group - if one is supplied by the user
	  if (typeof params.click_tile === 'function') {
	    d3.selectAll(params.root + ' .tile').on('click', function (d) {

	      // export row/col name and value from tile
	      var tile_info = {};
	      tile_info.row = params.network_data.row_nodes[d.pos_y].name;
	      tile_info.col = params.network_data.col_nodes[d.pos_x].name;
	      tile_info.value = d.value;

	      if (utils.has(d, 'value_up')) {
	        tile_info.value_up = d.value_up;
	      }
	      if (utils.has(d, 'value_dn')) {
	        tile_info.value_dn = d.value_dn;
	      }
	      if (utils.has(d, 'info')) {
	        tile_info.info = d.info;
	      }
	      // run the user supplied callback function
	      params.click_tile(tile_info);
	      add_click_hlight(params, this);
	    });
	  } else {

	    // highlight clicked tile
	    if (params.tile_click_hlight) {
	      d3.selectAll(params.root + ' .tile').on('click', function () {
	        add_click_hlight(params, this);
	      });
	    }
	  }

	  // draw grid lines after drawing tiles
	  var delays = {};
	  var duration = 0;
	  delays.enter = 0;
	  draw_gridlines(params, delays, duration);

	  // Matrix API
	  return {
	    get_clust_group: function () {
	      return clust_group;
	    },
	    get_matrix: function () {
	      return matrix;
	    },
	    get_nodes: function (type) {
	      if (type === 'row') {
	        return network_data.row_nodes;
	      }
	      return network_data.col_nodes;
	    }
	  };
		};

/***/ },
/* 39 */
/***/ function(module, exports) {

	// var grid_lines_viz = require('./grid_lines_viz');
	// var toggle_grid_lines = require('./toggle_grid_lines');

	module.exports = function draw_gridlines(params, delays, duration) {

	  // var row_nodes = params.network_data.row_nodes;
	  // var col_nodes = params.network_data.col_nodes;

	  // // Fade in new gridlines
	  // ///////////////////////////

	  // // append horizontal line groups
	  // var horz_lines = d3.select(params.root+' .clust_group')
	  //   .selectAll('.horz_lines')
	  //   .data(row_nodes, function(d){return d.name;})
	  //   .enter()
	  //   .append('g')
	  //   .attr('class','horz_lines');

	  // // append vertical line groups
	  // var vert_lines = d3.select(params.root+' .clust_group')
	  //   .selectAll('.vert_lines')
	  //   .data(col_nodes)
	  //   .enter()
	  //   .append('g')
	  //   .attr('class', 'vert_lines');

	  // grid_lines_viz(params, duration);

	  // horz_lines
	  //   .select('line')
	  //   .attr('opacity',0)
	  //   .attr('stroke','white')
	  //   .attr('opacity', 1);

	  // vert_lines
	  //   .select('line')
	  //   .style('stroke', 'white')
	  //   .attr('opacity',0)
	  //   .transition().delay(delays.enter).duration(2*duration)
	  //   .attr('opacity', 1);

	  // toggle_grid_lines(params);

	};

/***/ },
/* 40 */
/***/ function(module, exports) {

	module.exports = function (params, clicked_rect) {

	  // get x position of rectangle
	  d3.select(clicked_rect).each(function (d) {
	    var pos_x = d.pos_x;
	    var pos_y = d.pos_y;

	    d3.selectAll(params.root + ' .click_hlight').remove();

	    if (pos_x != params.matrix.click_hlight_x || pos_y != params.matrix.click_hlight_y) {

	      // save pos_x to params.viz.click_hlight_x
	      params.matrix.click_hlight_x = pos_x;
	      params.matrix.click_hlight_y = pos_y;

	      // draw the highlighting rectangle as four rectangles
	      // so that the width and height can be controlled
	      // separately

	      var rel_width_hlight = 6;
	      var opacity_hlight = 0.85;

	      var hlight_width = rel_width_hlight * params.viz.border_width.x;
	      var hlight_height = rel_width_hlight * params.viz.border_width.y;

	      // top highlight
	      d3.select(clicked_rect.parentNode).append('rect').classed('click_hlight', true).classed('top_hlight', true).attr('width', params.viz.x_scale.rangeBand()).attr('height', hlight_height).attr('fill', params.matrix.hlight_color).attr('transform', function () {
	        return 'translate(' + params.viz.x_scale(pos_x) + ',0)';
	      }).attr('opacity', opacity_hlight);

	      // left highlight
	      d3.select(clicked_rect.parentNode)
						.append('rect')
						.classed('click_hlight', true)
						.classed('left_hlight', true)
						.attr('width', hlight_width)
						.attr('height', params.viz.y_scale.rangeBand() - hlight_height * 0.99)
						.attr('fill', params.matrix.hlight_color).attr('transform', function () {
	        			return "translate(" + params.viz.x_scale(pos_x) + "," + hlight_height * 0.99 + ")";
						})
						.attr('opacity', opacity_hlight);

	      // right highlight
	      d3.select(clicked_rect.parentNode).append('rect').classed('click_hlight', true).classed('right_hlight', true).attr('width', hlight_width).attr('height', params.viz.y_scale.rangeBand() - hlight_height * 0.99).attr('fill', params.matrix.hlight_color).attr('transform', function () {
	        var tmp_translate = params.viz.x_scale(pos_x) + params.viz.x_scale.rangeBand() - hlight_width;
	        return 'translate(' + tmp_translate + ',' + hlight_height * 0.99 + ')';
	      }).attr('opacity', opacity_hlight);

	      // bottom highlight
	      d3.select(clicked_rect.parentNode).append('rect').classed('click_hlight', true).classed('bottom_hlight', true).attr('width', function () {
	        return params.viz.x_scale.rangeBand() - 1.98 * hlight_width;
	      }).attr('height', hlight_height).attr('fill', params.matrix.hlight_color).attr('transform', function () {
	        var tmp_translate_x = params.viz.x_scale(pos_x) + hlight_width * 0.99;
	        var tmp_translate_y = params.viz.y_scale.rangeBand() - hlight_height;
	        return 'translate(' + tmp_translate_x + ',' + tmp_translate_y + ')';
	      }).attr('opacity', opacity_hlight);
	    } else {
	      params.matrix.click_hlight_x = -666;
	      params.matrix.click_hlight_y = -666;
	    }
	  });
	};

/***/ },
/* 41 */
/***/ function(module, exports, __webpack_require__) {

	var make_simple_rows = __webpack_require__(42);
	var d3_tip_custom = __webpack_require__(48);

	// current matrix can change with downsampling
	module.exports = function make_matrix_rows(params, current_matrix, row_names = 'all', ds_level = -1) {

	  // defaults
	  var y_scale = params.viz.y_scale;
	  var make_tip = true;
	  var row_class = 'row';

	  if (ds_level >= 0) {
	    y_scale = params.viz.ds[ds_level].y_scale;

	    // do not show tip when rows are downsampled
	    make_tip = false;
	    row_class = 'ds' + String(ds_level) + '_row';
	  }

	  if (make_tip) {

	    // do not remove tile_tip here
	    /////////////////////////////////

	    // make rows in the matrix - add key names to rows in matrix
	    /////////////////////////////////////////////////////////////
	    // d3-tooltip - for tiles
	    var tip = d3_tip_custom().attr('class', function () {
	      var root_tip_selector = params.viz.root_tips.replace('.', '');
	      var class_string = root_tip_selector + ' d3-tip ' + root_tip_selector + '_tile_tip';
	      return class_string;
	    }).style('display', 'none').direction('nw').offset([0, 0]).html(function (d) {
	      var inst_value = String(d.value.toFixed(3));
	      var tooltip_string;

	      if (params.keep_orig) {
	        var orig_value = String(d.value_orig.toFixed(3));
	        tooltip_string = '<p>' + d.row_name + ' and ' + d.col_name + '</p>' + '<p> normalized value: ' + inst_value + '</p>' + '<div> original value: ' + orig_value + '</div>';
	      } else {
	        tooltip_string = '<p>' + d.row_name + ' and ' + d.col_name + '</p>' + '<div> value: ' + inst_value + '</div>';
	      }

	      return tooltip_string;
	    });
	  } else {
	    tip = null;
	  }

	  // gather a subset of row data from the matrix or use all rows
	  var matrix_subset = [];
	  if (row_names === 'all') {
	    matrix_subset = current_matrix;
	  } else {
	    _.each(current_matrix, function (inst_row) {
	      if (_.contains(row_names, inst_row.name)) {
	        matrix_subset.push(inst_row);
	      }
	    });
	  }

	  d3.select(params.root + ' .clust_group').selectAll('.row').data(matrix_subset, function (d) {
	    return d.name;
	  }).enter().append('g').classed(row_class, true).attr('transform', function (d) {
	    return 'translate(0,' + y_scale(d.row_index) + ')';
	  }).each(function (d) {
	    make_simple_rows(params, d, tip, this, ds_level);
	  });

	  if (params.viz.ds_level === -1 && tip != null) {
	    d3.selectAll(params.root + ' .row').call(tip);
	  }
		};

/***/ },
/* 42 */
/***/ function(module, exports, __webpack_require__) {

	/* eslint-disable */

	var draw_up_tile = __webpack_require__(43);
	var draw_dn_tile = __webpack_require__(44);
	var mouseover_tile = __webpack_require__(45);
	var mouseout_tile = __webpack_require__(46);
	var fine_position_tile = __webpack_require__(47);

	module.exports = function make_simple_rows(params, inst_data, tip, row_selection, ds_level = -1) {

	  var inp_row_data = inst_data.row_data;

	  var make_tip = true;
	  var rect_height = params.viz.rect_height;
	  if (ds_level >= 0) {
	    // make_tip = false;
	    rect_height = params.viz.ds[ds_level].rect_height;
	  }

	  var keep_orig;
	  if (_.has(params.network_data.links[0], 'value_orig')) {
	    keep_orig = true;
	  } else {
	    keep_orig = false;
	  }

	  var row_values;
	  if (keep_orig === false) {
	    // value: remove zero values to make visualization faster
	    row_values = _.filter(inp_row_data, function (num) {
	      return num.value !== 0;
	    });
	  } else {
	    row_values = inp_row_data;
	  }

	  // generate tiles in the current row
	  var tile = d3.select(row_selection).selectAll('rect').data(row_values, function (d) {
	    return d.col_name;
	  }).enter().append('rect').attr('class', 'tile row_tile').attr('width', params.viz.rect_width).attr('height', rect_height).style('fill', function (d) {
	    // switch the color based on up/dn value
	    var inst_fill;
	    if (d.value_orig === 'NaN') {
	      inst_fill = '#000000';
	    } else {
	      inst_fill = d.value > params.matrix.mid_val ? params.matrix.tile_colors[0] : params.matrix.tile_colors[1];
	    }
	    return inst_fill;
	  }).style('fill-opacity', function (d) {
	    // calculate output opacity using the opacity scale
	    var inst_opacity;
	    if (d.value_orig === 'NaN') {
	      // console.log('found NaN while making tiles');
	      inst_opacity = 0.175;
	    } else {
				var op_val = params.matrix.mid_val + Math.abs(d.value - params.matrix.mid_val);

	      inst_opacity = params.matrix.opacity_scale(op_val);
	    }
	    return inst_opacity;
	  }).attr('transform', function (d) {
	    return fine_position_tile(params, d);
	  });

	  if (make_tip) {
	    tile.on('mouseover', function () {
	      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
	        args[_key] = arguments[_key];
	      }
	      mouseover_tile(params, this, tip, args);
	    }).on('mouseout', function () {
	      mouseout_tile(params, this, tip);
	    });
	  }

	  // // tile circles
	  // /////////////////////////////
	  // var tile = d3.select(row_selection)
	  //   .selectAll('circle')
	  //   .data(row_values, function(d){ return d.col_name; })
	  //   .enter()
	  //   .append('circle')
	  //   .attr('cx', params.viz.rect_height/2)
	  //   .attr('cy', params.viz.rect_height/2)
	  //   .attr('r', params.viz.rect_height/3)
	  //   .attr('class', 'tile_circle')
	  //   // .attr('width', params.viz.rect_width/2)
	  //   // .attr('height', params.viz.rect_height/2)
	  //   // // switch the color based on up/dn value
	  //   // .style('fill', function(d) {
	  //   //   // return d.value > 0 ? params.matrix.tile_colors[0] : params.matrix.tile_colors[1];
	  //   //   return 'black';
	  //   // })
	  //   .on('mouseover', function(...args) {
	  //       mouseover_tile(params, this, tip, args);
	  //   })
	  //   .on('mouseout', function() {
	  //     mouseout_tile(params, this, tip);
	  //   })
	  //   .style('fill-opacity', function(d) {
	  //     // calculate output opacity using the opacity scale
	  //     var output_opacity = params.matrix.opacity_scale(Math.abs(d.value));
	  //     if (output_opacity < 0.3){
	  //       output_opacity = 0;
	  //     } else if (output_opacity < 0.6){
	  //       output_opacity = 0.35;
	  //     } else {
	  //       output_opacity = 1;
	  //     }
	  //     return output_opacity;
	  //     // return 0.1;
	  //   })
	  //   .attr('transform', function(d) {
	  //     return fine_position_tile(params, d);
	  //   });


	  if (params.matrix.tile_type == 'updn') {

	    // value split
	    var row_split_data = _.filter(inp_row_data, function (num) {
	      return num.value_up != 0 || num.value_dn != 0;
	    });

	    // tile_up
	    d3.select(row_selection).selectAll('.tile_up').data(row_split_data, function (d) {
	      return d.col_name;
	    }).enter().append('path').attr('class', 'tile_up').attr('d', function () {
	      return draw_up_tile(params);
	    }).attr('transform', function (d) {
	      fine_position_tile(params, d);
	    }).style('fill', function () {
	      return params.matrix.tile_colors[0];
	    }).style('fill-opacity', function (d) {
	      var inst_opacity = 0;
	      if (Math.abs(d.value_dn) > 0) {
	        inst_opacity = params.matrix.opacity_scale(Math.abs(d.value_up));
	      }
	      return inst_opacity;
	    }).on('mouseover', function (...args) {
	      mouseover_tile(params, this, tip, args);
	    }).on('mouseout', function () {
	      mouseout_tile(params, this, tip);
	    });

	    // tile_dn
	    d3.select(row_selection).selectAll('.tile_dn').data(row_split_data, function (d) {
	      return d.col_name;
	    }).enter().append('path').attr('class', 'tile_dn').attr('d', function () {
	      return draw_dn_tile(params);
	    }).attr('transform', function (d) {
	      fine_position_tile(params, d);
	    }).style('fill', function () {
	      return params.matrix.tile_colors[1];
	    }).style('fill-opacity', function (d) {
	      var inst_opacity = 0;
	      if (Math.abs(d.value_up) > 0) {
	        inst_opacity = params.matrix.opacity_scale(Math.abs(d.value_dn));
	      }
	      return inst_opacity;
	    }).on('mouseover', function (...args) {
	      mouseover_tile(params, this, tip, args);
	    }).on('mouseout', function () {
	      mouseout_tile(params, this, tip);
	    });

	    // remove rect when tile is split
	    tile.each(function (d) {
	      if (Math.abs(d.value_up) > 0 && Math.abs(d.value_dn) > 0) {
	        d3.select(this).remove();
	      }
	    });
	  }

	  // append title to group
	  if (params.matrix.tile_title) {
	    tile.append('title').text(function (d) {
	      var inst_string = 'value: ' + d.value;
	      return inst_string;
	    });
	  }
		};

/***/ },
/* 43 */
/***/ function(module, exports) {

	module.exports = function draw_up_tile(params) {

	  var start_x = 0;
	  var final_x = params.viz.x_scale.rangeBand() - params.viz.border_width.x;
	  var start_y = 0;
	  var final_y = params.viz.y_scale.rangeBand() - params.viz.border_width.y;

	  var output_string = 'M' + start_x + ',' + start_y + ', L' + start_x + ', ' + final_y + ', L' + final_x + ',0 Z';

	  return output_string;
	};

/***/ },
/* 44 */
/***/ function(module, exports) {

	module.exports = function draw_dn_tile(params) {

	  var start_x = 0;
	  var final_x = params.viz.x_scale.rangeBand() - params.viz.border_width.x;
	  var start_y = params.viz.y_scale.rangeBand() - params.viz.border_width.y;
	  var final_y = params.viz.y_scale.rangeBand() - params.viz.border_width.y;

	  var output_string = 'M' + start_x + ', ' + start_y + ' ,   L' + final_x + ', ' + final_y + ',  L' + final_x + ',0 Z';

	  return output_string;
	};

/***/ },
/* 45 */
/***/ function(module, exports) {

	module.exports = function mouseover_tile(params, inst_selection, tip, inst_arguments) {

	  var inst_data = inst_arguments[0];
	  var args = [].slice.call(inst_arguments);
	  var timeout;
	  var delay = 1000;

	  d3.select(inst_selection).classed('hovering', true);

	  _.each(['row', 'col'], function (inst_rc) {

	    d3.selectAll(params.root + ' .' + inst_rc + '_label_group text').style('font-weight', function (d) {
	      var font_weight;
	      var inst_found = inst_data[inst_rc + '_name'].replace(/_/g, ' ') === d.name;

	      if (inst_found) {
	        font_weight = 'bold';
	      } else {
	        font_weight = 'normal';
	      }
	      return font_weight;
	    });
	  });

	  args.push(inst_selection);
	  clearTimeout(timeout);
	  timeout = setTimeout(check_if_hovering, delay, inst_selection);

	  function check_if_hovering() {

	    if (d3.select(inst_selection).classed('hovering')) {

	      var inst_zoom = Number(d3.select(params.root + ' .viz_svg').attr('is_zoom'));

	      if (inst_zoom === 0) {

	        if (params.matrix.show_tile_tooltips && tip !== null) {

	          d3.selectAll(params.viz.root_tips + '_tile_tip').style('display', 'block');

	          tip.show.apply(inst_selection, args);

	          if (params.tile_tip_callback != null) {
	            var tile_info = args[0];
	            params.tile_tip_callback(tile_info);
	          }
	        }
	      }
	    }
	  }
		};

/***/ },
/* 46 */
/***/ function(module, exports) {

	module.exports = function mouseout_tile(params, inst_selection, tip) {

	  d3.select(inst_selection).classed('hovering', false);

	  d3.selectAll(params.viz.root_tips + '_tile_tip').style('display', 'none');

	  _.each(['row', 'col'], function (inst_rc) {

	    d3.selectAll(params.root + ' .' + inst_rc + '_label_group text').style('font-weight', 'normal');
	  });

	  if (tip != null) {
	    tip.hide();
	  }
	};

/***/ },
/* 47 */
/***/ function(module, exports) {

	module.exports = function fine_position_tile(params, d) {

	  var offset_x;

	  // prevent rows not in x_scale domain from causing errors
	  if (d.pos_x in params.viz.x_scale.domain()) {
	    offset_x = params.viz.x_scale(d.pos_x);
	  } else {
	    offset_x = 0;
	  }

	  var x_pos = offset_x + 0.5 * params.viz.border_width.x;
	  var y_pos = 0.5 * params.viz.border_width.y;
	  return 'translate(' + x_pos + ',' + y_pos + ')';
	};

/***/ },
/* 48 */
/***/ function(module, exports) {

	module.exports = function d3_tip_custom() {
	  /* eslint-disable */
	  // Copyright (c) 2013 Justin Palmer
	  //
	  // Tooltips for d3.js SVG visualizations

	  // Public - contructs a new tooltip
	  //
	  // Returns a tip
	  // ******************
	  // Nick Fernandez modified version 4-19-2016
	  // improved multiple svg, scrolling+zooming support
	  // made syntax fixes
	  //////////////////////////////////////////////
	  var direction = d3_tip_direction,
	      offset = d3_tip_offset,
	      html = d3_tip_html,
	      node = initNode(),
	      svg = null,
	      point = null,
	      target = null;

	  function tip(vis) {
	    svg = getSVGNode(vis);
	    point = svg.createSVGPoint();
	    document.body.appendChild(node);
	  }

	  // Public - show the tooltip on the screen
	  //
	  // Returns a tip
	  tip.show = function () {

	    var args = Array.prototype.slice.call(arguments);
	    if (args[args.length - 1] instanceof SVGElement) {
	      target = args.pop();
	    }

	    var content = html.apply(this, args);
	    var poffset = offset.apply(this, args);
	    var dir = direction.apply(this, args);
	    var nodel = d3.select(node);
	    var i = 0;
	    var coords;

	    // add z-index to make sure tooltips appear on top
	    nodel.html(content).style({ opacity: 1, 'pointer-events': 'all' }).style('z-index', 99);

	    while (i--) {
	      nodel.classed(directions[i], false);
	    }
	    coords = direction_callbacks.get(dir).apply(this);
	    nodel.classed(dir, true).style({
	      top: coords.top + poffset[0] + 'px',
	      left: coords.left + poffset[1] + 'px'
	    });

	    // quick fix for fading tile tooltips
	    if (isFunction(this) === false) {

	      var inst_class = d3.select(this).attr('class');

	      if (inst_class.indexOf('tile') >= 0) {
	        setTimeout(fade_tips, 5000, this);
	      }
	    }

	    return tip;
	  };

	  // Public - hide the tooltip
	  //
	  // Returns a tip
	  tip.hide = function () {

	    // // hide all d3-tip tooltips
	    // d3.selectAll('.d3-tip')
	    //   .style('display', 'none');

	    var nodel = d3.select(node);
	    nodel.style({ opacity: 0, 'pointer-events': 'none' });
	    return tip;
	  };

	  // Public: Proxy attr calls to the d3 tip container.  Sets or gets attribute value.
	  //
	  // n - name of the attribute
	  // v - value of the attribute
	  //
	  // Returns tip or attribute value
	  tip.attr = function (n) {
	    if (arguments.length < 2 && typeof n === 'string') {
	      return d3.select(node).attr(n);
	    } else {
	      var args = Array.prototype.slice.call(arguments);
	      d3.selection.prototype.attr.apply(d3.select(node), args);
	    }

	    return tip;
	  };

	  // Public: Proxy style calls to the d3 tip container.  Sets or gets a style value.
	  //
	  // n - name of the property
	  // v - value of the property
	  //
	  // Returns tip or style property value
	  tip.style = function (n) {
	    if (arguments.length < 2 && typeof n === 'string') {
	      return d3.select(node).style(n);
	    } else {
	      var args = Array.prototype.slice.call(arguments);
	      d3.selection.prototype.style.apply(d3.select(node), args);
	    }

	    return tip;
	  };

	  // Public: Set or get the direction of the tooltip
	  //
	  // v - One of n(north), s(south), e(east), or w(west), nw(northwest),
	  //     sw(southwest), ne(northeast) or se(southeast)
	  //
	  // Returns tip or direction
	  tip.direction = function (v) {
	    if (!arguments.length) {
	      return direction;
	    }
	    direction = v == null ? v : d3.functor(v);

	    return tip;
	  };

	  // Public: Sets or gets the offset of the tip
	  //
	  // v - Array of [x, y] offset
	  //
	  // Returns offset or
	  tip.offset = function (v) {
	    if (!arguments.length) {
	      return offset;
	    }
	    offset = v == null ? v : d3.functor(v);

	    return tip;
	  };

	  // Public: sets or gets the html value of the tooltip
	  //
	  // v - String value of the tip
	  //
	  // Returns html value or tip
	  tip.html = function (v) {
	    if (!arguments.length) {
	      return html;
	    }
	    html = v == null ? v : d3.functor(v);

	    return tip;
	  };

	  function d3_tip_direction() {
	    return 'n';
	  }
	  function d3_tip_offset() {
	    return [0, 0];
	  }
	  function d3_tip_html() {
	    return ' ';
	  }

	  var direction_callbacks = d3.map({
	    n: direction_n,
	    s: direction_s,
	    e: direction_e,
	    w: direction_w,
	    nw: direction_nw,
	    ne: direction_ne,
	    sw: direction_sw,
	    se: direction_se,
	    south_custom: direction_south_custom
	  }),
	      directions = direction_callbacks.keys();

	  function direction_south_custom() {
	    var bbox = getScreenBBox();

	    return {
	      top: bbox.s.y,
	      left: bbox.s.x
	    };
	  }

	  function direction_n() {
	    var bbox = getScreenBBox();
	    return {
	      top: bbox.n.y - node.offsetHeight,
	      left: bbox.n.x - node.offsetWidth / 2
	    };
	  }

	  function direction_s() {
	    var bbox = getScreenBBox();
	    return {
	      top: bbox.s.y,
	      left: bbox.s.x - node.offsetWidth / 2
	    };
	  }

	  function direction_e() {
	    var bbox = getScreenBBox();
	    return {
	      top: bbox.e.y - node.offsetHeight / 2,
	      left: bbox.e.x
	    };
	  }

	  function direction_w() {
	    var bbox = getScreenBBox();
	    return {
	      top: bbox.w.y - node.offsetHeight / 2,
	      left: bbox.w.x - node.offsetWidth
	    };
	  }

	  function direction_nw() {
	    var bbox = getScreenBBox();
	    return {
	      top: bbox.nw.y - node.offsetHeight,
	      left: bbox.nw.x - node.offsetWidth
	    };
	  }

	  function direction_ne() {
	    var bbox = getScreenBBox();
	    return {
	      top: bbox.ne.y - node.offsetHeight,
	      left: bbox.ne.x
	    };
	  }

	  function direction_sw() {
	    var bbox = getScreenBBox();
	    return {
	      top: bbox.sw.y,
	      left: bbox.sw.x - node.offsetWidth
	    };
	  }

	  function direction_se() {
	    var bbox = getScreenBBox();
	    return {
	      top: bbox.se.y,
	      left: bbox.e.x
	    };
	  }

	  function initNode() {
	    var node = d3.select(document.createElement('div'));
	    node.style({
	      position: 'absolute',
	      opacity: 0,
	      pointerEvents: 'none',
	      boxSizing: 'border-box'
	    });

	    return node.node();
	  }

	  function getSVGNode(el) {
	    el = el.node();
	    if (el.tagName.toLowerCase() == 'svg') {
	      return el;
	    }

	    return el.ownerSVGElement;
	  }

	  // Private - gets the screen coordinates of a shape
	  //
	  // Given a shape on the screen, will return an SVGPoint for the directions
	  // n(north), s(south), e(east), w(west), ne(northeast), se(southeast), nw(northwest),
	  // sw(southwest).
	  //
	  //    +-+-+
	  //    |   |
	  //    +   +
	  //    |   |
	  //    +-+-+
	  //
	  // Returns an Object {n, s, e, w, nw, sw, ne, se}
	  function getScreenBBox() {
	    var targetel = target || d3.event.target;
	    var bbox = {};
	    var matrix = targetel.getScreenCTM();
	    var tbbox = targetel.getBBox();
	    var width = tbbox.width;
	    var height = tbbox.height;
	    var x = tbbox.x;
	    var y = tbbox.y;
	    var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
	    var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;

	    // Nick - prevents bugs with scrolling and zooming on the same object
	    matrix.a = 1;
	    matrix.d = 1;
	    // changing order of adding scrolling,
	    // original ordering was causing problems with pre-translated or rotated
	    // elements.
	    matrix.e = matrix.e + scrollLeft;
	    matrix.f = matrix.f + scrollTop;
	    point.x = x; //+ scrollLeft
	    point.y = y; //+ scrollTop

	    bbox.nw = point.matrixTransform(matrix);
	    point.x = point.x + width;
	    bbox.ne = point.matrixTransform(matrix);
	    point.y = point.y + height;
	    bbox.se = point.matrixTransform(matrix);
	    point.x = point.x - width;
	    bbox.sw = point.matrixTransform(matrix);
	    point.y = point.y - height / 2;
	    bbox.w = point.matrixTransform(matrix);
	    point.x = point.x + width;
	    bbox.e = point.matrixTransform(matrix);
	    point.x = point.x - width / 2;
	    point.y = point.y - height / 2;
	    bbox.n = point.matrixTransform(matrix);
	    point.y = point.y + height;
	    bbox.s = point.matrixTransform(matrix);

	    return bbox;
	  }

	  // only fade tips if you are still hovering on the current tip
	  function fade_tips(inst_selection) {

	    var is_hovering = d3.select(inst_selection).classed('hovering');

	    if (is_hovering) {
	      d3.selectAll('.d3-tip').transition().duration(250).style('opacity', 0).style('display', 'none');
	    }
	  }

	  function isFunction(functionToCheck) {
	    var getType = {};
	    return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
	  }

	  return tip;
	};

/***/ },
/* 49 */
/***/ function(module, exports, __webpack_require__) {

	var make_row_labels = __webpack_require__(50);

	module.exports = function make_row_label_container(cgm, text_delay) {

	  var params = cgm.params;

	  var row_container;

	  // row container holds all row text and row visualizations (triangles rects)
	  ////////////////////////////////////////////////////////////////////////////
	  if (d3.select(params.viz.viz_svg + ' .row_container').empty()) {
	    row_container = d3.select(params.viz.viz_svg).append('g').classed('row_container', true).attr('transform', 'translate(' + params.viz.norm_labels.margin.left + ',' + params.viz.clust.margin.top + ')');
	  } else {
	    row_container = d3.select(params.viz.viz_svg).select('.row_container').attr('transform', 'translate(' + params.viz.norm_labels.margin.left + ',' + params.viz.clust.margin.top + ')');
	  }

	  if (d3.select(params.root + ' .row_white_background').empty()) {
	    row_container.append('rect').classed('row_white_background', true).classed('white_bars', true).attr('fill', params.viz.background_color).attr('width', params.viz.label_background.row).attr('height', 30 * params.viz.clust.dim.height + 'px');
	  }

	  // add container to hold text row labels if not already there
	  if (d3.select(params.root + ' .row_label_container').empty()) {
	    row_container.append('g').classed('row_label_container', true).attr('transform', 'translate(' + params.viz.norm_labels.width.row + ',0)').append('g').classed('row_label_zoom_container', true);
	  } else {
	    row_container.select(params.root + ' .row_label_container').attr('transform', 'translate(' + params.viz.norm_labels.width.row + ',0)');
	  }

	  // make row labels in the container
	  ///////////////////////////////////////
	  if (params.viz.ds_level === -1) {
	    make_row_labels(cgm, 'all', text_delay);
	  }
		};

/***/ },
/* 50 */
/***/ function(module, exports, __webpack_require__) {

	var utils = __webpack_require__(2);
	var add_row_click_hlight = __webpack_require__(51);
	var row_reorder = __webpack_require__(52);
	var make_row_tooltips = __webpack_require__(102);

	module.exports = function make_row_labels(cgm, row_names = 'all', text_delay = 0) {

	  // console.log('make_row_labels')
	  // console.log(row_names)

	  var params = cgm.params;
	  var row_nodes = [];

	  if (row_names === 'all') {
	    row_nodes = params.network_data.row_nodes;
	  } else {
	    _.each(params.network_data.row_nodes, function (inst_row) {
	      if (_.contains(row_names, inst_row.name)) {
	        row_nodes.push(inst_row);
	      }
	    });
	  }

	  // make row labels in row_label_zoom_container, bind row_nodes data
	  var row_labels = d3.select(params.root + ' .row_label_zoom_container').selectAll('g').data(row_nodes, function (d) {
	    return d.name;
	  }).enter().append('g').classed('row_label_group', true);

	  var row_nodes_names = params.network_data.row_nodes_names;
	  row_labels.attr('transform', function (d) {
	    // var inst_index = d.row_index;
	    var inst_index = _.indexOf(row_nodes_names, d.name);
	    return 'translate(0,' + params.viz.y_scale(inst_index) + ')';
	  });

	  row_labels.on('dblclick', function (d) {

	    var data_attr = '__data__';
	    var row_name = this[data_attr].name;

	    // if (params.sim_mat){
	    //   row_reorder(cgm, this, row_name);

	    //   d3.selectAll(params.root+' .col_label_text')
	    //     .filter(function(d){
	    //       return d.name == row_name;}
	    //       )[0][0];

	    //   // this is causing buggyness may reenable
	    //   // col_reorder -> two_translate_zoom -> show_visible_area -> make_row_labels -> col_reorder
	    //   // col_reorder(cgm, col_selection, row_name);

	    // } else {
	    //   row_reorder(cgm, this, row_name);
	    // }

	    row_reorder(cgm, this, row_name);

	    if (params.tile_click_hlight) {
	      add_row_click_hlight(this, d.ini);
	    }
	  });

	  make_row_tooltips(params);

	  // append rectangle behind text
	  row_labels.insert('rect').style('opacity', 0);

	  // append row label text
	  row_labels.append('text').attr('y', params.viz.rect_height * 0.5 + params.labels.default_fs_row * 0.35).attr('text-anchor', 'end').style('font-size', params.labels.default_fs_row + 'px').text(function (d) {
	    return utils.normal_name(d);
	  }).attr('pointer-events', 'none').style('opacity', 0).style('cursor', 'default').transition().delay(text_delay).duration(text_delay).style('opacity', 1);

	  // change the size of the highlighting rects
	  row_labels.each(function () {
	    var bbox = d3.select(this).select('text')[0][0].getBBox();
	    d3.select(this).select('rect').attr('x', bbox.x).attr('y', 0).attr('width', bbox.width).attr('height', params.viz.y_scale.rangeBand()).style('fill', function () {
	      var inst_hl = 'yellow';
	      return inst_hl;
	    }).style('opacity', function (d) {
	      var inst_opacity = 0;
	      // highlight target genes
	      if (d.target === 1) {
	        inst_opacity = 1;
	      }
	      return inst_opacity;
	    });
	  });

	  // almost-deprecated row value bars
	  ///////////////////////////////
	  if (utils.has(params.network_data.row_nodes[0], 'value')) {

	    row_labels.append('rect').classed('row_bars', true).attr('width', function (d) {
	      var inst_value = 0;
	      inst_value = params.labels.bar_scale_row(Math.abs(d.value));
	      return inst_value;
	    }).attr('x', function (d) {
	      var inst_value = 0;
	      inst_value = -params.labels.bar_scale_row(Math.abs(d.value));
	      return inst_value;
	    }).attr('height', params.viz.y_scale.rangeBand()).attr('fill', function (d) {
	      return d.value > 0 ? params.matrix.bar_colors[0] : params.matrix.bar_colors[1];
	    }).attr('opacity', 0.4);
	  }
		};

/***/ },
/* 51 */
/***/ function(module, exports) {

	module.exports = function (params, clicked_row, id_clicked_row) {
	  if (id_clicked_row != params.click_hlight_row) {

	    var rel_width_hlight = 6;
	    var opacity_hlight = 0.85;
	    var hlight_height = rel_width_hlight * params.viz.border_width.x;

	    d3.selectAll(params.root + ' .click_hlight').remove();

	    // // highlight selected row
	    // d3.selectAll(params.root+' .row_label_group')
	    //   .select('rect')
	    // d3.select(this)
	    //   .select('rect')
	    //   .style('opacity', 1);

	    d3.select(clicked_row).append('rect').classed('click_hlight', true).classed('row_top_hlight', true).attr('width', params.viz.svg_dim.width).attr('height', hlight_height).attr('fill', params.matrix.hlight_color).attr('opacity', opacity_hlight);

	    d3.select(clicked_row).append('rect').classed('click_hlight', true).classed('row_bottom_hlight', true).attr('width', params.viz.svg_dim.width).attr('height', hlight_height).attr('fill', params.matrix.hlight_color).attr('opacity', opacity_hlight).attr('transform', function () {
	      var tmp_translate_y = params.viz.y_scale.rangeBand() - hlight_height;
	      return 'translate(0,' + tmp_translate_y + ')';
	    });
	  } else {
	    d3.selectAll(params.root + ' .click_hlight').remove();
	    params.click_hlight_row = -666;
	  }
		};

/***/ },
/* 52 */
/***/ function(module, exports, __webpack_require__) {

	var reposition_tile_highlight = __webpack_require__(53);
	var toggle_dendro_view = __webpack_require__(54);
	var ini_zoom_info = __webpack_require__(36);
	var get_previous_zoom = __webpack_require__(101);
	var calc_downsampled_levels = __webpack_require__(27);

	module.exports = function row_reorder(cgm, row_selection, inst_row) {

	  var params = cgm.params;
	  var prev_zoom = get_previous_zoom(params);

	  if (prev_zoom.zoom_y === 1 && prev_zoom.zoom_x === 1) {

	    params.viz.inst_order.row = 'custom';
	    toggle_dendro_view(cgm, 'col');

	    d3.selectAll(params.root + ' .toggle_col_order .btn').classed('active', false);

	    params.viz.run_trans = true;

	    var mat = $.extend(true, {}, params.matrix.matrix);
	    var row_nodes = params.network_data.row_nodes;
	    var col_nodes = params.network_data.col_nodes;

	    // find the index of the row
	    var tmp_arr = [];
	    row_nodes.forEach(function (node) {
	      tmp_arr.push(node.name);
	    });

	    // find index
	    inst_row = _.indexOf(tmp_arr, inst_row);

	    // gather the values of the input genes
	    tmp_arr = [];
	    col_nodes.forEach(function (node, index) {
	      tmp_arr.push(mat[inst_row].row_data[index].value);
	    });

	    // sort the rows
	    var tmp_sort = d3.range(tmp_arr.length).sort(function (a, b) {
	      return tmp_arr[b] - tmp_arr[a];
	    });

	    // resort cols (cols are reorderd by double clicking a row)
	    params.viz.x_scale.domain(tmp_sort);

	    // save to custom col order
	    params.matrix.orders.custom_row = tmp_sort;

	    // reorder matrix
	    ////////////////////
	    var t;
	    if (params.network_data.links.length > params.matrix.def_large_matrix) {
	      t = d3.select(params.root + ' .viz_svg');
	    } else {
	      t = d3.select(params.root + ' .viz_svg').transition().duration(2500);
	    }

	    var col_nodes_names = params.network_data.col_nodes_names;

	    // Move Col Labels
	    t.select('.col_zoom_container').selectAll('.col_label_text').attr('transform', function (d) {
	      var inst_index = _.indexOf(col_nodes_names, d.name);
	      return 'translate(' + params.viz.x_scale(inst_index) + ')rotate(-90)';
	    });

	    // reorder col_class groups
	    t.selectAll('.col_cat_group').attr('transform', function (d) {
	      var inst_index = _.indexOf(col_nodes_names, d.name);
	      return 'translate(' + params.viz.x_scale(inst_index) + ',0)';
	    });

	    // reorder tiles in matrix (do not change row order)
	    if (params.viz.ds_level === -1) {
	      t.selectAll('.tile').attr('transform', function (d) {
	        return 'translate(' + params.viz.x_scale(d.pos_x) + ',0)';
	      });

	      t.selectAll('.tile_up').attr('transform', function (d) {
	        return 'translate(' + params.viz.x_scale(d.pos_x) + ',0)';
	      });

	      t.selectAll('.tile_dn').attr('transform', function (d) {
	        return 'translate(' + params.viz.x_scale(d.pos_x) + ',0)';
	      });
	    }

	    // highlight selected row
	    ///////////////////////////////
	    // unhilight and unbold all columns (already unbolded earlier)
	    d3.selectAll(params.root + ' .row_label_group').select('rect').style('opacity', 0);
	    // highlight column name
	    d3.select(row_selection).select('rect').style('opacity', 1);

	    reposition_tile_highlight(params);

	    // redefine x and y positions
	    params.network_data.links.forEach(function (d) {
	      d.x = params.viz.x_scale(d.target);
	      d.y = params.viz.y_scale(d.source);
	    });

	    params.zoom_info = ini_zoom_info();

	    setTimeout(function () {
	      params.viz.run_trans = false;
	    }, 2500);

	    // calculate downsmapling if necessary
	    if (params.viz.ds_num_levels > 0 && params.viz.ds_level >= 0) {

	      calc_downsampled_levels(params);

	      // var zooming_stopped = true;
	      // var zooming_out = true;
	      // var make_all_rows = true;
	      // // show_visible_area is also run with two_translate_zoom, but at that point
	      // // the parameters were not updated and two_translate_zoom if only run
	      // // if needed to reset zoom
	      // show_visible_area(cgm, zooming_stopped, zooming_out, make_all_rows);
	    }
	  }
		};

/***/ },
/* 53 */
/***/ function(module, exports) {

	module.exports = function (params) {

	  // resize click hlight
	  var rel_width_hlight = 6;
	  // var opacity_hlight = 0.85;

	  var hlight_width = rel_width_hlight * params.viz.border_width.x;
	  var hlight_height = rel_width_hlight * params.viz.border_width.y;

	  // reposition tile highlight
	  ////////////////////////////////
	  // top highlight
	  d3.select(params.root + ' .top_hlight').attr('width', params.viz.x_scale.rangeBand()).attr('height', hlight_height).transition().duration(2500).attr('transform', function () {
	    return 'translate(' + params.viz.x_scale(params.matrix.click_hlight_x) + ',0)';
	  });

	  // left highlight
	  d3.select(params.root + ' .left_hlight').attr('width', hlight_width).attr('height', params.viz.y_scale.rangeBand() - hlight_height * 0.99).transition().duration(2500).attr('transform', function () {
	    return 'translate(' + params.viz.x_scale(params.matrix.click_hlight_x) + ',' + hlight_height * 0.99 + ')';
	  });

	  // right highlight
	  d3.select(params.root + ' .right_hlight').attr('width', hlight_width).attr('height', params.viz.y_scale.rangeBand() - hlight_height * 0.99).transition().duration(2500).attr('transform', function () {
	    var tmp_translate = params.viz.x_scale(params.matrix.click_hlight_x) + params.viz.x_scale.rangeBand() - hlight_width;
	    return 'translate(' + tmp_translate + ',' + hlight_height * 0.99 + ')';
	  });

	  // bottom highlight
	  d3.select(params.root + ' .bottom_hlight').attr('width', function () {
	    return params.viz.x_scale.rangeBand() - 1.98 * hlight_width;
	  }).attr('height', hlight_height).transition().duration(2500).attr('transform', function () {
	    var tmp_translate_x = params.viz.x_scale(params.matrix.click_hlight_x) + hlight_width * 0.99;
	    var tmp_translate_y = params.viz.y_scale.rangeBand() - hlight_height;
	    return 'translate(' + tmp_translate_x + ',' + tmp_translate_y + ')';
	  });
		};

/***/ },
/* 54 */
/***/ function(module, exports, __webpack_require__) {

	var make_dendro_triangles = __webpack_require__(55);

	module.exports = function toggle_dendro_view(cgm, inst_rc, wait_time = 1500) {

	  var params = cgm.params;

	  // row and col are reversed
	  if (inst_rc === 'row') {
	    if (params.viz.inst_order.col === 'clust') {
	      // the last true tells the viz that I'm chaning group size and not to
	      // delay the change in dendro
	      setTimeout(make_dendro_triangles, wait_time, cgm, 'row', true);
	    }
	  }

	  if (inst_rc === 'col') {
	    if (params.viz.inst_order.row === 'clust') {
	      setTimeout(make_dendro_triangles, wait_time, cgm, 'col', true);
	    }
	  }

	  if (params.viz.inst_order.row != 'clust' && params.viz.dendro_filter.col === false) {
	    d3.selectAll(params.root + ' .col_dendro_group').style('opacity', 0).on('mouseover', null).on('mouseout', null);

	    d3.select(params.root + ' .col_slider_group').style('opacity', 0);

	    // toggle crop buttons
	    d3.selectAll(params.root + ' .col_dendro_crop_buttons').style('opacity', 0).on('mouseover', null).on('mouseout', null);
	  }

	  if (params.viz.inst_order.col != 'clust' && params.viz.dendro_filter.row === false) {

	    d3.selectAll(params.root + ' .row_dendro_group').style('opacity', 0).on('mouseover', null).on('mouseout', null).on('click', null);

	    d3.select(params.root + ' .row_slider_group').style('opacity', 0);

	    // toggle crop buttons
	    d3.selectAll(params.root + ' .row_dendro_crop_buttons').style('opacity', 0).on('mouseover', null).on('mouseout', null);
	  }
	};

/***/ },
/* 55 */
/***/ function(module, exports, __webpack_require__) {

	var calc_row_dendro_triangles = __webpack_require__(56);
	var calc_col_dendro_triangles = __webpack_require__(57);
	var dendro_group_highlight = __webpack_require__(58);
	var d3_tip_custom = __webpack_require__(48);
	var make_dendro_crop_buttons = __webpack_require__(60);
	var make_cat_breakdown_graph = __webpack_require__(63);

	module.exports = function make_dendro_triangles(cgm, inst_rc, is_change_group = false) {

	  var params = cgm.params;

	  // in case sim_mat
	  if (inst_rc === 'both') {
	    inst_rc = 'row';
	  }

	  var other_rc;
	  if (inst_rc === 'row') {
	    other_rc = 'col';
	  } else {
	    other_rc = 'row';
	  }

	  // orders are switched!
	  if (params.viz.inst_order[other_rc] === 'clust') {
	    d3.select(params.root + ' .' + inst_rc + '_slider_group').style('opacity', 1);
	  }

	  var dendro_info;

	  if (inst_rc === 'row') {
	    dendro_info = calc_row_dendro_triangles(params);
	  } else {
	    dendro_info = calc_col_dendro_triangles(params);
	  }

	  if (d3.select(cgm.params.root + ' .' + inst_rc + '_dendro_crop_buttons').empty() === false) {
	    make_dendro_crop_buttons(cgm, inst_rc);
	  }

	  // constant dendrogram opacity
	  var inst_dendro_opacity = params.viz.dendro_opacity;

	  function still_hovering(inst_selection, inst_data, i) {

	    if (d3.select(inst_selection).classed('hovering')) {

	      // define where graph should be built
	      var inst_selector = params.viz.root_tips + '_' + inst_rc + '_dendro_tip';

	      // prevent mouseover from making multiple graphs
	      if (d3.select(inst_selector + ' .cat_graph').empty()) {

	        if (params.viz.cat_info[inst_rc] !== null) {
	          make_cat_breakdown_graph(params, inst_rc, inst_data, dendro_info[i], inst_selector, true);
	        }
	      }

	      d3.selectAll(params.viz.root_tips + '_' + inst_rc + '_dendro_tip').style('opacity', 1);
	    }
	  }

	  var wait_before_tooltip = 500;

	  // remove any old dendro tooltips from this visualization
	  d3.selectAll(cgm.params.viz.root_tips + '_' + inst_rc + '_dendro_tip').remove();

	  // run transition rules
	  var run_transition;
	  if (d3.selectAll(params.root + ' .' + inst_rc + '_dendro_group').empty()) {
	    run_transition = false;
	  } else {
	    run_transition = true;
	    d3.selectAll(params.root + ' .' + inst_rc + '_dendro_group').remove();
	    // d3.selectAll(params.root+' .dendro_tip').remove();
	  }

	  // d3-tooltip
	  var tmp_y_offset = 0;
	  var tmp_x_offset = -5;
	  var dendro_tip = d3_tip_custom().attr('class', function () {
	    // add root element to class
	    var root_tip_selector = params.viz.root_tips.replace('.', '');
	    var class_string = root_tip_selector + ' d3-tip ' + root_tip_selector + '_' + inst_rc + '_dendro_tip';

	    return class_string;
	  }).direction('nw').offset([tmp_y_offset, tmp_x_offset]).style('display', 'none').style('opacity', 0);

	  dendro_tip.html(function () {
	    var full_string = '<div class="cluster_info_container"></div>Click for cluster information <br>' + 'and additional options.';
	    return full_string;
	  });

	  if (is_change_group) {
	    run_transition = false;
	  }

	  var dendro_traps = d3.select(params.root + ' .' + inst_rc + '_dendro_container').selectAll('path').data(dendro_info, function (d) {
	    return d.name;
	  }).enter().append('path').style('opacity', 0).attr('class', inst_rc + '_dendro_group').style('fill', 'black');

	  // draw triangles (shown as trapezoids)
	  //////////////////////////////////////////
	  var start_x;
	  var start_y;
	  var mid_x;
	  var mid_y;
	  var final_x;
	  var final_y;

	  // row triangles
	  dendro_traps.attr('d', function (d) {

	    if (inst_rc === 'row') {
	      // row triangles
	      start_x = 0;
	      start_y = d.pos_top;
	      mid_x = 30;
	      mid_y = d.pos_mid;
	      final_x = 0;
	      final_y = d.pos_bot;
	    } else {
	      // column triangles
	      start_x = d.pos_top;
	      start_y = 0;
	      mid_x = d.pos_mid;
	      mid_y = 30;
	      final_x = d.pos_bot;
	      final_y = 0;
	    }

	    var output_string = 'M' + start_x + ',' + start_y + ', L' + mid_x + ', ' + mid_y + ', L' + final_x + ',' + final_y + ' Z';
	    return output_string;
	  });

	  dendro_traps.on('mouseover', function (d, i) {

	    // if (params.sim_mat){
	    //   inst_rc = 'both';
	    // }

	    // run instantly on mouseover
	    d3.select(this).classed('hovering', true);

	    if (cgm.params.dendro_callback != null) {
	      cgm.params.dendro_callback(this);
	    }

	    // display tip
	    // this is needed for it to show in the right place and the opacity
	    // will be toggled to delay the tooltip for the user
	    d3.select(params.viz.root_tips + '_' + inst_rc + '_dendro_tip').style('display', 'block');

	    dendro_group_highlight(params, this, d, inst_rc);

	    // show the tip (make sure it is displaying before it is shown)
	    dendro_tip.show(d);

	    // set opacity to zero
	    d3.select(params.viz.root_tips + '_' + inst_rc + '_dendro_tip').style('opacity', 0);

	    // check if still hovering
	    setTimeout(still_hovering, wait_before_tooltip, this, d, i);
	  }).on('mouseout', function () {
	    if (params.viz.inst_order[other_rc] === 'clust') {
	      d3.select(this).style('opacity', inst_dendro_opacity);
	    }

	    d3.selectAll(params.root + ' .dendro_shadow').remove();

	    d3.select(this).classed('hovering', false);
	    dendro_tip.hide(this);
	  }).on('click', function (d, i) {

	    $(params.root + ' .dendro_info').modal('toggle');

	    var group_string = d.all_names.join(', ');
	    d3.select(params.root + ' .dendro_info input').attr('value', group_string);

	    var inst_selector = params.root + ' .dendro_info';

	    // remove old graphs (modals are not within params.root)
	    d3.selectAll('.dendro_info .cluster_info_container .cat_graph').remove();

	    if (params.viz.cat_info[inst_rc] !== null) {
	      make_cat_breakdown_graph(params, inst_rc, d, dendro_info[i], inst_selector);
	    }

	    if (cgm.params.dendro_click_callback != null) {
	      cgm.params.dendro_click_callback(this);
	    }
	  }).call(dendro_tip);

	  var triangle_opacity;
	  if (params.viz.inst_order[other_rc] === 'clust') {
	    triangle_opacity = inst_dendro_opacity;
	  } else {
	    triangle_opacity = 0;
	  }

	  if (run_transition) {

	    d3.select(params.root + ' .' + inst_rc + '_dendro_container').selectAll('path').transition().delay(1000).duration(1000).style('opacity', triangle_opacity);
	  } else {

	    d3.select(params.root + ' .' + inst_rc + '_dendro_container').selectAll('path').style('opacity', triangle_opacity);
	  }
		};

/***/ },
/* 56 */
/***/ function(module, exports) {

	module.exports = function calc_row_dendro_triangles(params) {

	  var triangle_info = {};
	  var inst_level = params.group_level.row;
	  var row_nodes = params.network_data.row_nodes;
	  var row_nodes_names = params.network_data.row_nodes_names;

	  _.each(row_nodes, function (d) {

	    // console.log('row_node '+d.name)

	    var tmp_group = d.group[inst_level];
	    var inst_index = _.indexOf(row_nodes_names, d.name);
	    var inst_top = params.viz.y_scale(inst_index);
	    var inst_bot = inst_top + params.viz.y_scale.rangeBand();

	    if (_.has(triangle_info, tmp_group) === false) {
	      triangle_info[tmp_group] = {};
	      triangle_info[tmp_group].name_top = d.name;
	      triangle_info[tmp_group].name_bot = d.name;
	      triangle_info[tmp_group].pos_top = inst_top;
	      triangle_info[tmp_group].pos_bot = inst_bot;
	      triangle_info[tmp_group].pos_mid = (inst_top + inst_bot) / 2;
	      triangle_info[tmp_group].name = tmp_group;
	      triangle_info[tmp_group].all_names = [];
	      triangle_info[tmp_group].inst_rc = 'row';
	    }

	    triangle_info[tmp_group].all_names.push(d.name);

	    if (inst_top < triangle_info[tmp_group].pos_top) {
	      triangle_info[tmp_group].name_top = d.name;
	      triangle_info[tmp_group].pos_top = inst_top;
	      triangle_info[tmp_group].pos_mid = (inst_top + triangle_info[tmp_group].pos_bot) / 2;
	    }

	    if (inst_bot > triangle_info[tmp_group].pos_bot) {
	      triangle_info[tmp_group].name_bot = d.name;
	      triangle_info[tmp_group].pos_bot = inst_bot;
	      triangle_info[tmp_group].pos_mid = (triangle_info[tmp_group].pos_top + inst_bot) / 2;
	    }
	  });

	  var group_info = [];

	  _.each(triangle_info, function (d) {
	    group_info.push(d);
	  });

	  return group_info;
	};

/***/ },
/* 57 */
/***/ function(module, exports) {

	module.exports = function calc_col_dendro_triangles(params) {

	  var triangle_info = {};
	  var inst_level = params.group_level.col;
	  var col_nodes = params.network_data.col_nodes;
	  var col_nodes_names = params.network_data.col_nodes_names;

	  _.each(col_nodes, function (d) {

	    var tmp_group = d.group[inst_level];
	    var inst_index = _.indexOf(col_nodes_names, d.name);
	    var inst_top = params.viz.x_scale(inst_index);
	    var inst_bot = inst_top + params.viz.x_scale.rangeBand();

	    if (_.has(triangle_info, tmp_group) === false) {
	      triangle_info[tmp_group] = {};
	      triangle_info[tmp_group].name_top = d.name;
	      triangle_info[tmp_group].name_bot = d.name;
	      triangle_info[tmp_group].pos_top = inst_top;
	      triangle_info[tmp_group].pos_bot = inst_bot;
	      triangle_info[tmp_group].pos_mid = (inst_top + inst_bot) / 2;
	      triangle_info[tmp_group].name = tmp_group;
	      triangle_info[tmp_group].all_names = [];
	      triangle_info[tmp_group].inst_rc = 'col';
	    }

	    triangle_info[tmp_group].all_names.push(d.name);

	    if (inst_top < triangle_info[tmp_group].pos_top) {
	      triangle_info[tmp_group].name_top = d.name;
	      triangle_info[tmp_group].pos_top = inst_top;
	      triangle_info[tmp_group].pos_mid = (inst_top + triangle_info[tmp_group].pos_bot) / 2;
	    }

	    if (inst_bot > triangle_info[tmp_group].pos_bot) {
	      triangle_info[tmp_group].name_bot = d.name;
	      triangle_info[tmp_group].pos_bot = inst_bot;
	      triangle_info[tmp_group].pos_mid = (triangle_info[tmp_group].pos_top + inst_bot) / 2;
	    }
	  });

	  var group_info = [];

	  _.each(triangle_info, function (d) {
	    group_info.push(d);
	  });

	  return group_info;
		};

/***/ },
/* 58 */
/***/ function(module, exports, __webpack_require__) {

	var dendro_shade_bars = __webpack_require__(59);

	module.exports = function dendro_group_highlight(params, inst_selection, inst_data, inst_rc) {

	  // only make shadows if there is more than one crop button
	  if (d3.selectAll(params.root + ' .' + inst_rc + '_dendro_crop_buttons')[0].length > 1) {
	    setTimeout(still_hovering, 500);
	  } else {
	    d3.selectAll(params.root + ' .dendro_shadow').remove();
	  }

	  function still_hovering() {

	    // check that user is still hovering over dendrogram group
	    if (d3.select(inst_selection).classed('hovering')) {

	      // check that user is not using dendrogram slider
	      if (params.is_slider_drag === false) {

	        d3.select(inst_selection).style('opacity', 0.7);

	        if (d3.select(params.viz.viz_svg).classed('running_update') === false) {
	          make_shadow_bars();
	        }
	      }
	    }
	  }

	  function make_shadow_bars() {

	    if (inst_rc === 'row') {

	      // row and col labling are reversed
	      if (params.viz.inst_order.col === 'clust') {
	        dendro_shade_bars(params, inst_selection, inst_rc, inst_data);
	      }
	    } else if (inst_rc === 'col') {

	      // row and col labeling are reversed
	      if (params.viz.inst_order.row === 'clust') {
	        dendro_shade_bars(params, inst_selection, inst_rc, inst_data);
	      }
	    } else if (inst_rc === 'both') {

	      if (params.viz.inst_order.col === 'clust') {
	        dendro_shade_bars(params, inst_selection, 'row', inst_data);
	      }
	      if (params.viz.inst_order.row === 'clust') {
	        dendro_shade_bars(params, inst_selection, 'col', inst_data);
	      }
	    }
	  }
	};

/***/ },
/* 59 */
/***/ function(module, exports) {

	module.exports = function dendro_shade_bars(params, inst_selection, inst_rc, inst_data) {

	  var inst_opacity = 0.2;
	  var bot_height;

	  d3.selectAll(params.root + ' .dendro_shadow').remove();

	  if (inst_rc == 'row') {

	    // top shade
	    d3.select(params.root + ' .clust_group').append('rect').attr('width', params.viz.clust.dim.width + 'px').attr('height', inst_data.pos_top + 'px').attr('fill', 'black').classed('dendro_shadow', true).attr('opacity', inst_opacity);

	    bot_height = params.viz.clust.dim.height - inst_data.pos_bot;
	    // bottom shade
	    d3.select(params.root + ' .clust_group').append('rect').attr('width', params.viz.clust.dim.width + 'px').attr('height', bot_height + 'px').attr('transform', 'translate(0,' + inst_data.pos_bot + ')').attr('fill', 'black').classed('dendro_shadow', true).attr('opacity', inst_opacity);
	  } else if (inst_rc === 'col') {

	    // top shade
	    d3.select(params.root + ' .clust_group').append('rect').attr('width', inst_data.pos_top + 'px').attr('height', params.viz.clust.dim.height + 'px').attr('fill', 'black').classed('dendro_shadow', true).attr('opacity', inst_opacity);

	    // bottom shade
	    bot_height = params.viz.clust.dim.width - inst_data.pos_bot;
	    d3.select(params.root + ' .clust_group').append('rect').attr('width', bot_height + 'px').attr('height', params.viz.clust.dim.height + 'px').attr('transform', 'translate(' + inst_data.pos_bot + ',0)').attr('fill', 'black').classed('dendro_shadow', true).attr('opacity', inst_opacity);
	  }
		};

/***/ },
/* 60 */
/***/ function(module, exports, __webpack_require__) {

	var calc_row_dendro_triangles = __webpack_require__(56);
	var calc_col_dendro_triangles = __webpack_require__(57);
	var d3_tip_custom = __webpack_require__(48);
	var dendro_group_highlight = __webpack_require__(58);
	var run_dendro_filter = __webpack_require__(61);
	var zoom_crop_triangles = __webpack_require__(62);

	module.exports = function make_dendro_crop_buttons(cgm, inst_rc) {

	  var params = cgm.params;

	  var button_opacity = params.viz.dendro_opacity * 0.60;

	  // information needed to make dendro
	  var dendro_info;
	  var other_rc;
	  if (inst_rc === 'row') {
	    dendro_info = calc_row_dendro_triangles(params);
	    other_rc = 'col';
	  } else {
	    dendro_info = calc_col_dendro_triangles(params);
	    other_rc = 'row';
	  }

	  // d3-tooltip
	  var tmp_y_offset = 5;
	  var tmp_x_offset = -5;
	  var dendro_crop_tip = d3_tip_custom().attr('class', function () {
	    var root_tip_selector = params.viz.root_tips.replace('.', '');
	    var class_string = root_tip_selector + ' d3-tip ' + root_tip_selector + '_' + inst_rc + '_dendro_crop_tip';

	    return class_string;
	  }).direction('nw').style('display', 'none').offset([tmp_y_offset, tmp_x_offset]);

	  var wait_before_tooltip = 500;

	  d3.selectAll(params.viz.root_tips + '_' + inst_rc + '_dendro_crop_tip').remove();
	  d3.selectAll(params.root + ' .' + inst_rc + '_dendro_crop_buttons').remove();

	  var icons;
	  // position triangles
	  var start_x;
	  var start_y;
	  var mid_x;
	  var mid_y;
	  var final_x;
	  var final_y;

	  // need to improve to account for zooming
	  var min_tri_height = 45;
	  var scale_down_tri = 0.25;
	  var tri_height;
	  var tri_width;
	  var tri_dim;

	  // make crop buttons or undo buttons
	  var button_class = inst_rc + '_dendro_crop_buttons';
	  if (d3.select(cgm.params.root + ' .' + inst_rc + '_dendro_icons_group').classed('ran_filter') === false) {

	    // Crop Triangle
	    //////////////////////////////
	    icons = d3.select(params.root + ' .' + inst_rc + '_dendro_icons_group').selectAll('path').data(dendro_info, function (d) {
	      return d.name;
	    }).enter().append('path').classed(button_class, true).attr('d', function (d) {

	      // redefine
	      tri_height = 10;
	      tri_width = 10;

	      var tmp_height = d.pos_bot - d.pos_top;

	      // Row Dendrogram Crop Triangle
	      if (inst_rc === 'row') {

	        if (tmp_height < min_tri_height) {
	          tri_height = tmp_height * scale_down_tri;
	        }

	        // pointing left
	        start_x = tri_width;
	        start_y = -tri_height;
	        mid_x = 0;
	        mid_y = 0;
	        final_x = tri_width;
	        final_y = tri_height;

	        tri_dim = tri_height;

	        // Column Dendrogram Crop Triangle
	      } else {

	        if (tmp_height < min_tri_height) {
	          tri_width = tmp_height * scale_down_tri;
	        }

	        // pointing upward
	        start_x = -tri_width;
	        start_y = tri_height;
	        mid_x = 0;
	        mid_y = 0;
	        final_x = tri_width;
	        final_y = tri_height;

	        tri_dim = tri_width;
	      }

	      // save triangle height
	      // d3.select(this)[0][0].__data__.tri_dim = tri_dim;
	      var data_key = '__data__';
	      d3.select(this)[0][0][data_key].tri_dim = tri_dim;

	      var output_string = 'M' + start_x + ',' + start_y + ', L' + mid_x + ', ' + mid_y + ', L' + final_x + ',' + final_y + ' Z';

	      return output_string;
	    });

	    dendro_crop_tip.html(function () {
	      var full_string = 'Click to crop cluster';
	      return full_string;
	    });
	  } else {

	    // Undo Triangle
	    //////////////////////////////
	    icons = d3.select(params.root + ' .' + inst_rc + '_dendro_icons_group').selectAll('path').data(dendro_info, function (d) {
	      return d.name;
	    }).enter().append('path').classed(button_class, true).attr('d', function (d) {

	      // redefine
	      tri_height = 10;
	      tri_width = 12;

	      var tmp_height = d.pos_bot - d.pos_top;

	      if (inst_rc === 'row') {

	        if (tmp_height < min_tri_height) {
	          tri_height = tmp_height * scale_down_tri;
	        }

	        // pointing right
	        start_x = 0;
	        start_y = -tri_height;
	        mid_x = tri_width;
	        mid_y = 0;
	        final_x = 0;
	        final_y = tri_height;
	      } else {

	        if (tmp_height < min_tri_height) {
	          tri_width = tmp_height * scale_down_tri;
	        }

	        // pointing downward
	        start_x = -tri_width;
	        start_y = 0;
	        mid_x = 0;
	        mid_y = tri_height;
	        final_x = tri_width;
	        final_y = 0;
	      }

	      // save triangle height
	      var data_key = '__data__';
	      d3.select(this)[0][0][data_key].tri_dim = 10;

	      var output_string = 'M' + start_x + ',' + start_y + ', L' + mid_x + ', ' + mid_y + ', L' + final_x + ',' + final_y + ' Z';

	      return output_string;
	    });

	    dendro_crop_tip.html(function () {
	      var full_string = 'Click to undo crop';
	      return full_string;
	    });
	  }

	  icons.style('cursor', 'pointer').style('opacity', function () {

	    var inst_opacity;

	    // if (d3.select(this).classed('hide_crop')){
	    //   inst_opacity = 0;
	    // } else {
	    //   inst_opacity = button_opacity;
	    // }

	    inst_opacity = button_opacity;
	    return inst_opacity;
	  }).attr('transform', function (d) {
	    var inst_translate;

	    var inst_x;
	    var inst_y;

	    if (inst_rc === 'row') {
	      inst_x = params.viz.uni_margin;
	      inst_y = d.pos_mid;
	    } else {
	      inst_x = d.pos_mid;
	      inst_y = params.viz.uni_margin;
	    }

	    inst_translate = 'translate(' + inst_x + ',' + inst_y + ')';
	    return inst_translate;
	  }).on('mouseover', function (d) {

	    d3.select(this).classed('hovering', true);

	    dendro_crop_tip.show(d);

	    dendro_group_highlight(params, this, d, inst_rc);

	    // display with zero opacity
	    d3.selectAll(params.viz.root_tips + '_' + inst_rc + '_dendro_crop_tip').style('opacity', 0).style('display', 'block');

	    // check if still hovering
	    setTimeout(still_hovering, wait_before_tooltip, this);
	  }).on('mouseout', function () {

	    d3.select(this).classed('hovering', false);

	    d3.selectAll(params.root + ' .dendro_shadow').remove();

	    d3.select(this).style('opacity', button_opacity);

	    dendro_crop_tip.hide(this);
	  }).on('click', function (d) {

	    // give user visual cue
	    d3.select(this).style('opacity', 0.9).transition().duration(1000).style('opacity', 0);

	    // remove dendro shadows when clicked
	    d3.selectAll(params.root + ' .dendro_shadow').remove();

	    /* filter using dendrogram */
	    if (cgm.params.dendro_filter.row === false && cgm.params.dendro_filter.col === false && cgm.params.cat_filter.row === false && cgm.params.cat_filter.col === false) {

	      // Run Filtering
	      ///////////////////

	      // use class as 'global' variable
	      d3.select(cgm.params.root + ' .' + inst_rc + '_dendro_icons_group').attr('transform', 'translate(0,0), scale(1,1)').classed('ran_filter', true);

	      d3.select(cgm.params.root + ' .' + other_rc + '_dendro_icons_group').attr('transform', 'translate(0,0), scale(1,1)');

	      // do not display dendrogram slider if filtering has been run
	      d3.select(cgm.params.root + ' .' + inst_rc + '_slider_group').style('display', 'none');

	      // do not display other crop buttons since they are inactive
	      d3.select(cgm.params.root + ' .' + other_rc + '_dendro_icons_container').style('display', 'none');

	      // do not display brush-crop button if performing dendro crop
	      d3.select(cgm.params.root + ' .crop_button').style('opacity', 0.2);
	    } else {

	      // Undo Filtering
	      ///////////////////
	      // use class as 'global' variable
	      d3.select(cgm.params.root + ' .' + inst_rc + '_dendro_icons_group').attr('transform', 'translate(0,0), scale(1,1)').classed('ran_filter', false);

	      d3.select(cgm.params.root + ' .' + other_rc + '_dendro_icons_group').attr('transform', 'translate(0,0), scale(1,1)');

	      if (params.viz.inst_order[other_rc] === 'clust') {
	        // display slider when cropping has not been done
	        d3.select(cgm.params.root + ' .' + inst_rc + '_slider_group').style('display', 'block');
	      }

	      // display other crop buttons when cropping has not been done
	      d3.select(cgm.params.root + ' .' + other_rc + '_dendro_icons_container').style('display', 'block');

	      // display brush-crop button if not performing dendro crop
	      d3.select(cgm.params.root + ' .crop_button').style('opacity', 1);
	    }

	    run_dendro_filter(cgm, d, inst_rc);
	  }).call(dendro_crop_tip);

	  // ordering has been reversed
	  if (params.viz.inst_order[other_rc] != 'clust') {
	    // do not display if not in cluster order
	    d3.select(params.root + ' .' + inst_rc + '_dendro_icons_group').selectAll('path').style('display', 'none');
	  }

	  function still_hovering(inst_selection) {

	    if (d3.select(inst_selection).classed('hovering')) {
	      // increase opacity
	      d3.selectAll(params.viz.root_tips + '_' + inst_rc + '_dendro_crop_tip').style('opacity', 1).style('display', 'block');
	    }
	  }

	  zoom_crop_triangles(params, params.zoom_info, inst_rc);
		};

/***/ },
/* 61 */
/***/ function(module, exports) {

	module.exports = function run_dendro_filter(cgm, d, inst_rc) {

	  var names = {};

	  if (cgm.params.dendro_filter.row === false && cgm.params.dendro_filter.col === false && cgm.params.cat_filter.row === false && cgm.params.cat_filter.col === false) {

	    d3.select(cgm.params.root + ' .' + inst_rc + '_slider_group').style('opacity', 0.35).style('pointer-events', 'none');

	    names[inst_rc] = d.all_names;

	    var tmp_names = cgm.params.network_data[inst_rc + '_nodes_names'];

	    // keep a backup of the inst_view
	    var inst_row_nodes = cgm.params.network_data.row_nodes;
	    var inst_col_nodes = cgm.params.network_data.col_nodes;

	    cgm.filter_viz_using_names(names);

	    // overwrite with backup of original nodes
	    cgm.params.inst_nodes.row_nodes = inst_row_nodes;
	    cgm.params.inst_nodes.col_nodes = inst_col_nodes;

	    d3.selectAll(cgm.params.root + ' .dendro_shadow').transition().duration(1000).style('opacity', 0).remove();

	    // keep the names of all the nodes
	    cgm.params.dendro_filter[inst_rc] = tmp_names;

	    /* reset filter */
	  } else {

	    names[inst_rc] = cgm.params.dendro_filter[inst_rc];

	    cgm.filter_viz_using_names(names);
	    cgm.params.dendro_filter[inst_rc] = false;
	  }
		};

/***/ },
/* 62 */
/***/ function(module, exports) {

	module.exports = function zoom_crop_triangles(params, zoom_info, inst_rc) {

	  if (inst_rc === 'row') {

	    // transform icons (undo zoom on triangles)
	    d3.select(params.root + ' .row_dendro_icons_group').selectAll('path').attr('transform', function (d) {
	      var inst_x = params.viz.uni_margin;
	      var inst_y = d.pos_mid;
	      var curr_zoom = zoom_info.zoom_y;
	      var tri_dim = d3.select(this).data()[0].tri_dim;
	      var inst_zoom = constrain_zoom(curr_zoom, tri_dim);
	      return 'translate(' + inst_x + ',' + inst_y + ') ' + 'scale(1, ' + 1 / inst_zoom + ')';
	    });
	  } else {

	    // transform icons (undo zoom on triangles)
	    d3.select(params.root + ' .col_dendro_icons_group').selectAll('path').attr('transform', function (d) {
	      var inst_x = d.pos_mid;
	      var inst_y = params.viz.uni_margin;
	      var curr_zoom = zoom_info.zoom_x;
	      var tri_dim = d3.select(this).data()[0].tri_dim;
	      var inst_zoom = constrain_zoom(curr_zoom, tri_dim);
	      return 'translate(' + inst_x + ',' + inst_y + ') ' + 'scale(' + 1 / inst_zoom + ', 1)';
	    });
	  }

	  function constrain_zoom(curr_zoom, tri_height) {
	    var inst_zoom;
	    var default_tri_height = 10;
	    if (tri_height * curr_zoom < default_tri_height) {
	      inst_zoom = 1;
	    } else {
	      var max_zoom = default_tri_height / tri_height;
	      inst_zoom = curr_zoom / max_zoom;
	    }
	    return inst_zoom;
	  }
		};

/***/ },
/* 63 */
/***/ function(module, exports, __webpack_require__) {

	var calc_cat_cluster_breakdown = __webpack_require__(64);

	module.exports = function make_cat_breakdown_graph(params, inst_rc, inst_data, dendro_info, selector, tooltip = false) {

	  /*
	  This function is used to make the category breakdown graphs for tooltips on
	  dendrogram mousover and on dendrogram click modal popup.
	  */

	  // in case sim_mat
	  if (inst_rc === 'both') {
	    inst_rc = 'row';
	  }

	  var cat_breakdown = calc_cat_cluster_breakdown(params, inst_data, inst_rc);

	  if (cat_breakdown.length > 0) {

	    // put cluster information in dendro_tip
	    ///////////////////////////////////////////
	    var cluster_info_container = d3.select(selector + ' .cluster_info_container');

	    // loop through cat_breakdown data
	    var super_string = ': ';
	    var paragraph_string = '<p>';
	    var width = 370;
	    var bar_offset = 23;
	    var bar_height = 20;
	    var max_string_length = 25;
	    var bar_width = 180;
	    var title_height = 27;
	    var shift_tooltip_left = 177;

	    // these are the indexes where the number-of-nodes and the number of downsampled
	    // nodes are stored
	    var num_nodes_index = 4;
	    var num_nodes_ds_index = 5;
	    var offset_ds_count = 150;
	    var binom_pval_index = 6;

	    var is_downsampled = false;
	    if (cat_breakdown[0].bar_data[0][num_nodes_ds_index] != null) {
	      width = width + 100;
	      shift_tooltip_left = shift_tooltip_left + offset_ds_count - 47;
	      is_downsampled = true;
	    }

	    // the index that will be used to generate the bars (will be different if
	    // downsampled)
	    var cluster_total = dendro_info.all_names.length;
	    var bars_index = num_nodes_index;
	    if (is_downsampled) {
	      bars_index = num_nodes_ds_index;

	      // calculate the total number of nodes in downsampled case
	      var inst_bar_data = cat_breakdown[0].bar_data;
	      cluster_total = 0;
	      _.each(inst_bar_data, function (tmp_data) {
	        cluster_total = cluster_total + tmp_data[num_nodes_ds_index];
	      });
	    }

	    // limit on the number of category types shown
	    var max_cats = 3;
	    // limit the number of bars shown
	    var max_bars = 25;

	    // calculate height needed for svg based on cat_breakdown data
	    var svg_height = 20;
	    _.each(cat_breakdown.slice(0, max_cats), function (tmp_break) {
	      var num_bars = tmp_break.bar_data.length;
	      if (num_bars > max_bars) {
	        num_bars = max_bars;
	      }
	      svg_height = svg_height + title_height * (num_bars + 1);
	    });

	    // Cluster Information Title (for tooltip only not modal)
	    if (tooltip) {
	      cluster_info_container.append('text').text('Cluster Information');
	    }

	    var main_dendro_svg = cluster_info_container.append('div').style('margin-top', '5px').classed('cat_graph', true).append('svg').style('height', svg_height + 'px').style('width', width + 'px');

	    // make background
	    main_dendro_svg.append('rect').classed('cat_background', true).attr('height', svg_height + 'px').attr('width', width + 'px').attr('fill', 'white').attr('opacity', 1);

	    // the total amout to shift down the next category
	    var shift_down = title_height;

	    // limit the category-types
	    cat_breakdown = cat_breakdown.slice(0, max_cats);

	    _.each(cat_breakdown, function (cat_data) {

	      var max_bar_value = cat_data.bar_data[0][bars_index];

	      // offset the count column based on how large the counts are
	      var digit_offset_scale = d3.scale.linear().domain([0, 100000]).range([20, 30]);

	      // only keep the top max_bars categories
	      cat_data.bar_data = cat_data.bar_data.slice(0, max_bars);

	      cluster_info_container.style('margin-bottom', '5px');

	      var cat_graph_group = main_dendro_svg.append('g').classed('cat_graph_group', true).attr('transform', 'translate(10, ' + shift_down + ')');

	      // shift down based on number of bars
	      shift_down = shift_down + title_height * (cat_data.bar_data.length + 1);

	      var inst_title = cat_data.type_name;
	      // ensure that title is not too long
	      if (inst_title.length >= max_string_length) {
	        inst_title = inst_title.slice(0, max_string_length) + '..';
	      }

	      // make title
	      cat_graph_group.append('text').classed('cat_graph_title', true).text(inst_title).style('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif').style('font-weight', 800);

	      // shift the position of the numbers based on the size of the number
	      var count_offset = digit_offset_scale(max_bar_value);

	      // Count Title
	      cat_graph_group.append('text').text('Count').attr('transform', function () {
	        var inst_x = bar_width + count_offset;
	        var inst_translate = 'translate(' + inst_x + ', 0)';
	        return inst_translate;
	      });

	      // Percentage Title
	      cat_graph_group.append('text').text('Pct').attr('transform', function () {
	        var inst_x = bar_width + count_offset + 60;
	        var inst_translate = 'translate(' + inst_x + ', 0)';
	        return inst_translate;
	      });

	      // Percentage Title
	      cat_graph_group.append('text').text('P-val').attr('transform', function () {
	        var inst_x = bar_width + count_offset + 115;
	        var inst_translate = 'translate(' + inst_x + ', 0)';
	        return inst_translate;
	      });

	      // Count Downsampled Title
	      if (is_downsampled) {
	        cat_graph_group.append('text').text('Clusters').attr('transform', function () {
	          var inst_x = bar_width + offset_ds_count;
	          var inst_translate = 'translate(' + inst_x + ', 0)';
	          return inst_translate;
	        });
	      }

	      var line_y = 4;
	      cat_graph_group.append('line').attr('x1', 0).attr('x2', bar_width).attr('y1', line_y).attr('y2', line_y).attr('stroke', 'blue').attr('stroke-width', 1).attr('opacity', 1.0);

	      var cat_bar_container = cat_graph_group.append('g').classed('cat_bar_container', true).attr('transform', 'translate(0, 10)');

	      // make bar groups (hold bar and text)
	      var cat_bar_groups = cat_bar_container.selectAll('g').data(cat_data.bar_data).enter().append('g').attr('transform', function (d, i) {
	        var inst_y = i * bar_offset;
	        return 'translate(0,' + inst_y + ')';
	      });

	      // bar length is max when all nodes in cluster are of
	      // a single cat
	      var bar_scale = d3.scale.linear().domain([0, max_bar_value]).range([0, bar_width]);

	      // make bars
	      cat_bar_groups.append('rect').attr('height', bar_height + 'px').attr('width', function (d) {
	        var inst_width = bar_scale(d[bars_index]);
	        return inst_width + 'px';
	      }).attr('fill', function (d) {
	        // cat color is stored in the third element
	        return d[3];
	      }).attr('opacity', params.viz.cat_colors.opacity).attr('stroke', 'grey').attr('stroke-width', '0.5px');

	      // make bar labels
	      cat_bar_groups.append('text').classed('bar_labels', true).text(function (d) {
	        var inst_text = d[1];
	        if (inst_text.indexOf(super_string) > 0) {
	          inst_text = inst_text.split(super_string)[1];
	        }
	        if (inst_text.indexOf(paragraph_string) > 0) {
	          // required for Enrichr category names (needs improvements)
	          inst_text = inst_text.split(paragraph_string)[0];
	        }
	        // ensure that bar name is not too long
	        if (inst_text.length >= max_string_length) {
	          inst_text = inst_text.slice(0, max_string_length) + '..';
	        }
	        return inst_text;
	      }).attr('transform', function () {
	        return 'translate(5, ' + 0.75 * bar_height + ')';
	      }).attr('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif').attr('font-weight', 400).attr('text-anchor', 'right');

	      // Count/Pct Rows
	      /////////////////////////////
	      var shift_count_num = 35;

	      cat_bar_groups.append('text').classed('count_labels', true).text(function (d) {
	        var inst_count = d[bars_index];
	        inst_count = inst_count.toLocaleString();
	        return String(inst_count);
	      }).attr('transform', function () {
	        var inst_x = bar_width + count_offset + shift_count_num;
	        var inst_y = 0.75 * bar_height;
	        return 'translate(' + inst_x + ', ' + inst_y + ')';
	      }).attr('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif').attr('font-weight', 400).attr('text-anchor', 'end');

	      cat_bar_groups.append('text').classed('count_labels', true).text(function (d) {
	        // calculate the percentage relative to the current cluster
	        var inst_count = d[bars_index] / cluster_total * 100;
	        inst_count = Math.round(inst_count * 10) / 10;
	        inst_count = inst_count.toLocaleString();
	        return String(inst_count);
	      }).attr('transform', function () {
	        var inst_x = bar_width + count_offset + shift_count_num + 47;
	        var inst_y = 0.75 * bar_height;
	        return 'translate(' + inst_x + ', ' + inst_y + ')';
	      }).attr('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif').attr('font-weight', 400).attr('text-anchor', 'end');

	      // Binomial Test Pvals
	      cat_bar_groups.append('text').classed('count_labels', true).text(function (d) {
	        // calculate the percentage relative to the current cluster
	        var inst_count = d[binom_pval_index];

	        if (inst_count < 0.1) {
	          inst_count = parseFloat(inst_count.toPrecision(3));
	          inst_count = inst_count.toExponential();
	        } else {
	          inst_count = parseFloat(inst_count.toPrecision(2));
	        }

	        // inst_count = inst_count.toLocaleString();
	        return inst_count;
	      }).attr('transform', function () {
	        var inst_x = bar_width + count_offset + shift_count_num + 112;
	        var inst_y = 0.75 * bar_height;
	        return 'translate(' + inst_x + ', ' + inst_y + ')';
	      }).attr('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif').attr('font-weight', 400).attr('text-anchor', 'end');

	      if (is_downsampled) {
	        cat_bar_groups.append('text').classed('count_labels', true).text(function (d) {
	          return String(d[num_nodes_index].toLocaleString());
	        }).attr('transform', function () {
	          // downsampled cluster numbers are smaller and need less flexible offsetting
	          var inst_x = bar_width + shift_count_num + offset_ds_count + 20;
	          var inst_y = 0.75 * bar_height;
	          return 'translate(' + inst_x + ', ' + inst_y + ')';
	        }).attr('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif').attr('font-weight', 400).attr('text-anchor', 'end');
	      }
	    });

	    // reposition tooltip
	    /////////////////////////////////////////////////
	    if (tooltip) {

	      var dendro_tip = d3.select(selector);
	      var old_top = dendro_tip.style('top').split('.px')[0];
	      var old_left = dendro_tip.style('left').split('.px')[0];
	      var shift_top = 0;
	      var shift_left = 0;

	      // shifting
	      if (inst_rc === 'row') {

	        // rows
	        //////////////
	        shift_top = 0;
	        shift_left = shift_tooltip_left;

	        // // prevent graph from being too high
	        // if (dendro_info.pos_top < svg_height){
	        //   // do not shift position of category breakdown graph
	        //   // shift_top = -(svg_height + (dendro_info.pos_mid - dendro_info.pos_top)/2) ;
	        // }
	      } else {

	        // columns
	        //////////////
	        shift_top = svg_height + 32;
	        shift_left = 30;
	      }

	      dendro_tip.style('top', function () {
	        var new_top = String(parseInt(old_top, 10) - shift_top) + 'px';
	        return new_top;
	      }).style('left', function () {
	        var new_left = String(parseInt(old_left, 10) - shift_left) + 'px';
	        return new_left;
	      });
	    }
	  }
		};

/***/ },
/* 64 */
/***/ function(module, exports, __webpack_require__) {

	var binom_test = __webpack_require__(65);

	module.exports = function calc_cat_cluster_breakdown(params, inst_data, inst_rc) {
	  // Category-breakdown of dendrogram-clusters
	  /////////////////////////////////////////////
	  /*
	  1. get information for nodes in cluster
	  2. find category-types that are string-type
	  3. count instances of each category name for each category-type
	  */

	  // in case sim_mat
	  if (inst_rc === 'both') {
	    inst_rc = 'row';
	  }

	  // 1: get information for nodes in cluster
	  ///////////////////////////////////////////

	  // names of nodes in cluster
	  var clust_names = inst_data.all_names;
	  // array of nodes in the cluster
	  var clust_nodes = [];
	  var all_nodes = params.network_data[inst_rc + '_nodes'];
	  var num_in_clust_index = null;
	  var is_downsampled = false;

	  var inst_name;
	  _.each(all_nodes, function (inst_node) {

	    inst_name = inst_node.name;

	    if (clust_names.indexOf(inst_name) >= 0) {
	      clust_nodes.push(inst_node);
	    }
	  });

	  // 2: find category-types that are string-type
	  ///////////////////////////////////////////////

	  var cat_breakdown = [];

	  if (params.viz.cat_info[inst_rc] !== null) {

	    var inst_cat_info = params.viz.cat_info[inst_rc];

	    // tmp list of all categories
	    var tmp_types_index = _.keys(inst_cat_info);
	    // this will hold the indexes of string-type categories
	    var cat_types_index = [];

	    // get category names (only include string-type categories)
	    var cat_types_names = [];
	    var type_name;
	    var inst_index;
	    var cat_index;
	    for (var i = 0; i < tmp_types_index.length; i++) {

	      cat_index = 'cat-' + String(i);

	      if (params.viz.cat_info[inst_rc][cat_index].type === 'cat_strings') {
	        type_name = params.viz.cat_names[inst_rc][cat_index];
	        cat_types_names.push(type_name);
	        cat_types_index.push(cat_index);
	      } else {

	        // save number in clust category index if found
	        if (params.viz.cat_names[inst_rc][cat_index] === 'number in clust') {
	          num_in_clust_index = cat_index;
	          is_downsampled = true;
	        }
	      }
	    }

	    var tmp_run_count = {};
	    var inst_breakdown = {};
	    var bar_data;
	    var radix_param = 10;

	    // sort by actual counts (rather than cluster counts)
	    var sorting_index = 4;
	    if (is_downsampled) {
	      sorting_index = 5;
	    }

	    var no_title_given;
	    if (type_name === cat_index) {
	      no_title_given = true;
	    } else {
	      no_title_given = false;
	    }

	    if (cat_types_names.length > 0) {

	      // 3: count instances of each category name for each category-type
	      var cat_name;
	      var num_in_clust = clust_names.length;

	      // use the cat_hist to get the number of instances of this category in
	      // all rows/cols
	      // params

	      _.each(cat_types_index, function (cat_index) {

	        inst_index = cat_index.split('-')[1];
	        type_name = cat_types_names[inst_index];

	        if (no_title_given) {
	          if (cat_index.indexOf('-') >= 0) {
	            var tmp_num = parseInt(cat_index.split('-')[1], radix_param) + 1;
	            type_name = 'Category ' + String(tmp_num);
	          } else {
	            // backup behavior
	            type_name = 'Category';
	          }
	        }

	        tmp_run_count[type_name] = {};

	        // loop through the nodes and keep a running count of categories
	        _.each(clust_nodes, function (tmp_node) {

	          cat_name = tmp_node[cat_index];

	          if (cat_name.indexOf(': ') >= 0) {
	            cat_name = cat_name.split(': ')[1];
	          }

	          if (cat_name in tmp_run_count[type_name]) {
	            tmp_run_count[type_name][cat_name].num_nodes = tmp_run_count[type_name][cat_name].num_nodes + 1;

	            if (num_in_clust_index != null) {
	              tmp_run_count[type_name][cat_name].num_nodes_ds = tmp_run_count[type_name][cat_name].num_nodes_ds + parseInt(tmp_node[num_in_clust_index].split(': ')[1], radix_param);
	            }
	          } else {

	            tmp_run_count[type_name][cat_name] = {};
	            tmp_run_count[type_name][cat_name].num_nodes = 1;
	            if (num_in_clust_index != null) {
	              tmp_run_count[type_name][cat_name].num_nodes_ds = parseInt(tmp_node[num_in_clust_index].split(': ')[1], radix_param);
	            }
	          }
	        });

	        inst_breakdown = {};
	        inst_breakdown.type_name = type_name;
	        inst_breakdown.num_in_clust = num_in_clust;

	        // sort cat info in cat_breakdown
	        bar_data = [];
	        var bar_color;
	        var cat_title_and_name;
	        var inst_run_count = tmp_run_count[type_name];

	        for (var inst_cat in inst_run_count) {

	          var tot_num_cat = params.viz.cat_info[inst_rc][cat_index].cat_hist[inst_cat];
	          var total_nodes = params.network_data[inst_rc + '_nodes'].length;
	          var expect_prob = tot_num_cat / total_nodes;

	          // if no cat-title given
	          if (no_title_given) {
	            cat_title_and_name = inst_cat;
	          } else {
	            cat_title_and_name = type_name + ': ' + inst_cat;
	          }

	          // num_nodes: number of cat-nodes drawn in cluster
	          var num_nodes = inst_run_count[inst_cat].num_nodes;

	          var actual_k = num_nodes;
	          var pval = binom_test(actual_k, num_in_clust, expect_prob);

	          // working on tracking the 'real' number of nodes, which is only different
	          // if downsampling has been done
	          if (_.has(inst_run_count[inst_cat], 'num_nodes_ds')) {
	            var num_nodes_ds = inst_run_count[inst_cat].num_nodes_ds;
	          } else {
	            num_nodes_ds = null;
	          }

	          bar_color = params.viz.cat_colors[inst_rc][cat_index][cat_title_and_name];

	          bar_data.push([cat_index, cat_title_and_name, inst_run_count[inst_cat], bar_color, num_nodes, num_nodes_ds, pval]);
	        }

	        bar_data.sort(function (a, b) {
	          return b[sorting_index] - a[sorting_index];
	        });

	        inst_breakdown.bar_data = bar_data;

	        cat_breakdown.push(inst_breakdown);
	      });
	    }
	  }

	  return cat_breakdown;
	};

/***/ },
/* 65 */
/***/ function(module, exports, __webpack_require__) {


	// Load the math.js core
	// Create a new, empty math.js instance
	// It will only contain methods `import` and `config`
	// math.import(require('mathjs/lib/type/fraction'));
	var p_dict = __webpack_require__(66);
	var core = __webpack_require__(67);
	var math = core.create();

	math.import(__webpack_require__(79));

	module.exports = function binom_test(actual_k, n, p) {

	  var fact = math.factorial;
	  var pval;

	  function binom_dist(k, n, p) {
	    var bin_coeff = fact(n) / (fact(k) * fact(n - k));
	    p = bin_coeff * (Math.pow(p, k) * Math.pow(1 - p, n - k));
	    return p;
	  }

	  function my_binom_test_2(actual_k, n, p) {
	    var cp = 0;
	    var k;
	    var dp;
	    for (var inst_k = actual_k; inst_k < n + 1; inst_k++) {
	      k = inst_k;
	      dp = binom_dist(k, n, p);
	      cp = cp + dp;
	    }

	    return cp;
	  }

	  // look up p-value from z-score using table
	  function binom_prop_table(actual_k, n, p) {

	    // expected average number of successes
	    var mu = n * p;

	    // standard deviation
	    var sigma = Math.sqrt(n * p * (1 - p));

	    // how many standard deviations is the actual_k away
	    // from the expected value
	    var z = (actual_k - mu) / sigma;

	    var z_vals = p_dict.z;
	    var p_vals = p_dict.p;

	    var found_index = -1;
	    var found = false;

	    for (var index = 0; index < z_vals.length; index++) {
	      var inst_z = z_vals[index];

	      // increasing inst_z until z is less than inst_z
	      if (z < inst_z && found === false) {
	        found_index = index;
	        found = true;
	      }
	    }

	    // give it the smallest p-val if the z-score was larger than
	    // any in the table
	    if (found_index === -1) {
	      found_index = z_vals.length - 1;
	    }
	    pval = p_vals[found_index];

	    return pval;
	  }

	  // calculate pval
	  pval = my_binom_test_2(actual_k, n, p);
	  if (isNaN(pval)) {
	    pval = binom_prop_table(actual_k, n, p);
	  }

	  return pval;
		};

/***/ },
/* 66 */
/***/ function(module, exports) {

	module.exports = {
	  "p": [0.5, 0.48006119416162751, 0.46017216272297101, 0.4403823076297575, 0.42074029056089696, 0.4012936743170763, 0.38208857781104733, 0.3631693488243809, 0.34457825838967582, 0.32635522028791997, 0.30853753872598688, 0.29115968678834636, 0.27425311775007355, 0.25784611080586473, 0.24196365222307303, 0.22662735237686821, 0.21185539858339669, 0.19766254312269238, 0.18406012534675947, 0.17105612630848183, 0.15865525393145707, 0.14685905637589591, 0.13566606094638267, 0.12507193563715024, 0.11506967022170828, 0.10564977366685535, 0.096800484585610358, 0.088507991437401956, 0.080756659233771066, 0.073529259609648304, 0.066807201268858071, 0.060570758002059008, 0.054799291699557974, 0.049471468033648075, 0.044565462758543006, 0.040059156863817086, 0.035930319112925789, 0.032156774795613713, 0.028716559816001783, 0.025588059521638611, 0.022750131948179195, 0.020182215405704383, 0.017864420562816542, 0.015777607391090499, 0.013903447513498595, 0.012224472655044696, 0.010724110021675795, 0.0093867055348385662, 0.0081975359245961138, 0.0071428107352714152, 0.0062096653257761323, 0.0053861459540666843, 0.0046611880237187467, 0.0040245885427583027, 0.0034669738030406647, 0.0029797632350545551, 0.002555130330427929, 0.0021859614549132405, 0.0018658133003840339, 0.0015888696473648667, 0.0013498980316300933, 0.0011442068310226977, 0.00096760321321835631, 0.00081635231282856037, 0.00068713793791584708, 0.00057702504239076592, 0.00048342414238377663, 0.0004040578018640207, 0.00033692926567687988, 0.00028029327681617744, 0.00023262907903552502, 0.00019261557563563279, 0.00015910859015753364, 0.00013112015442048433, 0.00010779973347738823, 8.8417285200803773e-05, 7.2348043925119787e-05, 5.9058912418922374e-05, 4.8096344017602614e-05, 3.9075596597787456e-05, 3.1671241833119863e-05, 2.5608816474041489e-05, 2.0657506912546683e-05, 1.6623763729652213e-05, 1.334574901590631e-05, 1.0688525774934402e-05, 8.5399054709917942e-06, 6.8068765993340312e-06, 5.4125439077038407e-06, 4.293514469971858e-06, 3.3976731247300535e-06, 2.6822957796388472e-06, 2.1124547025028419e-06, 1.6596751443714555e-06, 1.3008074539172771e-06, 1.0170832425687032e-06, 7.9332815197558919e-07, 6.1730737200919249e-07, 4.7918327659031855e-07, 3.7106740796333271e-07, 2.8665157187919333e-07, 2.2090503226954194e-07, 1.6982674071475937e-07, 1.3024322953320117e-07, 9.9644263169334701e-08, 7.6049605164887e-08, 5.7901340399645569e-08, 4.3977115940058689e-08, 3.3320448485428448e-08, 2.518491005446105e-08, 1.8989562465887681e-08, 1.4283479893922661e-08, 1.0717590258310852e-08, 8.0223918506634739e-09, 5.9903714010635304e-09, 4.4621724539016108e-09, 3.3157459783261365e-09, 2.4578650618080152e-09, 1.8175078630994235e-09, 1.3407124440918662e-09, 9.8658764503769458e-10, 7.2422917051376055e-10, 5.303423262948808e-10, 3.8741473466756636e-10, 2.8231580370432682e-10, 2.0522634252189396e-10, 1.4882282217622966e-10, 1.0765746385121517e-10, 7.7688475817097756e-11, 5.592507575942645e-11, 4.0160005838590881e-11, 2.8768541736043109e-11, 2.055788909399508e-11, 1.4654650977302715e-11, 1.0420976987965154e-11, 7.3922577780177942e-12, 5.2309575441445253e-12, 3.6924994272355614e-12, 2.600126965638173e-12, 1.8264310619769611e-12, 1.279812543885835e-12, 8.9458895587698439e-13, 6.23784446333152e-13, 4.3388950271780343e-13, 3.0106279811174218e-13, 2.0838581586720548e-13, 1.4388386381575764e-13, 9.9103427495475088e-14, 6.8092248906200155e-14, 4.6670115887190274e-14, 3.1908916729108844e-14, 2.1762912097085575e-14, 1.4806537490047908e-14, 1.0048965656526223e-14, 6.8033115407739012e-15, 4.5946274357785623e-15, 3.095358771958668e-15, 2.0801863521393674e-15, 1.394517146659261e-15, 9.3255757716812045e-16, 6.2209605742717405e-16, 4.1397018162731219e-16, 2.7479593923982212e-16, 1.8196213635266084e-16, 1.2019351542735647e-16, 7.9197263146424757e-17, 5.2055697448902465e-17, 3.4131483264581459e-17, 2.232393197288031e-17, 1.456514112590909e-17, 9.4795348222032499e-18, 6.1544255908503949e-18, 3.985804962848151e-18, 2.5749715380118873e-18, 1.6594208699647519e-18, 1.0667637375474856e-18, 6.840807685935497e-19, 4.3759647993090167e-19, 2.7923343749396233e-19, 1.7774117841455144e-19, 1.1285884059538324e-19, 7.1484170112696837e-20, 4.516591491435403e-20, 2.8466774084602088e-20, 1.7897488120140146e-20, 1.1224633591327901e-20, 7.0222842404415411e-21, 4.3823862990664603e-21, 2.7281535713460872e-21, 1.6941535024881097e-21, 1.0494515075362604e-21, 6.4848144530772079e-22, 3.9972212057261192e-22, 2.4577864834723153e-22, 1.5074931688101589e-22, 9.2234135249393526e-23, 5.6292823113765143e-23, 3.4271987941135974e-23, 2.0813752194932085e-23, 1.2609160670206559e-23],
	  "z": [0.0, 0.050000000000000003, 0.10000000000000001, 0.15000000000000002, 0.20000000000000001, 0.25, 0.30000000000000004, 0.35000000000000003, 0.40000000000000002, 0.45000000000000001, 0.5, 0.55000000000000004, 0.60000000000000009, 0.65000000000000002, 0.70000000000000007, 0.75, 0.80000000000000004, 0.85000000000000009, 0.90000000000000002, 0.95000000000000007, 1.0, 1.05, 1.1000000000000001, 1.1500000000000001, 1.2000000000000002, 1.25, 1.3, 1.3500000000000001, 1.4000000000000001, 1.4500000000000002, 1.5, 1.55, 1.6000000000000001, 1.6500000000000001, 1.7000000000000002, 1.75, 1.8, 1.8500000000000001, 1.9000000000000001, 1.9500000000000002, 2.0, 2.0500000000000003, 2.1000000000000001, 2.1499999999999999, 2.2000000000000002, 2.25, 2.3000000000000003, 2.3500000000000001, 2.4000000000000004, 2.4500000000000002, 2.5, 2.5500000000000003, 2.6000000000000001, 2.6500000000000004, 2.7000000000000002, 2.75, 2.8000000000000003, 2.8500000000000001, 2.9000000000000004, 2.9500000000000002, 3.0, 3.0500000000000003, 3.1000000000000001, 3.1500000000000004, 3.2000000000000002, 3.25, 3.3000000000000003, 3.3500000000000001, 3.4000000000000004, 3.4500000000000002, 3.5, 3.5500000000000003, 3.6000000000000001, 3.6500000000000004, 3.7000000000000002, 3.75, 3.8000000000000003, 3.8500000000000001, 3.9000000000000004, 3.9500000000000002, 4.0, 4.0499999999999998, 4.1000000000000005, 4.1500000000000004, 4.2000000000000002, 4.25, 4.2999999999999998, 4.3500000000000005, 4.4000000000000004, 4.4500000000000002, 4.5, 4.5499999999999998, 4.6000000000000005, 4.6500000000000004, 4.7000000000000002, 4.75, 4.8000000000000007, 4.8500000000000005, 4.9000000000000004, 4.9500000000000002, 5.0, 5.0500000000000007, 5.1000000000000005, 5.1500000000000004, 5.2000000000000002, 5.25, 5.3000000000000007, 5.3500000000000005, 5.4000000000000004, 5.4500000000000002, 5.5, 5.5500000000000007, 5.6000000000000005, 5.6500000000000004, 5.7000000000000002, 5.75, 5.8000000000000007, 5.8500000000000005, 5.9000000000000004, 5.9500000000000002, 6.0, 6.0500000000000007, 6.1000000000000005, 6.1500000000000004, 6.2000000000000002, 6.25, 6.3000000000000007, 6.3500000000000005, 6.4000000000000004, 6.4500000000000002, 6.5, 6.5500000000000007, 6.6000000000000005, 6.6500000000000004, 6.7000000000000002, 6.75, 6.8000000000000007, 6.8500000000000005, 6.9000000000000004, 6.9500000000000002, 7.0, 7.0500000000000007, 7.1000000000000005, 7.1500000000000004, 7.2000000000000002, 7.25, 7.3000000000000007, 7.3500000000000005, 7.4000000000000004, 7.4500000000000002, 7.5, 7.5500000000000007, 7.6000000000000005, 7.6500000000000004, 7.7000000000000002, 7.75, 7.8000000000000007, 7.8500000000000005, 7.9000000000000004, 7.9500000000000002, 8.0, 8.0500000000000007, 8.0999999999999996, 8.1500000000000004, 8.2000000000000011, 8.25, 8.3000000000000007, 8.3499999999999996, 8.4000000000000004, 8.4500000000000011, 8.5, 8.5500000000000007, 8.5999999999999996, 8.6500000000000004, 8.7000000000000011, 8.75, 8.8000000000000007, 8.8499999999999996, 8.9000000000000004, 8.9500000000000011, 9.0, 9.0500000000000007, 9.0999999999999996, 9.1500000000000004, 9.2000000000000011, 9.25, 9.3000000000000007, 9.3499999999999996, 9.4000000000000004, 9.4500000000000011, 9.5, 9.5500000000000007, 9.6000000000000014, 9.6500000000000004, 9.7000000000000011, 9.75, 9.8000000000000007, 9.8500000000000014, 9.9000000000000004, 9.9500000000000011]
		};

/***/ },
/* 67 */
/***/ function(module, exports, __webpack_require__) {

	module.exports = __webpack_require__(68);

/***/ },
/* 68 */
/***/ function(module, exports, __webpack_require__) {

	var isFactory = __webpack_require__(69).isFactory;
	var deepExtend = __webpack_require__(69).deepExtend;
	var typedFactory = __webpack_require__(70);
	var emitter = __webpack_require__(74);

	var importFactory = __webpack_require__(76);
	var configFactory = __webpack_require__(78);

	/**
	 * Math.js core. Creates a new, empty math.js instance
	 * @param {Object} [options] Available options:
	 *                            {number} epsilon
	 *                              Minimum relative difference between two
	 *                              compared values, used by all comparison functions.
	 *                            {string} matrix
	 *                              A string 'Matrix' (default) or 'Array'.
	 *                            {string} number
	 *                              A string 'number' (default), 'BigNumber', or 'Fraction'
	 *                            {number} precision
	 *                              The number of significant digits for BigNumbers.
	 *                              Not applicable for Numbers.
	 *                            {boolean} predictable
	 *                              Predictable output type of functions. When true,
	 *                              output type depends only on the input types. When
	 *                              false (default), output type can vary depending
	 *                              on input values. For example `math.sqrt(-2)`
	 *                              returns `NaN` when predictable is false, and
	 *                              returns `complex('2i')` when true.
	 * @returns {Object} Returns a bare-bone math.js instance containing
	 *                   functions:
	 *                   - `import` to add new functions
	 *                   - `config` to change configuration
	 *                   - `on`, `off`, `once`, `emit` for events
	 */
	exports.create = function create(options) {
	  // simple test for ES5 support
	  if (typeof Object.create !== 'function') {
	    throw new Error('ES5 not supported by this JavaScript engine. ' + 'Please load the es5-shim and es5-sham library for compatibility.');
	  }

	  // cached factories and instances
	  var factories = [];
	  var instances = [];

	  // create a namespace for the mathjs instance, and attach emitter functions
	  var math = emitter.mixin({});
	  math.type = {};
	  math.expression = {
	    transform: Object.create(math)
	  };

	  // create a new typed instance
	  math.typed = typedFactory.create(math.type);

	  // create configuration options. These are private
	  var _config = {
	    // minimum relative difference between two compared values,
	    // used by all comparison functions
	    epsilon: 1e-12,

	    // type of default matrix output. Choose 'matrix' (default) or 'array'
	    matrix: 'Matrix',

	    // type of default number output. Choose 'number' (default) 'BigNumber', or 'Fraction
	    number: 'number',

	    // number of significant digits in BigNumbers
	    precision: 64,

	    // predictable output type of functions. When true, output type depends only
	    // on the input types. When false (default), output type can vary depending
	    // on input values. For example `math.sqrt(-2)` returns `NaN` when
	    // predictable is false, and returns `complex('2i')` when true.
	    predictable: false
	  };

	  /**
	   * Load a function or data type from a factory.
	   * If the function or data type already exists, the existing instance is
	   * returned.
	   * @param {{type: string, name: string, factory: Function}} factory
	   * @returns {*}
	   */
	  function load(factory) {
	    if (!isFactory(factory)) {
	      throw new Error('Factory object with properties `type`, `name`, and `factory` expected');
	    }

	    var index = factories.indexOf(factory);
	    var instance;
	    if (index === -1) {
	      // doesn't yet exist
	      if (factory.math === true) {
	        // pass with math namespace
	        instance = factory.factory(math.type, _config, load, math.typed, math);
	      } else {
	        instance = factory.factory(math.type, _config, load, math.typed);
	      }

	      // append to the cache
	      factories.push(factory);
	      instances.push(instance);
	    } else {
	      // already existing function, return the cached instance
	      instance = instances[index];
	    }

	    return instance;
	  }

	  // load the import and config functions
	  math['import'] = load(importFactory);
	  math['config'] = load(configFactory);

	  // apply options
	  if (options) {
	    math.config(options);
	  }

	  return math;
	};

/***/ },
/* 69 */
/***/ function(module, exports) {

	'use strict';

	/**
	 * Clone an object
	 *
	 *     clone(x)
	 *
	 * Can clone any primitive type, array, and object.
	 * If x has a function clone, this function will be invoked to clone the object.
	 *
	 * @param {*} x
	 * @return {*} clone
	 */

	exports.clone = function clone(x) {
	  var type = typeof x;

	  // immutable primitive types
	  if (type === 'number' || type === 'string' || type === 'boolean' || x === null || x === undefined) {
	    return x;
	  }

	  // use clone function of the object when available
	  if (typeof x.clone === 'function') {
	    return x.clone();
	  }

	  // array
	  if (Array.isArray(x)) {
	    return x.map(function (value) {
	      return clone(value);
	    });
	  }

	  if (x instanceof Number) return new Number(x.valueOf());
	  if (x instanceof String) return new String(x.valueOf());
	  if (x instanceof Boolean) return new Boolean(x.valueOf());
	  if (x instanceof Date) return new Date(x.valueOf());
	  if (x && x.isBigNumber === true) return x; // bignumbers are immutable
	  if (x instanceof RegExp) throw new TypeError('Cannot clone ' + x); // TODO: clone a RegExp

	  // object
	  var m = {};
	  for (var key in x) {
	    if (x.hasOwnProperty(key)) {
	      m[key] = clone(x[key]);
	    }
	  }
	  return m;
	};

	/**
	 * Extend object a with the properties of object b
	 * @param {Object} a
	 * @param {Object} b
	 * @return {Object} a
	 */
	exports.extend = function (a, b) {
	  for (var prop in b) {
	    if (b.hasOwnProperty(prop)) {
	      a[prop] = b[prop];
	    }
	  }
	  return a;
	};

	/**
	 * Deep extend an object a with the properties of object b
	 * @param {Object} a
	 * @param {Object} b
	 * @returns {Object}
	 */
	exports.deepExtend = function deepExtend(a, b) {
	  // TODO: add support for Arrays to deepExtend
	  if (Array.isArray(b)) {
	    throw new TypeError('Arrays are not supported by deepExtend');
	  }

	  for (var prop in b) {
	    if (b.hasOwnProperty(prop)) {
	      if (b[prop] && b[prop].constructor === Object) {
	        if (a[prop] === undefined) {
	          a[prop] = {};
	        }
	        if (a[prop].constructor === Object) {
	          deepExtend(a[prop], b[prop]);
	        } else {
	          a[prop] = b[prop];
	        }
	      } else if (Array.isArray(b[prop])) {
	        throw new TypeError('Arrays are not supported by deepExtend');
	      } else {
	        a[prop] = b[prop];
	      }
	    }
	  }
	  return a;
	};

	/**
	 * Deep test equality of all fields in two pairs of arrays or objects.
	 * @param {Array | Object} a
	 * @param {Array | Object} b
	 * @returns {boolean}
	 */
	exports.deepEqual = function deepEqual(a, b) {
	  var prop, i, len;
	  if (Array.isArray(a)) {
	    if (!Array.isArray(b)) {
	      return false;
	    }

	    if (a.length != b.length) {
	      return false;
	    }

	    for (i = 0, len = a.length; i < len; i++) {
	      if (!exports.deepEqual(a[i], b[i])) {
	        return false;
	      }
	    }
	    return true;
	  } else if (a instanceof Object) {
	    if (Array.isArray(b) || !(b instanceof Object)) {
	      return false;
	    }

	    for (prop in a) {
	      //noinspection JSUnfilteredForInLoop
	      if (!exports.deepEqual(a[prop], b[prop])) {
	        return false;
	      }
	    }
	    for (prop in b) {
	      //noinspection JSUnfilteredForInLoop
	      if (!exports.deepEqual(a[prop], b[prop])) {
	        return false;
	      }
	    }
	    return true;
	  } else {
	    return typeof a === typeof b && a == b;
	  }
	};

	/**
	 * Test whether the current JavaScript engine supports Object.defineProperty
	 * @returns {boolean} returns true if supported
	 */
	exports.canDefineProperty = function () {
	  // test needed for broken IE8 implementation
	  try {
	    if (Object.defineProperty) {
	      Object.defineProperty({}, 'x', { get: function () {} });
	      return true;
	    }
	  } catch (e) {}

	  return false;
	};

	/**
	 * Attach a lazy loading property to a constant.
	 * The given function `fn` is called once when the property is first requested.
	 * On older browsers (<IE8), the function will fall back to direct evaluation
	 * of the properties value.
	 * @param {Object} object   Object where to add the property
	 * @param {string} prop     Property name
	 * @param {Function} fn     Function returning the property value. Called
	 *                          without arguments.
	 */
	exports.lazy = function (object, prop, fn) {
	  if (exports.canDefineProperty()) {
	    var _uninitialized = true;
	    var _value;
	    Object.defineProperty(object, prop, {
	      get: function () {
	        if (_uninitialized) {
	          _value = fn();
	          _uninitialized = false;
	        }
	        return _value;
	      },

	      set: function (value) {
	        _value = value;
	        _uninitialized = false;
	      },

	      configurable: true,
	      enumerable: true
	    });
	  } else {
	    // fall back to immediate evaluation
	    object[prop] = fn();
	  }
	};

	/**
	 * Traverse a path into an object.
	 * When a namespace is missing, it will be created
	 * @param {Object} object
	 * @param {string} path   A dot separated string like 'name.space'
	 * @return {Object} Returns the object at the end of the path
	 */
	exports.traverse = function (object, path) {
	  var obj = object;

	  if (path) {
	    var names = path.split('.');
	    for (var i = 0; i < names.length; i++) {
	      var name = names[i];
	      if (!(name in obj)) {
	        obj[name] = {};
	      }
	      obj = obj[name];
	    }
	  }

	  return obj;
	};

	/**
	 * Test whether an object is a factory. a factory has fields:
	 *
	 * - factory: function (type: Object, config: Object, load: function, typed: function [, math: Object])   (required)
	 * - name: string (optional)
	 * - path: string    A dot separated path (optional)
	 * - math: boolean   If true (false by default), the math namespace is passed
	 *                   as fifth argument of the factory function
	 *
	 * @param {*} object
	 * @returns {boolean}
	 */
	exports.isFactory = function (object) {
	  return object && typeof object.factory === 'function';
	};

/***/ },
/* 70 */
/***/ function(module, exports, __webpack_require__) {

	var typedFunction = __webpack_require__(71);
	var digits = __webpack_require__(72).digits;

	// returns a new instance of typed-function
	var createTyped = function () {
	  // initially, return the original instance of typed-function
	  // consecutively, return a new instance from typed.create.
	  createTyped = typedFunction.create;
	  return typedFunction;
	};

	/**
	 * Factory function for creating a new typed instance
	 * @param {Object} type   Object with data types like Complex and BigNumber
	 * @returns {Function}
	 */
	exports.create = function create(type) {
	  // TODO: typed-function must be able to silently ignore signatures with unknown data types

	  // get a new instance of typed-function
	  var typed = createTyped();

	  // define all types. The order of the types determines in which order function
	  // arguments are type-checked (so for performance it's important to put the
	  // most used types first).
	  typed.types = [{ name: 'number', test: function (x) {
	      return typeof x === 'number';
	    } }, { name: 'Complex', test: function (x) {
	      return x && x.isComplex;
	    } }, { name: 'BigNumber', test: function (x) {
	      return x && x.isBigNumber;
	    } }, { name: 'Fraction', test: function (x) {
	      return x && x.isFraction;
	    } }, { name: 'Unit', test: function (x) {
	      return x && x.isUnit;
	    } }, { name: 'string', test: function (x) {
	      return typeof x === 'string';
	    } }, { name: 'Array', test: Array.isArray }, { name: 'Matrix', test: function (x) {
	      return x && x.isMatrix;
	    } }, { name: 'DenseMatrix', test: function (x) {
	      return x && x.isDenseMatrix;
	    } }, { name: 'SparseMatrix', test: function (x) {
	      return x && x.isSparseMatrix;
	    } }, { name: 'ImmutableDenseMatrix', test: function (x) {
	      return x && x.isImmutableDenseMatrix;
	    } }, { name: 'Range', test: function (x) {
	      return x && x.isRange;
	    } }, { name: 'Index', test: function (x) {
	      return x && x.isIndex;
	    } }, { name: 'boolean', test: function (x) {
	      return typeof x === 'boolean';
	    } }, { name: 'ResultSet', test: function (x) {
	      return x && x.isResultSet;
	    } }, { name: 'Help', test: function (x) {
	      return x && x.isHelp;
	    } }, { name: 'function', test: function (x) {
	      return typeof x === 'function';
	    } }, { name: 'Date', test: function (x) {
	      return x instanceof Date;
	    } }, { name: 'RegExp', test: function (x) {
	      return x instanceof RegExp;
	    } }, { name: 'Object', test: function (x) {
	      return typeof x === 'object';
	    } }, { name: 'null', test: function (x) {
	      return x === null;
	    } }, { name: 'undefined', test: function (x) {
	      return x === undefined;
	    } }];

	  // TODO: add conversion from BigNumber to number?
	  typed.conversions = [{
	    from: 'number',
	    to: 'BigNumber',
	    convert: function (x) {
	      // note: conversion from number to BigNumber can fail if x has >15 digits
	      if (digits(x) > 15) {
	        throw new TypeError('Cannot implicitly convert a number with >15 significant digits to BigNumber ' + '(value: ' + x + '). ' + 'Use function bignumber(x) to convert to BigNumber.');
	      }
	      return new type.BigNumber(x);
	    }
	  }, {
	    from: 'number',
	    to: 'Complex',
	    convert: function (x) {
	      return new type.Complex(x, 0);
	    }
	  }, {
	    from: 'number',
	    to: 'string',
	    convert: function (x) {
	      return x + '';
	    }
	  }, {
	    from: 'BigNumber',
	    to: 'Complex',
	    convert: function (x) {
	      return new type.Complex(x.toNumber(), 0);
	    }
	  }, {
	    from: 'Fraction',
	    to: 'Complex',
	    convert: function (x) {
	      return new type.Complex(x.valueOf(), 0);
	    }
	  }, {
	    from: 'number',
	    to: 'Fraction',
	    convert: function (x) {
	      if (digits(x) > 15) {
	        throw new TypeError('Cannot implicitly convert a number with >15 significant digits to Fraction ' + '(value: ' + x + '). ' + 'Use function fraction(x) to convert to Fraction.');
	      }
	      return new type.Fraction(x);
	    }
	  }, {
	    // FIXME: add conversion from Fraction to number, for example for `sqrt(fraction(1,3))`
	    //  from: 'Fraction',
	    //  to: 'number',
	    //  convert: function (x) {
	    //    return x.valueOf();
	    //  }
	    //}, {
	    from: 'string',
	    to: 'number',
	    convert: function (x) {
	      var n = Number(x);
	      if (isNaN(n)) {
	        throw new Error('Cannot convert "' + x + '" to a number');
	      }
	      return n;
	    }
	  }, {
	    from: 'boolean',
	    to: 'number',
	    convert: function (x) {
	      return +x;
	    }
	  }, {
	    from: 'boolean',
	    to: 'BigNumber',
	    convert: function (x) {
	      return new type.BigNumber(+x);
	    }
	  }, {
	    from: 'boolean',
	    to: 'Fraction',
	    convert: function (x) {
	      return new type.Fraction(+x);
	    }
	  }, {
	    from: 'boolean',
	    to: 'string',
	    convert: function (x) {
	      return +x;
	    }
	  }, {
	    from: 'null',
	    to: 'number',
	    convert: function () {
	      return 0;
	    }
	  }, {
	    from: 'null',
	    to: 'string',
	    convert: function () {
	      return 'null';
	    }
	  }, {
	    from: 'null',
	    to: 'BigNumber',
	    convert: function () {
	      return new type.BigNumber(0);
	    }
	  }, {
	    from: 'null',
	    to: 'Fraction',
	    convert: function () {
	      return new type.Fraction(0);
	    }
	  }, {
	    from: 'Array',
	    to: 'Matrix',
	    convert: function (array) {
	      // TODO: how to decide on the right type of matrix to create?
	      return new type.DenseMatrix(array);
	    }
	  }, {
	    from: 'Matrix',
	    to: 'Array',
	    convert: function (matrix) {
	      return matrix.valueOf();
	    }
	  }];

	  return typed;
	};

/***/ },
/* 71 */
/***/ function(module, exports, __webpack_require__) {

	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
	 * typed-function
	 *
	 * Type checking for JavaScript functions
	 *
	 * https://github.com/josdejong/typed-function
	 */
	'use strict';

	(function (root, factory) {
	  if (true) {
	    // AMD. Register as an anonymous module.
	    !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
	  } else if (typeof exports === 'object') {
	    // OldNode. Does not work with strict CommonJS, but
	    // only CommonJS-like environments that support module.exports,
	    // like OldNode.
	    module.exports = factory();
	  } else {
	    // Browser globals (root is window)
	    root.typed = factory();
	  }
	})(this, function () {
	  // factory function to create a new instance of typed-function
	  // TODO: allow passing configuration, types, tests via the factory function
	  function create() {
	    /**
	     * Get a type test function for a specific data type
	     * @param {string} name                   Name of a data type like 'number' or 'string'
	     * @returns {Function(obj: *) : boolean}  Returns a type testing function.
	     *                                        Throws an error for an unknown type.
	     */
	    function getTypeTest(name) {
	      var test;
	      for (var i = 0; i < typed.types.length; i++) {
	        var entry = typed.types[i];
	        if (entry.name === name) {
	          test = entry.test;
	          break;
	        }
	      }

	      if (!test) {
	        var hint;
	        for (i = 0; i < typed.types.length; i++) {
	          entry = typed.types[i];
	          if (entry.name.toLowerCase() == name.toLowerCase()) {
	            hint = entry.name;
	            break;
	          }
	        }

	        throw new Error('Unknown type "' + name + '"' + (hint ? '. Did you mean "' + hint + '"?' : ''));
	      }
	      return test;
	    }

	    /**
	     * Retrieve the function name from a set of functions, and check
	     * whether the name of all functions match (if given)
	     * @param {Array.<function>} fns
	     */
	    function getName(fns) {
	      var name = '';

	      for (var i = 0; i < fns.length; i++) {
	        var fn = fns[i];

	        // merge function name when this is a typed function
	        if (fn.signatures && fn.name != '') {
	          if (name == '') {
	            name = fn.name;
	          } else if (name != fn.name) {
	            var err = new Error('Function names do not match (expected: ' + name + ', actual: ' + fn.name + ')');
	            err.data = {
	              actual: fn.name,
	              expected: name
	            };
	            throw err;
	          }
	        }
	      }

	      return name;
	    }

	    /**
	     * Create an ArgumentsError. Creates messages like:
	     *
	     *   Unexpected type of argument (expected: ..., actual: ..., index: ...)
	     *   Too few arguments (expected: ..., index: ...)
	     *   Too many arguments (expected: ..., actual: ...)
	     *
	     * @param {String} fn         Function name
	     * @param {number} argCount   Number of arguments
	     * @param {Number} index      Current argument index
	     * @param {*} actual          Current argument
	     * @param {string} [expected] An optional, comma separated string with
	     *                            expected types on given index
	     * @extends Error
	     */
	    function createError(fn, argCount, index, actual, expected) {
	      var actualType = getTypeOf(actual);
	      var _expected = expected ? expected.split(',') : null;
	      var _fn = fn || 'unnamed';
	      var anyType = _expected && contains(_expected, 'any');
	      var message;
	      var data = {
	        fn: fn,
	        index: index,
	        actual: actual,
	        expected: _expected
	      };

	      if (_expected) {
	        if (argCount > index && !anyType) {
	          // unexpected type
	          message = 'Unexpected type of argument in function ' + _fn + ' (expected: ' + _expected.join(' or ') + ', actual: ' + actualType + ', index: ' + index + ')';
	        } else {
	          // too few arguments
	          message = 'Too few arguments in function ' + _fn + ' (expected: ' + _expected.join(' or ') + ', index: ' + index + ')';
	        }
	      } else {
	        // too many arguments
	        message = 'Too many arguments in function ' + _fn + ' (expected: ' + index + ', actual: ' + argCount + ')';
	      }

	      var err = new TypeError(message);
	      err.data = data;
	      return err;
	    }

	    /**
	     * Collection with function references (local shortcuts to functions)
	     * @constructor
	     * @param {string} [name='refs']  Optional name for the refs, used to generate
	     *                                JavaScript code
	     */
	    function Refs(name) {
	      this.name = name || 'refs';
	      this.categories = {};
	    }

	    /**
	     * Add a function reference.
	     * @param {Function} fn
	     * @param {string} [category='fn']    A function category, like 'fn' or 'signature'
	     * @returns {string} Returns the function name, for example 'fn0' or 'signature2'
	     */
	    Refs.prototype.add = function (fn, category) {
	      var cat = category || 'fn';
	      if (!this.categories[cat]) this.categories[cat] = [];

	      var index = this.categories[cat].indexOf(fn);
	      if (index == -1) {
	        index = this.categories[cat].length;
	        this.categories[cat].push(fn);
	      }

	      return cat + index;
	    };

	    /**
	     * Create code lines for all function references
	     * @returns {string} Returns the code containing all function references
	     */
	    Refs.prototype.toCode = function () {
	      var code = [];
	      var path = this.name + '.categories';
	      var categories = this.categories;

	      for (var cat in categories) {
	        if (categories.hasOwnProperty(cat)) {
	          var category = categories[cat];

	          for (var i = 0; i < category.length; i++) {
	            code.push('var ' + cat + i + ' = ' + path + '[\'' + cat + '\'][' + i + '];');
	          }
	        }
	      }

	      return code.join('\n');
	    };

	    /**
	     * A function parameter
	     * @param {string | string[] | Param} types    A parameter type like 'string',
	     *                                             'number | boolean'
	     * @param {boolean} [varArgs=false]            Variable arguments if true
	     * @constructor
	     */
	    function Param(types, varArgs) {
	      // parse the types, can be a string with types separated by pipe characters |
	      if (typeof types === 'string') {
	        // parse variable arguments operator (ellipses '...number')
	        var _types = types.trim();
	        var _varArgs = _types.substr(0, 3) === '...';
	        if (_varArgs) {
	          _types = _types.substr(3);
	        }
	        if (_types === '') {
	          this.types = ['any'];
	        } else {
	          this.types = _types.split('|');
	          for (var i = 0; i < this.types.length; i++) {
	            this.types[i] = this.types[i].trim();
	          }
	        }
	      } else if (Array.isArray(types)) {
	        this.types = types;
	      } else if (types instanceof Param) {
	        return types.clone();
	      } else {
	        throw new Error('String or Array expected');
	      }

	      // can hold a type to which to convert when handling this parameter
	      this.conversions = [];
	      // TODO: implement better API for conversions, be able to add conversions via constructor (support a new type Object?)

	      // variable arguments
	      this.varArgs = _varArgs || varArgs || false;

	      // check for any type arguments
	      this.anyType = this.types.indexOf('any') !== -1;
	    }

	    /**
	     * Order Params
	     * any type ('any') will be ordered last, and object as second last (as other
	     * types may be an object as well, like Array).
	     *
	     * @param {Param} a
	     * @param {Param} b
	     * @returns {number} Returns 1 if a > b, -1 if a < b, and else 0.
	     */
	    Param.compare = function (a, b) {
	      // TODO: simplify parameter comparison, it's a mess
	      if (a.anyType) return 1;
	      if (b.anyType) return -1;

	      if (contains(a.types, 'Object')) return 1;
	      if (contains(b.types, 'Object')) return -1;

	      if (a.hasConversions()) {
	        if (b.hasConversions()) {
	          var i, ac, bc;

	          for (i = 0; i < a.conversions.length; i++) {
	            if (a.conversions[i] !== undefined) {
	              ac = a.conversions[i];
	              break;
	            }
	          }

	          for (i = 0; i < b.conversions.length; i++) {
	            if (b.conversions[i] !== undefined) {
	              bc = b.conversions[i];
	              break;
	            }
	          }

	          return typed.conversions.indexOf(ac) - typed.conversions.indexOf(bc);
	        } else {
	          return 1;
	        }
	      } else {
	        if (b.hasConversions()) {
	          return -1;
	        } else {
	          // both params have no conversions
	          var ai, bi;

	          for (i = 0; i < typed.types.length; i++) {
	            if (typed.types[i].name === a.types[0]) {
	              ai = i;
	              break;
	            }
	          }

	          for (i = 0; i < typed.types.length; i++) {
	            if (typed.types[i].name === b.types[0]) {
	              bi = i;
	              break;
	            }
	          }

	          return ai - bi;
	        }
	      }
	    };

	    /**
	     * Test whether this parameters types overlap an other parameters types.
	     * @param {Param} other
	     * @return {boolean} Returns true when there are conflicting types
	     */
	    Param.prototype.overlapping = function (other) {
	      for (var i = 0; i < this.types.length; i++) {
	        if (contains(other.types, this.types[i])) {
	          return true;
	        }
	      }
	      return false;
	    };

	    /**
	     * Create a clone of this param
	     * @returns {Param} Returns a cloned version of this param
	     */
	    Param.prototype.clone = function () {
	      var param = new Param(this.types.slice(), this.varArgs);
	      param.conversions = this.conversions.slice();
	      return param;
	    };

	    /**
	     * Test whether this parameter contains conversions
	     * @returns {boolean} Returns true if the parameter contains one or
	     *                    multiple conversions.
	     */
	    Param.prototype.hasConversions = function () {
	      return this.conversions.length > 0;
	    };

	    /**
	     * Tests whether this parameters contains any of the provided types
	     * @param {Object} types  A Map with types, like {'number': true}
	     * @returns {boolean}     Returns true when the parameter contains any
	     *                        of the provided types
	     */
	    Param.prototype.contains = function (types) {
	      for (var i = 0; i < this.types.length; i++) {
	        if (types[this.types[i]]) {
	          return true;
	        }
	      }
	      return false;
	    };

	    /**
	     * Return a string representation of this params types, like 'string' or
	     * 'number | boolean' or '...number'
	     * @param {boolean} [toConversion]   If true, the returned types string
	     *                                   contains the types where the parameter
	     *                                   will convert to. If false (default)
	     *                                   the "from" types are returned
	     * @returns {string}
	     */
	    Param.prototype.toString = function (toConversion) {
	      var types = [];
	      var keys = {};

	      for (var i = 0; i < this.types.length; i++) {
	        var conversion = this.conversions[i];
	        var type = toConversion && conversion ? conversion.to : this.types[i];
	        if (!(type in keys)) {
	          keys[type] = true;
	          types.push(type);
	        }
	      }

	      return (this.varArgs ? '...' : '') + types.join('|');
	    };

	    /**
	     * A function signature
	     * @param {string | string[] | Param[]} params
	     *                         Array with the type(s) of each parameter,
	     *                         or a comma separated string with types
	     * @param {Function} fn    The actual function
	     * @constructor
	     */
	    function Signature(params, fn) {
	      var _params;
	      if (typeof params === 'string') {
	        _params = params !== '' ? params.split(',') : [];
	      } else if (Array.isArray(params)) {
	        _params = params;
	      } else {
	        throw new Error('string or Array expected');
	      }

	      this.params = new Array(_params.length);
	      for (var i = 0; i < _params.length; i++) {
	        var param = new Param(_params[i]);
	        this.params[i] = param;
	        if (i === _params.length - 1) {
	          // the last argument
	          this.varArgs = param.varArgs;
	        } else {
	          // non-last argument
	          if (param.varArgs) {
	            throw new SyntaxError('Unexpected variable arguments operator "..."');
	          }
	        }
	      }

	      this.fn = fn;
	    }

	    /**
	     * Create a clone of this signature
	     * @returns {Signature} Returns a cloned version of this signature
	     */
	    Signature.prototype.clone = function () {
	      return new Signature(this.params.slice(), this.fn);
	    };

	    /**
	     * Expand a signature: split params with union types in separate signatures
	     * For example split a Signature "string | number" into two signatures.
	     * @return {Signature[]} Returns an array with signatures (at least one)
	     */
	    Signature.prototype.expand = function () {
	      var signatures = [];

	      function recurse(signature, path) {
	        if (path.length < signature.params.length) {
	          var i, newParam, conversion;

	          var param = signature.params[path.length];
	          if (param.varArgs) {
	            // a variable argument. do not split the types in the parameter
	            newParam = param.clone();

	            // add conversions to the parameter
	            // recurse for all conversions
	            for (i = 0; i < typed.conversions.length; i++) {
	              conversion = typed.conversions[i];
	              if (!contains(param.types, conversion.from) && contains(param.types, conversion.to)) {
	                var j = newParam.types.length;
	                newParam.types[j] = conversion.from;
	                newParam.conversions[j] = conversion;
	              }
	            }

	            recurse(signature, path.concat(newParam));
	          } else {
	            // split each type in the parameter
	            for (i = 0; i < param.types.length; i++) {
	              recurse(signature, path.concat(new Param(param.types[i])));
	            }

	            // recurse for all conversions
	            for (i = 0; i < typed.conversions.length; i++) {
	              conversion = typed.conversions[i];
	              if (!contains(param.types, conversion.from) && contains(param.types, conversion.to)) {
	                newParam = new Param(conversion.from);
	                newParam.conversions[0] = conversion;
	                recurse(signature, path.concat(newParam));
	              }
	            }
	          }
	        } else {
	          signatures.push(new Signature(path, signature.fn));
	        }
	      }

	      recurse(this, []);

	      return signatures;
	    };

	    /**
	     * Compare two signatures.
	     *
	     * When two params are equal and contain conversions, they will be sorted
	     * by lowest index of the first conversions.
	     *
	     * @param {Signature} a
	     * @param {Signature} b
	     * @returns {number} Returns 1 if a > b, -1 if a < b, and else 0.
	     */
	    Signature.compare = function (a, b) {
	      if (a.params.length > b.params.length) return 1;
	      if (a.params.length < b.params.length) return -1;

	      // count the number of conversions
	      var i;
	      var len = a.params.length; // a and b have equal amount of params
	      var ac = 0;
	      var bc = 0;
	      for (i = 0; i < len; i++) {
	        if (a.params[i].hasConversions()) ac++;
	        if (b.params[i].hasConversions()) bc++;
	      }

	      if (ac > bc) return 1;
	      if (ac < bc) return -1;

	      // compare the order per parameter
	      for (i = 0; i < a.params.length; i++) {
	        var cmp = Param.compare(a.params[i], b.params[i]);
	        if (cmp !== 0) {
	          return cmp;
	        }
	      }

	      return 0;
	    };

	    /**
	     * Test whether any of the signatures parameters has conversions
	     * @return {boolean} Returns true when any of the parameters contains
	     *                   conversions.
	     */
	    Signature.prototype.hasConversions = function () {
	      for (var i = 0; i < this.params.length; i++) {
	        if (this.params[i].hasConversions()) {
	          return true;
	        }
	      }
	      return false;
	    };

	    /**
	     * Test whether this signature should be ignored.
	     * Checks whether any of the parameters contains a type listed in
	     * typed.ignore
	     * @return {boolean} Returns true when the signature should be ignored
	     */
	    Signature.prototype.ignore = function () {
	      // create a map with ignored types
	      var types = {};
	      for (var i = 0; i < typed.ignore.length; i++) {
	        types[typed.ignore[i]] = true;
	      }

	      // test whether any of the parameters contains this type
	      for (i = 0; i < this.params.length; i++) {
	        if (this.params[i].contains(types)) {
	          return true;
	        }
	      }

	      return false;
	    };

	    /**
	     * Generate the code to invoke this signature
	     * @param {Refs} refs
	     * @param {string} prefix
	     * @returns {string} Returns code
	     */
	    Signature.prototype.toCode = function (refs, prefix) {
	      var code = [];

	      var args = new Array(this.params.length);
	      for (var i = 0; i < this.params.length; i++) {
	        var param = this.params[i];
	        var conversion = param.conversions[0];
	        if (param.varArgs) {
	          args[i] = 'varArgs';
	        } else if (conversion) {
	          args[i] = refs.add(conversion.convert, 'convert') + '(arg' + i + ')';
	        } else {
	          args[i] = 'arg' + i;
	        }
	      }

	      var ref = this.fn ? refs.add(this.fn, 'signature') : undefined;
	      if (ref) {
	        return prefix + 'return ' + ref + '(' + args.join(', ') + '); // signature: ' + this.params.join(', ');
	      }

	      return code.join('\n');
	    };

	    /**
	     * Return a string representation of the signature
	     * @returns {string}
	     */
	    Signature.prototype.toString = function () {
	      return this.params.join(', ');
	    };

	    /**
	     * A group of signatures with the same parameter on given index
	     * @param {Param[]} path
	     * @param {Signature} [signature]
	     * @param {Node[]} childs
	     * @constructor
	     */
	    function Node(path, signature, childs) {
	      this.path = path || [];
	      this.param = path[path.length - 1] || null;
	      this.signature = signature || null;
	      this.childs = childs || [];
	    }

	    /**
	     * Generate code for this group of signatures
	     * @param {Refs} refs
	     * @param {string} prefix
	     * @param {Node | undefined} [anyType]  Sibling of this node with any type parameter
	     * @returns {string} Returns the code as string
	     */
	    Node.prototype.toCode = function (refs, prefix, anyType) {
	      // TODO: split this function in multiple functions, it's too large
	      var code = [];

	      if (this.param) {
	        var index = this.path.length - 1;
	        var conversion = this.param.conversions[0];
	        var comment = '// type: ' + (conversion ? conversion.from + ' (convert to ' + conversion.to + ')' : this.param);

	        // non-root node (path is non-empty)
	        if (this.param.varArgs) {
	          if (this.param.anyType) {
	            // variable arguments with any type
	            code.push(prefix + 'if (arguments.length > ' + index + ') {');
	            code.push(prefix + '  var varArgs = [];');
	            code.push(prefix + '  for (var i = ' + index + '; i < arguments.length; i++) {');
	            code.push(prefix + '    varArgs.push(arguments[i]);');
	            code.push(prefix + '  }');
	            code.push(this.signature.toCode(refs, prefix + '  '));
	            code.push(prefix + '}');
	          } else {
	            // variable arguments with a fixed type
	            var getTests = function (types, arg) {
	              var tests = [];
	              for (var i = 0; i < types.length; i++) {
	                tests[i] = refs.add(getTypeTest(types[i]), 'test') + '(' + arg + ')';
	              }
	              return tests.join(' || ');
	            }.bind(this);

	            var allTypes = this.param.types;
	            var exactTypes = [];
	            for (var i = 0; i < allTypes.length; i++) {
	              if (this.param.conversions[i] === undefined) {
	                exactTypes.push(allTypes[i]);
	              }
	            }

	            code.push(prefix + 'if (' + getTests(allTypes, 'arg' + index) + ') { ' + comment);
	            code.push(prefix + '  var varArgs = [arg' + index + '];');
	            code.push(prefix + '  for (var i = ' + (index + 1) + '; i < arguments.length; i++) {');
	            code.push(prefix + '    if (' + getTests(exactTypes, 'arguments[i]') + ') {');
	            code.push(prefix + '      varArgs.push(arguments[i]);');

	            for (var i = 0; i < allTypes.length; i++) {
	              var conversion_i = this.param.conversions[i];
	              if (conversion_i) {
	                var test = refs.add(getTypeTest(allTypes[i]), 'test');
	                var convert = refs.add(conversion_i.convert, 'convert');
	                code.push(prefix + '    }');
	                code.push(prefix + '    else if (' + test + '(arguments[i])) {');
	                code.push(prefix + '      varArgs.push(' + convert + '(arguments[i]));');
	              }
	            }
	            code.push(prefix + '    } else {');
	            code.push(prefix + '      throw createError(name, arguments.length, i, arguments[i], \'' + exactTypes.join(',') + '\');');
	            code.push(prefix + '    }');
	            code.push(prefix + '  }');
	            code.push(this.signature.toCode(refs, prefix + '  '));
	            code.push(prefix + '}');
	          }
	        } else {
	          if (this.param.anyType) {
	            // any type
	            code.push(prefix + '// type: any');
	            code.push(this._innerCode(refs, prefix, anyType));
	          } else {
	            // regular type
	            var type = this.param.types[0];
	            var test = type !== 'any' ? refs.add(getTypeTest(type), 'test') : null;

	            code.push(prefix + 'if (' + test + '(arg' + index + ')) { ' + comment);
	            code.push(this._innerCode(refs, prefix + '  ', anyType));
	            code.push(prefix + '}');
	          }
	        }
	      } else {
	        // root node (path is empty)
	        code.push(this._innerCode(refs, prefix, anyType));
	      }

	      return code.join('\n');
	    };

	    /**
	     * Generate inner code for this group of signatures.
	     * This is a helper function of Node.prototype.toCode
	     * @param {Refs} refs
	     * @param {string} prefix
	     * @param {Node | undefined} [anyType]  Sibling of this node with any type parameter
	     * @returns {string} Returns the inner code as string
	     * @private
	     */
	    Node.prototype._innerCode = function (refs, prefix, anyType) {
	      var code = [];
	      var i;

	      if (this.signature) {
	        code.push(prefix + 'if (arguments.length === ' + this.path.length + ') {');
	        code.push(this.signature.toCode(refs, prefix + '  '));
	        code.push(prefix + '}');
	      }

	      var nextAnyType;
	      for (i = 0; i < this.childs.length; i++) {
	        if (this.childs[i].param.anyType) {
	          nextAnyType = this.childs[i];
	          break;
	        }
	      }

	      for (i = 0; i < this.childs.length; i++) {
	        code.push(this.childs[i].toCode(refs, prefix, nextAnyType));
	      }

	      if (anyType && !this.param.anyType) {
	        code.push(anyType.toCode(refs, prefix, nextAnyType));
	      }

	      var exceptions = this._exceptions(refs, prefix);
	      if (exceptions) {
	        code.push(exceptions);
	      }

	      return code.join('\n');
	    };

	    /**
	     * Generate code to throw exceptions
	     * @param {Refs} refs
	     * @param {string} prefix
	     * @returns {string} Returns the inner code as string
	     * @private
	     */
	    Node.prototype._exceptions = function (refs, prefix) {
	      var index = this.path.length;

	      if (this.childs.length === 0) {
	        // TODO: can this condition be simplified? (we have a fall-through here)
	        return [prefix + 'if (arguments.length > ' + index + ') {', prefix + '  throw createError(name, arguments.length, ' + index + ', arguments[' + index + ']);', prefix + '}'].join('\n');
	      } else {
	        var keys = {};
	        var types = [];

	        for (var i = 0; i < this.childs.length; i++) {
	          var node = this.childs[i];
	          if (node.param) {
	            for (var j = 0; j < node.param.types.length; j++) {
	              var type = node.param.types[j];
	              if (!(type in keys) && !node.param.conversions[j]) {
	                keys[type] = true;
	                types.push(type);
	              }
	            }
	          }
	        }

	        return prefix + 'throw createError(name, arguments.length, ' + index + ', arguments[' + index + '], \'' + types.join(',') + '\');';
	      }
	    };

	    /**
	     * Split all raw signatures into an array with expanded Signatures
	     * @param {Object.<string, Function>} rawSignatures
	     * @return {Signature[]} Returns an array with expanded signatures
	     */
	    function parseSignatures(rawSignatures) {
	      // FIXME: need to have deterministic ordering of signatures, do not create via object
	      var signature;
	      var keys = {};
	      var signatures = [];
	      var i;

	      for (var types in rawSignatures) {
	        if (rawSignatures.hasOwnProperty(types)) {
	          var fn = rawSignatures[types];
	          signature = new Signature(types, fn);

	          if (signature.ignore()) {
	            continue;
	          }

	          var expanded = signature.expand();

	          for (i = 0; i < expanded.length; i++) {
	            var signature_i = expanded[i];
	            var key = signature_i.toString();
	            var existing = keys[key];
	            if (!existing) {
	              keys[key] = signature_i;
	            } else {
	              var cmp = Signature.compare(signature_i, existing);
	              if (cmp < 0) {
	                // override if sorted first
	                keys[key] = signature_i;
	              } else if (cmp === 0) {
	                throw new Error('Signature "' + key + '" is defined twice');
	              }
	              // else: just ignore
	            }
	          }
	        }
	      }

	      // convert from map to array
	      for (key in keys) {
	        if (keys.hasOwnProperty(key)) {
	          signatures.push(keys[key]);
	        }
	      }

	      // order the signatures
	      signatures.sort(function (a, b) {
	        return Signature.compare(a, b);
	      });

	      // filter redundant conversions from signatures with varArgs
	      // TODO: simplify this loop or move it to a separate function
	      for (i = 0; i < signatures.length; i++) {
	        signature = signatures[i];

	        if (signature.varArgs) {
	          var index = signature.params.length - 1;
	          var param = signature.params[index];

	          var t = 0;
	          while (t < param.types.length) {
	            if (param.conversions[t]) {
	              var type = param.types[t];

	              for (var j = 0; j < signatures.length; j++) {
	                var other = signatures[j];
	                var p = other.params[index];

	                if (other !== signature && p && contains(p.types, type) && !p.conversions[index]) {
	                  // this (conversion) type already exists, remove it
	                  param.types.splice(t, 1);
	                  param.conversions.splice(t, 1);
	                  t--;
	                  break;
	                }
	              }
	            }
	            t++;
	          }
	        }
	      }

	      return signatures;
	    }

	    /**
	     * create a map with normalized signatures as key and the function as value
	     * @param {Signature[]} signatures   An array with split signatures
	     * @return {Object.<string, Function>} Returns a map with normalized
	     *                                     signatures as key, and the function
	     *                                     as value.
	     */
	    function mapSignatures(signatures) {
	      var normalized = {};

	      for (var i = 0; i < signatures.length; i++) {
	        var signature = signatures[i];
	        if (signature.fn && !signature.hasConversions()) {
	          var params = signature.params.join(',');
	          normalized[params] = signature.fn;
	        }
	      }

	      return normalized;
	    }

	    /**
	     * Parse signatures recursively in a node tree.
	     * @param {Signature[]} signatures  Array with expanded signatures
	     * @param {Param[]} path            Traversed path of parameter types
	     * @return {Node}                   Returns a node tree
	     */
	    function parseTree(signatures, path) {
	      var i, signature;
	      var index = path.length;
	      var nodeSignature;

	      var filtered = [];
	      for (i = 0; i < signatures.length; i++) {
	        signature = signatures[i];

	        // filter the first signature with the correct number of params
	        if (signature.params.length === index && !nodeSignature) {
	          nodeSignature = signature;
	        }

	        if (signature.params[index] != undefined) {
	          filtered.push(signature);
	        }
	      }

	      // sort the filtered signatures by param
	      filtered.sort(function (a, b) {
	        return Param.compare(a.params[index], b.params[index]);
	      });

	      // recurse over the signatures
	      var entries = [];
	      for (i = 0; i < filtered.length; i++) {
	        signature = filtered[i];
	        // group signatures with the same param at current index
	        var param = signature.params[index];

	        // TODO: replace the next filter loop
	        var existing = entries.filter(function (entry) {
	          return entry.param.overlapping(param);
	        })[0];

	        //var existing;
	        //for (var j = 0; j < entries.length; j++) {
	        //  if (entries[j].param.overlapping(param)) {
	        //    existing = entries[j];
	        //    break;
	        //  }
	        //}

	        if (existing) {
	          if (existing.param.varArgs) {
	            throw new Error('Conflicting types "' + existing.param + '" and "' + param + '"');
	          }
	          existing.signatures.push(signature);
	        } else {
	          entries.push({
	            param: param,
	            signatures: [signature]
	          });
	        }
	      }

	      // parse the childs
	      var childs = new Array(entries.length);
	      for (i = 0; i < entries.length; i++) {
	        var entry = entries[i];
	        childs[i] = parseTree(entry.signatures, path.concat(entry.param));
	      }

	      return new Node(path, nodeSignature, childs);
	    }

	    /**
	     * Generate an array like ['arg0', 'arg1', 'arg2']
	     * @param {number} count Number of arguments to generate
	     * @returns {Array} Returns an array with argument names
	     */
	    function getArgs(count) {
	      // create an array with all argument names
	      var args = [];
	      for (var i = 0; i < count; i++) {
	        args[i] = 'arg' + i;
	      }

	      return args;
	    }

	    /**
	     * Compose a function from sub-functions each handling a single type signature.
	     * Signatures:
	     *   typed(signature: string, fn: function)
	     *   typed(name: string, signature: string, fn: function)
	     *   typed(signatures: Object.<string, function>)
	     *   typed(name: string, signatures: Object.<string, function>)
	     *
	     * @param {string | null} name
	     * @param {Object.<string, Function>} signatures
	     * @return {Function} Returns the typed function
	     * @private
	     */
	    function _typed(name, signatures) {
	      var refs = new Refs();

	      // parse signatures, expand them
	      var _signatures = parseSignatures(signatures);
	      if (_signatures.length == 0) {
	        throw new Error('No signatures provided');
	      }

	      // parse signatures into a node tree
	      var node = parseTree(_signatures, []);

	      //var util = require('util');
	      //console.log('ROOT');
	      //console.log(util.inspect(node, { depth: null }));

	      // generate code for the typed function
	      var code = [];
	      var _name = name || '';
	      var _args = getArgs(maxParams(_signatures));
	      code.push('function ' + _name + '(' + _args.join(', ') + ') {');
	      code.push('  "use strict";');
	      code.push('  var name = \'' + _name + '\';');
	      code.push(node.toCode(refs, '  '));
	      code.push('}');

	      // generate body for the factory function
	      var body = [refs.toCode(), 'return ' + code.join('\n')].join('\n');

	      // evaluate the JavaScript code and attach function references
	      var factory = new Function(refs.name, 'createError', body);
	      var fn = factory(refs, createError);

	      //console.log('FN\n' + fn.toString()); // TODO: cleanup

	      // attach the signatures with sub-functions to the constructed function
	      fn.signatures = mapSignatures(_signatures);

	      return fn;
	    }

	    /**
	     * Calculate the maximum number of parameters in givens signatures
	     * @param {Signature[]} signatures
	     * @returns {number} The maximum number of parameters
	     */
	    function maxParams(signatures) {
	      var max = 0;

	      for (var i = 0; i < signatures.length; i++) {
	        var len = signatures[i].params.length;
	        if (len > max) {
	          max = len;
	        }
	      }

	      return max;
	    }

	    /**
	     * Get the type of a value
	     * @param {*} x
	     * @returns {string} Returns a string with the type of value
	     */
	    function getTypeOf(x) {
	      var obj;

	      for (var i = 0; i < typed.types.length; i++) {
	        var entry = typed.types[i];

	        if (entry.name === 'Object') {
	          // Array and Date are also Object, so test for Object afterwards
	          obj = entry;
	        } else {
	          if (entry.test(x)) return entry.name;
	        }
	      }

	      // at last, test whether an object
	      if (obj && obj.test(x)) return obj.name;

	      return 'unknown';
	    }

	    /**
	     * Test whether an array contains some entry
	     * @param {Array} array
	     * @param {*} entry
	     * @return {boolean} Returns true if array contains entry, false if not.
	     */
	    function contains(array, entry) {
	      return array.indexOf(entry) !== -1;
	    }

	    // data type tests
	    var types = [{ name: 'number', test: function (x) {
	        return typeof x === 'number';
	      } }, { name: 'string', test: function (x) {
	        return typeof x === 'string';
	      } }, { name: 'boolean', test: function (x) {
	        return typeof x === 'boolean';
	      } }, { name: 'Function', test: function (x) {
	        return typeof x === 'function';
	      } }, { name: 'Array', test: Array.isArray }, { name: 'Date', test: function (x) {
	        return x instanceof Date;
	      } }, { name: 'RegExp', test: function (x) {
	        return x instanceof RegExp;
	      } }, { name: 'Object', test: function (x) {
	        return typeof x === 'object';
	      } }, { name: 'null', test: function (x) {
	        return x === null;
	      } }, { name: 'undefined', test: function (x) {
	        return x === undefined;
	      } }];

	    // configuration
	    var config = {};

	    // type conversions. Order is important
	    var conversions = [];

	    // types to be ignored
	    var ignore = [];

	    // temporary object for holding types and conversions, for constructing
	    // the `typed` function itself
	    // TODO: find a more elegant solution for this
	    var typed = {
	      config: config,
	      types: types,
	      conversions: conversions,
	      ignore: ignore
	    };

	    /**
	     * Construct the typed function itself with various signatures
	     *
	     * Signatures:
	     *
	     *   typed(signatures: Object.<string, function>)
	     *   typed(name: string, signatures: Object.<string, function>)
	     */
	    typed = _typed('typed', {
	      'Object': function (signatures) {
	        var fns = [];
	        for (var signature in signatures) {
	          if (signatures.hasOwnProperty(signature)) {
	            fns.push(signatures[signature]);
	          }
	        }
	        var name = getName(fns);

	        return _typed(name, signatures);
	      },
	      'string, Object': _typed,
	      // TODO: add a signature 'Array.<function>'
	      '...Function': function (fns) {
	        var err;
	        var name = getName(fns);
	        var signatures = {};

	        for (var i = 0; i < fns.length; i++) {
	          var fn = fns[i];

	          // test whether this is a typed-function
	          if (!(typeof fn.signatures === 'object')) {
	            err = new TypeError('Function is no typed-function (index: ' + i + ')');
	            err.data = { index: i };
	            throw err;
	          }

	          // merge the signatures
	          for (var signature in fn.signatures) {
	            if (fn.signatures.hasOwnProperty(signature)) {
	              if (signatures.hasOwnProperty(signature)) {
	                if (fn.signatures[signature] !== signatures[signature]) {
	                  err = new Error('Signature "' + signature + '" is defined twice');
	                  err.data = { signature: signature };
	                  throw err;
	                }
	                // else: both signatures point to the same function, that's fine
	              } else {
	                signatures[signature] = fn.signatures[signature];
	              }
	            }
	          }
	        }

	        return _typed(name, signatures);
	      }
	    });

	    /**
	     * Find a specific signature from a (composed) typed function, for
	     * example:
	     *
	     *   typed.find(fn, ['number', 'string'])
	     *   typed.find(fn, 'number, string')
	     *
	     * Function find only only works for exact matches.
	     *
	     * @param {Function} fn                   A typed-function
	     * @param {string | string[]} signature   Signature to be found, can be
	     *                                        an array or a comma separated string.
	     * @return {Function}                     Returns the matching signature, or
	     *                                        throws an errror when no signature
	     *                                        is found.
	     */
	    function find(fn, signature) {
	      if (!fn.signatures) {
	        throw new TypeError('Function is no typed-function');
	      }

	      // normalize input
	      var arr;
	      if (typeof signature === 'string') {
	        arr = signature.split(',');
	        for (var i = 0; i < arr.length; i++) {
	          arr[i] = arr[i].trim();
	        }
	      } else if (Array.isArray(signature)) {
	        arr = signature;
	      } else {
	        throw new TypeError('String array or a comma separated string expected');
	      }

	      var str = arr.join(',');

	      // find an exact match
	      var match = fn.signatures[str];
	      if (match) {
	        return match;
	      }

	      // TODO: extend find to match non-exact signatures

	      throw new TypeError('Signature not found (signature: ' + (fn.name || 'unnamed') + '(' + arr.join(', ') + '))');
	    }

	    /**
	     * Convert a given value to another data type.
	     * @param {*} value
	     * @param {string} type
	     */
	    function convert(value, type) {
	      var from = getTypeOf(value);

	      // check conversion is needed
	      if (type === from) {
	        return value;
	      }

	      for (var i = 0; i < typed.conversions.length; i++) {
	        var conversion = typed.conversions[i];
	        if (conversion.from === from && conversion.to === type) {
	          return conversion.convert(value);
	        }
	      }

	      throw new Error('Cannot convert from ' + from + ' to ' + type);
	    }

	    // attach types and conversions to the final `typed` function
	    typed.config = config;
	    typed.types = types;
	    typed.conversions = conversions;
	    typed.ignore = ignore;
	    typed.create = create;
	    typed.find = find;
	    typed.convert = convert;

	    // add a type
	    typed.addType = function (type) {
	      if (!type || typeof type.name !== 'string' || typeof type.test !== 'function') {
	        throw new TypeError('Object with properties {name: string, test: function} expected');
	      }

	      typed.types.push(type);
	    };

	    // add a conversion
	    typed.addConversion = function (conversion) {
	      if (!conversion || typeof conversion.from !== 'string' || typeof conversion.to !== 'string' || typeof conversion.convert !== 'function') {
	        throw new TypeError('Object with properties {from: string, to: string, convert: function} expected');
	      }

	      typed.conversions.push(conversion);
	    };

	    return typed;
	  }

	  return create();
	});

/***/ },
/* 72 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';

	var NumberFormatter = __webpack_require__(73);

	/**
	 * Test whether value is a number
	 * @param {*} value
	 * @return {boolean} isNumber
	 */
	exports.isNumber = function (value) {
	  return typeof value === 'number';
	};

	/**
	 * Check if a number is integer
	 * @param {number | boolean} value
	 * @return {boolean} isInteger
	 */
	exports.isInteger = function (value) {
	  return isFinite(value) ? value == Math.round(value) : false;
	  // Note: we use ==, not ===, as we can have Booleans as well
	};

	/**
	 * Calculate the sign of a number
	 * @param {number} x
	 * @returns {*}
	 */
	exports.sign = Math.sign || function (x) {
	  if (x > 0) {
	    return 1;
	  } else if (x < 0) {
	    return -1;
	  } else {
	    return 0;
	  }
	};

	/**
	 * Convert a number to a formatted string representation.
	 *
	 * Syntax:
	 *
	 *    format(value)
	 *    format(value, options)
	 *    format(value, precision)
	 *    format(value, fn)
	 *
	 * Where:
	 *
	 *    {number} value   The value to be formatted
	 *    {Object} options An object with formatting options. Available options:
	 *                     {string} notation
	 *                         Number notation. Choose from:
	 *                         'fixed'          Always use regular number notation.
	 *                                          For example '123.40' and '14000000'
	 *                         'exponential'    Always use exponential notation.
	 *                                          For example '1.234e+2' and '1.4e+7'
	 *                         'engineering'    Always use engineering notation.
	 *                                          For example '123.4e+0' and '14.0e+6'
	 *                         'auto' (default) Regular number notation for numbers
	 *                                          having an absolute value between
	 *                                          `lower` and `upper` bounds, and uses
	 *                                          exponential notation elsewhere.
	 *                                          Lower bound is included, upper bound
	 *                                          is excluded.
	 *                                          For example '123.4' and '1.4e7'.
	 *                     {number} precision   A number between 0 and 16 to round
	 *                                          the digits of the number.
	 *                                          In case of notations 'exponential' and
	 *                                          'auto', `precision` defines the total
	 *                                          number of significant digits returned
	 *                                          and is undefined by default.
	 *                                          In case of notation 'fixed',
	 *                                          `precision` defines the number of
	 *                                          significant digits after the decimal
	 *                                          point, and is 0 by default.
	 *                     {Object} exponential An object containing two parameters,
	 *                                          {number} lower and {number} upper,
	 *                                          used by notation 'auto' to determine
	 *                                          when to return exponential notation.
	 *                                          Default values are `lower=1e-3` and
	 *                                          `upper=1e5`.
	 *                                          Only applicable for notation `auto`.
	 *    {Function} fn    A custom formatting function. Can be used to override the
	 *                     built-in notations. Function `fn` is called with `value` as
	 *                     parameter and must return a string. Is useful for example to
	 *                     format all values inside a matrix in a particular way.
	 *
	 * Examples:
	 *
	 *    format(6.4);                                        // '6.4'
	 *    format(1240000);                                    // '1.24e6'
	 *    format(1/3);                                        // '0.3333333333333333'
	 *    format(1/3, 3);                                     // '0.333'
	 *    format(21385, 2);                                   // '21000'
	 *    format(12.071, {notation: 'fixed'});                // '12'
	 *    format(2.3,    {notation: 'fixed', precision: 2});  // '2.30'
	 *    format(52.8,   {notation: 'exponential'});          // '5.28e+1'
	 *    format(12345678, {notation: 'engineering'});        // '12.345678e+6'
	 *
	 * @param {number} value
	 * @param {Object | Function | number} [options]
	 * @return {string} str The formatted value
	 */
	exports.format = function (value, options) {
	  if (typeof options === 'function') {
	    // handle format(value, fn)
	    return options(value);
	  }

	  // handle special cases
	  if (value === Infinity) {
	    return 'Infinity';
	  } else if (value === -Infinity) {
	    return '-Infinity';
	  } else if (isNaN(value)) {
	    return 'NaN';
	  }

	  // default values for options
	  var notation = 'auto';
	  var precision = undefined;

	  if (options) {
	    // determine notation from options
	    if (options.notation) {
	      notation = options.notation;
	    }

	    // determine precision from options
	    if (exports.isNumber(options)) {
	      precision = options;
	    } else if (options.precision) {
	      precision = options.precision;
	    }
	  }

	  // handle the various notations
	  switch (notation) {
	    case 'fixed':
	      return exports.toFixed(value, precision);

	    case 'exponential':
	      return exports.toExponential(value, precision);

	    case 'engineering':
	      return exports.toEngineering(value, precision);

	    case 'auto':
	      return exports.toPrecision(value, precision, options && options.exponential)

	      // remove trailing zeros after the decimal point
	      .replace(/((\.\d*?)(0+))($|e)/, function () {
	        var digits = arguments[2];
	        var e = arguments[4];
	        return digits !== '.' ? digits + e : e;
	      });

	    default:
	      throw new Error('Unknown notation "' + notation + '". ' + 'Choose "auto", "exponential", or "fixed".');
	  }
	};

	/**
	 * Format a number in exponential notation. Like '1.23e+5', '2.3e+0', '3.500e-3'
	 * @param {number} value
	 * @param {number} [precision]  Number of digits in formatted output.
	 *                              If not provided, the maximum available digits
	 *                              is used.
	 * @returns {string} str
	 */
	exports.toExponential = function (value, precision) {
	  return new NumberFormatter(value).toExponential(precision);
	};

	/**
	 * Format a number in engineering notation. Like '1.23e+6', '2.3e+0', '3.500e-3'
	 * @param {number} value
	 * @param {number} [precision]  Number of digits in formatted output.
	 *                              If not provided, the maximum available digits
	 *                              is used.
	 * @returns {string} str
	 */
	exports.toEngineering = function (value, precision) {
	  return new NumberFormatter(value).toEngineering(precision);
	};

	/**
	 * Format a number with fixed notation.
	 * @param {number} value
	 * @param {number} [precision=0]        Optional number of decimals after the
	 *                                      decimal point. Zero by default.
	 */
	exports.toFixed = function (value, precision) {
	  return new NumberFormatter(value).toFixed(precision);
	};

	/**
	 * Format a number with a certain precision
	 * @param {number} value
	 * @param {number} [precision=undefined] Optional number of digits.
	 * @param {{lower: number, upper: number}} [options]  By default:
	 *                                                    lower = 1e-3 (excl)
	 *                                                    upper = 1e+5 (incl)
	 * @return {string}
	 */
	exports.toPrecision = function (value, precision, options) {
	  return new NumberFormatter(value).toPrecision(precision, options);
	};

	/**
	 * Count the number of significant digits of a number.
	 *
	 * For example:
	 *   2.34 returns 3
	 *   0.0034 returns 2
	 *   120.5e+30 returns 4
	 *
	 * @param {number} value
	 * @return {number} digits   Number of significant digits
	 */
	exports.digits = function (value) {
	  return value.toExponential().replace(/e.*$/, '') // remove exponential notation
	  .replace(/^0\.?0*|\./, '') // remove decimal point and leading zeros
	  .length;
	};

	/**
	 * Minimum number added to one that makes the result different than one
	 */
	exports.DBL_EPSILON = Number.EPSILON || 2.2204460492503130808472633361816E-16;

	/**
	 * Compares two floating point numbers.
	 * @param {number} x          First value to compare
	 * @param {number} y          Second value to compare
	 * @param {number} [epsilon]  The maximum relative difference between x and y
	 *                            If epsilon is undefined or null, the function will
	 *                            test whether x and y are exactly equal.
	 * @return {boolean} whether the two numbers are nearly equal
	*/
	exports.nearlyEqual = function (x, y, epsilon) {
	  // if epsilon is null or undefined, test whether x and y are exactly equal
	  if (epsilon == null) {
	    return x == y;
	  }

	  // use "==" operator, handles infinities
	  if (x == y) {
	    return true;
	  }

	  // NaN
	  if (isNaN(x) || isNaN(y)) {
	    return false;
	  }

	  // at this point x and y should be finite
	  if (isFinite(x) && isFinite(y)) {
	    // check numbers are very close, needed when comparing numbers near zero
	    var diff = Math.abs(x - y);
	    if (diff < exports.DBL_EPSILON) {
	      return true;
	    } else {
	      // use relative error
	      return diff <= Math.max(Math.abs(x), Math.abs(y)) * epsilon;
	    }
	  }

	  // Infinite and Number or negative Infinite and positive Infinite cases
	  return false;
	};

/***/ },
/* 73 */
/***/ function(module, exports) {

	'use strict';

	/**
	 * Format a number using methods toPrecision, toFixed, toExponential.
	 * @param {number | string} value
	 * @constructor
	 */

	function NumberFormatter(value) {
	  // parse the input value
	  var match = String(value).toLowerCase().match(/^0*?(-?)(\d+\.?\d*)(e([+-]?\d+))?$/);
	  if (!match) {
	    throw new SyntaxError('Invalid number');
	  }

	  var sign = match[1];
	  var coefficients = match[2];
	  var exponent = parseFloat(match[4] || '0');

	  var dot = coefficients.indexOf('.');
	  exponent += dot !== -1 ? dot - 1 : coefficients.length - 1;

	  this.sign = sign;
	  this.coefficients = coefficients.replace('.', '') // remove the dot (must be removed before removing leading zeros)
	  .replace(/^0*/, function (zeros) {
	    // remove leading zeros, add their count to the exponent
	    exponent -= zeros.length;
	    return '';
	  }).replace(/0*$/, '') // remove trailing zeros
	  .split('').map(function (d) {
	    return parseInt(d);
	  });

	  if (this.coefficients.length === 0) {
	    this.coefficients.push(0);
	    exponent++;
	  }

	  this.exponent = exponent;
	}

	/**
	 * Format a number with engineering notation.
	 * @param {number} [precision=0]        Optional number of decimals after the
	 *                                      decimal point. Zero by default.
	 */
	NumberFormatter.prototype.toEngineering = function (precision) {
	  var rounded = this.roundDigits(precision);

	  var e = rounded.exponent;
	  var c = rounded.coefficients;

	  // find nearest lower multiple of 3 for exponent
	  var newExp = e % 3 === 0 ? e : e < 0 ? e - 3 - e % 3 : e - e % 3;

	  // concatenate coefficients with necessary zeros
	  var significandsDiff = e >= 0 ? e : Math.abs(newExp);

	  // add zeros if necessary (for ex: 1e+8)
	  if (c.length - 1 < significandsDiff) c = c.concat(zeros(significandsDiff - (c.length - 1)));

	  // find difference in exponents
	  var expDiff = Math.abs(e - newExp);

	  var decimalIdx = 1;
	  var str = '';

	  // push decimal index over by expDiff times
	  while (--expDiff >= 0) decimalIdx++;

	  // if all coefficient values are zero after the decimal point, don't add a decimal value.
	  // otherwise concat with the rest of the coefficients
	  var decimals = c.slice(decimalIdx).join('');
	  var decimalVal = decimals.match(/[1-9]/) ? '.' + decimals : '';

	  str = c.slice(0, decimalIdx).join('') + decimalVal;

	  str += 'e' + (e >= 0 ? '+' : '') + newExp.toString();
	  return rounded.sign + str;
	};

	/**
	 * Format a number with fixed notation.
	 * @param {number} [precision=0]        Optional number of decimals after the
	 *                                      decimal point. Zero by default.
	 */
	NumberFormatter.prototype.toFixed = function (precision) {
	  var rounded = this.roundDigits(this.exponent + 1 + (precision || 0));
	  var c = rounded.coefficients;
	  var p = rounded.exponent + 1; // exponent may have changed

	  // append zeros if needed
	  var pp = p + (precision || 0);
	  if (c.length < pp) {
	    c = c.concat(zeros(pp - c.length));
	  }

	  // prepend zeros if needed
	  if (p < 0) {
	    c = zeros(-p + 1).concat(c);
	    p = 1;
	  }

	  // insert a dot if needed
	  if (precision) {
	    c.splice(p, 0, p === 0 ? '0.' : '.');
	  }

	  return this.sign + c.join('');
	};

	/**
	 * Format a number in exponential notation. Like '1.23e+5', '2.3e+0', '3.500e-3'
	 * @param {number} [precision]  Number of digits in formatted output.
	 *                              If not provided, the maximum available digits
	 *                              is used.
	 */
	NumberFormatter.prototype.toExponential = function (precision) {
	  // round if needed, else create a clone
	  var rounded = precision ? this.roundDigits(precision) : this.clone();
	  var c = rounded.coefficients;
	  var e = rounded.exponent;

	  // append zeros if needed
	  if (c.length < precision) {
	    c = c.concat(zeros(precision - c.length));
	  }

	  // format as `C.CCCe+EEE` or `C.CCCe-EEE`
	  var first = c.shift();
	  return this.sign + first + (c.length > 0 ? '.' + c.join('') : '') + 'e' + (e >= 0 ? '+' : '') + e;
	};

	/**
	 * Format a number with a certain precision
	 * @param {number} [precision=undefined] Optional number of digits.
	 * @param {{lower: number | undefined, upper: number | undefined}} [options]
	 *                                       By default:
	 *                                         lower = 1e-3 (excl)
	 *                                         upper = 1e+5 (incl)
	 * @return {string}
	 */
	NumberFormatter.prototype.toPrecision = function (precision, options) {
	  // determine lower and upper bound for exponential notation.
	  var lower = options && options.lower !== undefined ? options.lower : 1e-3;
	  var upper = options && options.upper !== undefined ? options.upper : 1e+5;

	  var abs = Math.abs(Math.pow(10, this.exponent));
	  if (abs < lower || abs >= upper) {
	    // exponential notation
	    return this.toExponential(precision);
	  } else {
	    var rounded = precision ? this.roundDigits(precision) : this.clone();
	    var c = rounded.coefficients;
	    var e = rounded.exponent;

	    // append trailing zeros
	    if (c.length < precision) {
	      c = c.concat(zeros(precision - c.length));
	    }

	    // append trailing zeros
	    // TODO: simplify the next statement
	    c = c.concat(zeros(e - c.length + 1 + (c.length < precision ? precision - c.length : 0)));

	    // prepend zeros
	    c = zeros(-e).concat(c);

	    var dot = e > 0 ? e : 0;
	    if (dot < c.length - 1) {
	      c.splice(dot + 1, 0, '.');
	    }

	    return this.sign + c.join('');
	  }
	};

	/**
	 * Crete a clone of the NumberFormatter
	 * @return {NumberFormatter} Returns a clone of the NumberFormatter
	 */
	NumberFormatter.prototype.clone = function () {
	  var clone = new NumberFormatter('0');
	  clone.sign = this.sign;
	  clone.coefficients = this.coefficients.slice(0);
	  clone.exponent = this.exponent;
	  return clone;
	};

	/**
	 * Round the number of digits of a number *
	 * @param {number} precision  A positive integer
	 * @return {NumberFormatter}  Returns a new NumberFormatter with the rounded
	 *                            digits
	 */
	NumberFormatter.prototype.roundDigits = function (precision) {
	  var rounded = this.clone();
	  var c = rounded.coefficients;

	  // prepend zeros if needed
	  while (precision <= 0) {
	    c.unshift(0);
	    rounded.exponent++;
	    precision++;
	  }

	  if (c.length > precision) {
	    var removed = c.splice(precision, c.length - precision);

	    if (removed[0] >= 5) {
	      var i = precision - 1;
	      c[i]++;
	      while (c[i] === 10) {
	        c.pop();
	        if (i === 0) {
	          c.unshift(0);
	          rounded.exponent++;
	          i++;
	        }
	        i--;
	        c[i]++;
	      }
	    }
	  }

	  return rounded;
	};

	/**
	 * Create an array filled with zeros.
	 * @param {number} length
	 * @return {Array}
	 */
	function zeros(length) {
	  var arr = [];
	  for (var i = 0; i < length; i++) {
	    arr.push(0);
	  }
	  return arr;
	}

	module.exports = NumberFormatter;

/***/ },
/* 74 */
/***/ function(module, exports, __webpack_require__) {

	var Emitter = __webpack_require__(75);

	/**
	 * Extend given object with emitter functions `on`, `off`, `once`, `emit`
	 * @param {Object} obj
	 * @return {Object} obj
	 */
	exports.mixin = function (obj) {
	  // create event emitter
	  var emitter = new Emitter();

	  // bind methods to obj (we don't want to expose the emitter.e Array...)
	  obj.on = emitter.on.bind(emitter);
	  obj.off = emitter.off.bind(emitter);
	  obj.once = emitter.once.bind(emitter);
	  obj.emit = emitter.emit.bind(emitter);

	  return obj;
	};

/***/ },
/* 75 */
/***/ function(module, exports) {

	function E() {
	  // Keep this empty so it's easier to inherit from
	  // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)
	}

	E.prototype = {
	  on: function (name, callback, ctx) {
	    var e = this.e || (this.e = {});

	    (e[name] || (e[name] = [])).push({
	      fn: callback,
	      ctx: ctx
	    });

	    return this;
	  },

	  once: function (name, callback, ctx) {
	    var self = this;
	    function listener() {
	      self.off(name, listener);
	      callback.apply(ctx, arguments);
	    };

	    listener._ = callback;
	    return this.on(name, listener, ctx);
	  },

	  emit: function (name) {
	    var data = [].slice.call(arguments, 1);
	    var evtArr = ((this.e || (this.e = {}))[name] || []).slice();
	    var i = 0;
	    var len = evtArr.length;

	    for (i; i < len; i++) {
	      evtArr[i].fn.apply(evtArr[i].ctx, data);
	    }

	    return this;
	  },

	  off: function (name, callback) {
	    var e = this.e || (this.e = {});
	    var evts = e[name];
	    var liveEvents = [];

	    if (evts && callback) {
	      for (var i = 0, len = evts.length; i < len; i++) {
	        if (evts[i].fn !== callback && evts[i].fn._ !== callback) liveEvents.push(evts[i]);
	      }
	    }

	    // Remove event from queue to prevent memory leak
	    // Suggested by https://github.com/lazd
	    // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910

	    liveEvents.length ? e[name] = liveEvents : delete e[name];

	    return this;
	  }
	};

		module.exports = E;

/***/ },
/* 76 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';

	var lazy = __webpack_require__(69).lazy;
	var isFactory = __webpack_require__(69).isFactory;
	var traverse = __webpack_require__(69).traverse;
	var extend = __webpack_require__(69).extend;
	var ArgumentsError = __webpack_require__(77);

	function factory(type, config, load, typed, math) {
	  /**
	   * Import functions from an object or a module
	   *
	   * Syntax:
	   *
	   *    math.import(object)
	   *    math.import(object, options)
	   *
	   * Where:
	   *
	   * - `object: Object`
	   *   An object with functions to be imported.
	   * - `options: Object` An object with import options. Available options:
	   *   - `override: boolean`
	   *     If true, existing functions will be overwritten. False by default.
	   *   - `silent: boolean`
	   *     If true, the function will not throw errors on duplicates or invalid
	   *     types. False by default.
	   *   - `wrap: boolean`
	   *     If true, the functions will be wrapped in a wrapper function
	   *     which converts data types like Matrix to primitive data types like Array.
	   *     The wrapper is needed when extending math.js with libraries which do not
	   *     support these data type. False by default.
	   *
	   * Examples:
	   *
	   *    // define new functions and variables
	   *    math.import({
	   *      myvalue: 42,
	   *      hello: function (name) {
	   *        return 'hello, ' + name + '!';
	   *      }
	   *    });
	   *
	   *    // use the imported function and variable
	   *    math.myvalue * 2;               // 84
	   *    math.hello('user');             // 'hello, user!'
	   *
	   *    // import the npm module 'numbers'
	   *    // (must be installed first with `npm install numbers`)
	   *    math.import(require('numbers'), {wrap: true});
	   *
	   *    math.fibonacci(7); // returns 13
	   *
	   * @param {Object | Array} object   Object with functions to be imported.
	   * @param {Object} [options]        Import options.
	   */
	  function math_import(object, options) {
	    var num = arguments.length;
	    if (num != 1 && num != 2) {
	      throw new ArgumentsError('import', num, 1, 2);
	    }

	    if (!options) {
	      options = {};
	    }

	    if (isFactory(object)) {
	      _importFactory(object, options);
	    }
	    // TODO: allow a typed-function with name too
	    else if (Array.isArray(object)) {
	        object.forEach(function (entry) {
	          math_import(entry, options);
	        });
	      } else if (typeof object === 'object') {
	        // a map with functions
	        for (var name in object) {
	          if (object.hasOwnProperty(name)) {
	            var value = object[name];
	            if (isSupportedType(value)) {
	              _import(name, value, options);
	            } else if (isFactory(object)) {
	              _importFactory(object, options);
	            } else {
	              math_import(value, options);
	            }
	          }
	        }
	      } else {
	        if (!options.silent) {
	          throw new TypeError('Factory, Object, or Array expected');
	        }
	      }
	  }

	  /**
	   * Add a property to the math namespace and create a chain proxy for it.
	   * @param {string} name
	   * @param {*} value
	   * @param {Object} options  See import for a description of the options
	   * @private
	   */
	  function _import(name, value, options) {
	    if (options.wrap && typeof value === 'function') {
	      // create a wrapper around the function
	      value = _wrap(value);
	    }

	    if (isTypedFunction(math[name]) && isTypedFunction(value)) {
	      if (options.override) {
	        // give the typed function the right name
	        value = typed(name, value.signatures);
	      } else {
	        // merge the existing and typed function
	        value = typed(math[name], value);
	      }

	      math[name] = value;
	      _importTransform(name, value);
	      math.emit('import', name, function resolver() {
	        return value;
	      });
	      return;
	    }

	    if (math[name] === undefined || options.override) {
	      math[name] = value;
	      _importTransform(name, value);
	      math.emit('import', name, function resolver() {
	        return value;
	      });
	      return;
	    }

	    if (!options.silent) {
	      throw new Error('Cannot import "' + name + '": already exists');
	    }
	  }

	  function _importTransform(name, value) {
	    if (value && typeof value.transform === 'function') {
	      math.expression.transform[name] = value.transform;
	    }
	  }

	  /**
	   * Create a wrapper a round an function which converts the arguments
	   * to their primitive values (like convert a Matrix to Array)
	   * @param {Function} fn
	   * @return {Function} Returns the wrapped function
	   * @private
	   */
	  function _wrap(fn) {
	    var wrapper = function wrapper() {
	      var args = [];
	      for (var i = 0, len = arguments.length; i < len; i++) {
	        var arg = arguments[i];
	        args[i] = arg && arg.valueOf();
	      }
	      return fn.apply(math, args);
	    };

	    if (fn.transform) {
	      wrapper.transform = fn.transform;
	    }

	    return wrapper;
	  }

	  /**
	   * Import an instance of a factory into math.js
	   * @param {{factory: Function, name: string, path: string, math: boolean}} factory
	   * @param {Object} options  See import for a description of the options
	   * @private
	   */
	  function _importFactory(factory, options) {
	    if (typeof factory.name === 'string') {
	      var name = factory.name;
	      var namespace = factory.path ? traverse(math, factory.path) : math;
	      var existing = namespace.hasOwnProperty(name) ? namespace[name] : undefined;

	      var resolver = function () {
	        var instance = load(factory);

	        if (isTypedFunction(existing) && isTypedFunction(instance)) {
	          if (options.override) {
	            // replace the existing typed function (nothing to do)
	          } else {
	            // merge the existing and new typed function
	            instance = typed(existing, instance);
	          }

	          return instance;
	        }

	        if (existing === undefined || options.override) {
	          return instance;
	        }

	        if (!options.silent) {
	          throw new Error('Cannot import "' + name + '": already exists');
	        }
	      };

	      if (factory.lazy !== false) {
	        lazy(namespace, name, resolver);
	      } else {
	        namespace[name] = resolver();
	      }

	      math.emit('import', name, resolver, factory.path);
	    } else {
	      // unnamed factory.
	      // no lazy loading
	      load(factory);
	    }
	  }

	  /**
	   * Check whether given object is a type which can be imported
	   * @param {Function | number | string | boolean | null | Unit | Complex} object
	   * @return {boolean}
	   * @private
	   */
	  function isSupportedType(object) {
	    return typeof object == 'function' || typeof object === 'number' || typeof object === 'string' || typeof object === 'boolean' || object === null || object && object.isUnit === true || object && object.isComplex === true || object && object.isBigNumber === true || object && object.isFraction === true || object && object.isMatrix === true || object && Array.isArray(object) === true;
	  }

	  /**
	   * Test whether a given thing is a typed-function
	   * @param {*} fn
	   * @return {boolean} Returns true when `fn` is a typed-function
	   */
	  function isTypedFunction(fn) {
	    return typeof fn === 'function' && typeof fn.signatures === 'object';
	  }

	  return math_import;
	}

	exports.math = true; // request access to the math namespace as 5th argument of the factory function
	exports.name = 'import';
	exports.factory = factory;
	exports.lazy = true;

/***/ },
/* 77 */
/***/ function(module, exports) {

	'use strict';

	/**
	 * Create a syntax error with the message:
	 *     'Wrong number of arguments in function <fn> (<count> provided, <min>-<max> expected)'
	 * @param {string} fn     Function name
	 * @param {number} count  Actual argument count
	 * @param {number} min    Minimum required argument count
	 * @param {number} [max]  Maximum required argument count
	 * @extends Error
	 */

	function ArgumentsError(fn, count, min, max) {
	  if (!(this instanceof ArgumentsError)) {
	    throw new SyntaxError('Constructor must be called with the new operator');
	  }

	  this.fn = fn;
	  this.count = count;
	  this.min = min;
	  this.max = max;

	  this.message = 'Wrong number of arguments in function ' + fn + ' (' + count + ' provided, ' + min + (max != undefined ? '-' + max : '') + ' expected)';

	  this.stack = new Error().stack;
	}

	ArgumentsError.prototype = new Error();
	ArgumentsError.prototype.constructor = Error;
	ArgumentsError.prototype.name = 'ArgumentsError';
	ArgumentsError.prototype.isArgumentsError = true;

	module.exports = ArgumentsError;

/***/ },
/* 78 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';

	var object = __webpack_require__(69);

	function factory(type, config, load, typed, math) {
	  var MATRIX = ['Matrix', 'Array']; // valid values for option matrix
	  var NUMBER = ['number', 'BigNumber', 'Fraction']; // valid values for option number

	  /**
	   * Set configuration options for math.js, and get current options.
	   * Will emit a 'config' event, with arguments (curr, prev).
	   *
	   * Syntax:
	   *
	   *     math.config(config: Object): Object
	   *
	   * Examples:
	   *
	   *     math.config().number;                // outputs 'number'
	   *     math.eval('0.4');                    // outputs number 0.4
	   *     math.config({number: 'Fraction'});
	   *     math.eval('0.4');                    // outputs Fraction 2/5
	   *
	   * @param {Object} [options] Available options:
	   *                            {number} epsilon
	   *                              Minimum relative difference between two
	   *                              compared values, used by all comparison functions.
	   *                            {string} matrix
	   *                              A string 'Matrix' (default) or 'Array'.
	   *                            {string} number
	   *                              A string 'number' (default), 'BigNumber', or 'Fraction'
	   *                            {number} precision
	   *                              The number of significant digits for BigNumbers.
	   *                              Not applicable for Numbers.
	   *                            {string} parenthesis
	   *                              How to display parentheses in LaTeX and string
	   *                              output.
	   * @return {Object} Returns the current configuration
	   */
	  function _config(options) {
	    if (options) {
	      var prev = object.clone(config);

	      // validate some of the options
	      validateOption(options, 'matrix', MATRIX);
	      validateOption(options, 'number', NUMBER);

	      // merge options
	      object.deepExtend(config, options);

	      var curr = object.clone(config);

	      // emit 'config' event
	      math.emit('config', curr, prev);

	      return curr;
	    } else {
	      return object.clone(config);
	    }
	  }

	  // attach the valid options to the function so they can be extended
	  _config.MATRIX = MATRIX;
	  _config.NUMBER = NUMBER;

	  return _config;
	}

	/**
	 * Test whether an Array contains a specific item.
	 * @param {Array.<string>} array
	 * @param {string} item
	 * @return {boolean}
	 */
	function contains(array, item) {
	  return array.indexOf(item) !== -1;
	}

	/**
	 * Find a string in an array. Case insensitive search
	 * @param {Array.<string>} array
	 * @param {string} item
	 * @return {number} Returns the index when found. Returns -1 when not found
	 */
	function findIndex(array, item) {
	  return array.map(function (i) {
	    return i.toLowerCase();
	  }).indexOf(item.toLowerCase());
	}

	/**
	 * Validate an option
	 * @param {Object} options         Object with options
	 * @param {string} name            Name of the option to validate
	 * @param {Array.<string>} values  Array with valid values for this option
	 */
	function validateOption(options, name, values) {
	  if (options[name] !== undefined && !contains(values, options[name])) {
	    var index = findIndex(values, options[name]);
	    if (index !== -1) {
	      // right value, wrong casing
	      // TODO: lower case values are deprecated since v3, remove this warning some day.
	      console.warn('Warning: Wrong casing for configuration option "' + name + '", should be "' + values[index] + '" instead of "' + options[name] + '".');

	      options[name] = values[index]; // change the option to the right casing
	    } else {
	      // unknown value
	      console.warn('Warning: Unknown value "' + options[name] + '" for configuration option "' + name + '". Available options: ' + values.map(JSON.stringify).join(', ') + '.');
	    }
	  }
	}

	exports.name = 'config';
	exports.math = true; // request the math namespace as fifth argument
	exports.factory = factory;

/***/ },
/* 79 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';

	var deepMap = __webpack_require__(80);

	function factory(type, config, load, typed) {
	  var gamma = load(__webpack_require__(81));
	  var latex = __webpack_require__(89);

	  /**
	   * Compute the factorial of a value
	   *
	   * Factorial only supports an integer value as argument.
	   * For matrices, the function is evaluated element wise.
	   *
	   * Syntax:
	   *
	   *    math.factorial(n)
	   *
	   * Examples:
	   *
	   *    math.factorial(5);    // returns 120
	   *    math.factorial(3);    // returns 6
	   *
	   * See also:
	   *
	   *    combinations, gamma, permutations
	   *
	   * @param {number | BigNumber | Array | Matrix} n   An integer number
	   * @return {number | BigNumber | Array | Matrix}    The factorial of `n`
	   */
	  var factorial = typed('factorial', {
	    'number': function (n) {
	      if (n < 0) {
	        throw new Error('Value must be non-negative');
	      }

	      return gamma(n + 1);
	    },

	    'BigNumber': function (n) {
	      if (n.isNegative()) {
	        throw new Error('Value must be non-negative');
	      }

	      return gamma(n.plus(1));
	    },

	    'Array | Matrix': function (n) {
	      return deepMap(n, factorial);
	    }
	  });

	  factorial.toTex = {
	    1: '\\left(${args[0]}\\right)' + latex.operators['factorial']
	  };

	  return factorial;
	}

	exports.name = 'factorial';
	exports.factory = factory;

/***/ },
/* 80 */
/***/ function(module, exports) {

	'use strict';

	/**
	 * Execute the callback function element wise for each element in array and any
	 * nested array
	 * Returns an array with the results
	 * @param {Array | Matrix} array
	 * @param {Function} callback   The callback is called with two parameters:
	 *                              value1 and value2, which contain the current
	 *                              element of both arrays.
	 * @param {boolean} [skipZeros] Invoke callback function for non-zero values only.
	 *
	 * @return {Array | Matrix} res
	 */

	module.exports = function deepMap(array, callback, skipZeros) {
	  if (array && typeof array.map === 'function') {
	    // TODO: replace array.map with a for loop to improve performance
	    return array.map(function (x) {
	      return deepMap(x, callback, skipZeros);
	    });
	  } else {
	    return callback(array);
	  }
	};

/***/ },
/* 81 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';

	var deepMap = __webpack_require__(80);
	var isInteger = __webpack_require__(72).isInteger;

	function factory(type, config, load, typed) {
	  var multiply = load(__webpack_require__(82));
	  var pow = load(__webpack_require__(97));

	  /**
	   * Compute the gamma function of a value using Lanczos approximation for
	   * small values, and an extended Stirling approximation for large values.
	   *
	   * For matrices, the function is evaluated element wise.
	   *
	   * Syntax:
	   *
	   *    math.gamma(n)
	   *
	   * Examples:
	   *
	   *    math.gamma(5);       // returns 24
	   *    math.gamma(-0.5);    // returns -3.5449077018110335
	   *    math.gamma(math.i);  // returns -0.15494982830180973 - 0.49801566811835596i
	   *
	   * See also:
	   *
	   *    combinations, factorial, permutations
	   *
	   * @param {number | Array | Matrix} n   A real or complex number
	   * @return {number | Array | Matrix}    The gamma of `n`
	   */
	  var gamma = typed('gamma', {
	    'number': function (n) {
	      var t, x;

	      if (isInteger(n)) {
	        if (n <= 0) {
	          return isFinite(n) ? Infinity : NaN;
	        }

	        if (n > 171) {
	          return Infinity; // Will overflow
	        }

	        var value = n - 2;
	        var res = n - 1;
	        while (value > 1) {
	          res *= value;
	          value--;
	        }

	        if (res == 0) {
	          res = 1; // 0! is per definition 1
	        }

	        return res;
	      }

	      if (n < 0.5) {
	        return Math.PI / (Math.sin(Math.PI * n) * gamma(1 - n));
	      }

	      if (n >= 171.35) {
	        return Infinity; // will overflow
	      }

	      if (n > 85.0) {
	        // Extended Stirling Approx
	        var twoN = n * n;
	        var threeN = twoN * n;
	        var fourN = threeN * n;
	        var fiveN = fourN * n;
	        return Math.sqrt(2 * Math.PI / n) * Math.pow(n / Math.E, n) * (1 + 1 / (12 * n) + 1 / (288 * twoN) - 139 / (51840 * threeN) - 571 / (2488320 * fourN) + 163879 / (209018880 * fiveN) + 5246819 / (75246796800 * fiveN * n));
	      }

	      --n;
	      x = p[0];
	      for (var i = 1; i < p.length; ++i) {
	        x += p[i] / (n + i);
	      }

	      t = n + g + 0.5;
	      return Math.sqrt(2 * Math.PI) * Math.pow(t, n + 0.5) * Math.exp(-t) * x;
	    },

	    'Complex': function (n) {
	      var t, x;

	      if (n.im == 0) {
	        return gamma(n.re);
	      }

	      n = new type.Complex(n.re - 1, n.im);
	      x = new type.Complex(p[0], 0);
	      for (var i = 1; i < p.length; ++i) {
	        var real = n.re + i; // x += p[i]/(n+i)
	        var den = real * real + n.im * n.im;
	        if (den != 0) {
	          x.re += p[i] * real / den;
	          x.im += -(p[i] * n.im) / den;
	        } else {
	          x.re = p[i] < 0 ? -Infinity : Infinity;
	        }
	      }

	      t = new type.Complex(n.re + g + 0.5, n.im);
	      var twoPiSqrt = Math.sqrt(2 * Math.PI);

	      n.re += 0.5;
	      var result = pow(t, n);
	      if (result.im == 0) {
	        // sqrt(2*PI)*result
	        result.re *= twoPiSqrt;
	      } else if (result.re == 0) {
	        result.im *= twoPiSqrt;
	      } else {
	        result.re *= twoPiSqrt;
	        result.im *= twoPiSqrt;
	      }

	      var r = Math.exp(-t.re); // exp(-t)
	      t.re = r * Math.cos(-t.im);
	      t.im = r * Math.sin(-t.im);

	      return multiply(multiply(result, t), x);
	    },

	    'BigNumber': function (n) {
	      if (n.isInteger()) {
	        return n.isNegative() || n.isZero() ? new type.BigNumber(Infinity) : bigFactorial(n.minus(1));
	      }

	      if (!n.isFinite()) {
	        return new type.BigNumber(n.isNegative() ? NaN : Infinity);
	      }

	      throw new Error('Integer BigNumber expected');
	    },

	    'Array | Matrix': function (n) {
	      return deepMap(n, gamma);
	    }
	  });

	  /**
	   * Calculate factorial for a BigNumber
	   * @param {BigNumber} n
	   * @returns {BigNumber} Returns the factorial of n
	   */
	  function bigFactorial(n) {
	    if (n.isZero()) {
	      return new type.BigNumber(1); // 0! is per definition 1
	    }

	    var precision = config.precision + (Math.log(n.toNumber()) | 0);
	    var Big = type.BigNumber.clone({ precision: precision });

	    var res = new Big(n);
	    var value = n.toNumber() - 1; // number
	    while (value > 1) {
	      res = res.times(value);
	      value--;
	    }

	    return new type.BigNumber(res.toPrecision(type.BigNumber.precision));
	  }

	  gamma.toTex = { 1: '\\Gamma\\left(${args[0]}\\right)' };

	  return gamma;
	}

	// TODO: comment on the variables g and p

	var g = 4.7421875;

	var p = [0.99999999999999709182, 57.156235665862923517, -59.597960355475491248, 14.136097974741747174, -0.49191381609762019978, 0.33994649984811888699e-4, 0.46523628927048575665e-4, -0.98374475304879564677e-4, 0.15808870322491248884e-3, -0.21026444172410488319e-3, 0.21743961811521264320e-3, -0.16431810653676389022e-3, 0.84418223983852743293e-4, -0.26190838401581408670e-4, 0.36899182659531622704e-5];

	exports.name = 'gamma';
	exports.factory = factory;

/***/ },
/* 82 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';

	var extend = __webpack_require__(69).extend;
	var array = __webpack_require__(83);

	function factory(type, config, load, typed) {
	  var latex = __webpack_require__(89);

	  var matrix = load(__webpack_require__(90));
	  var addScalar = load(__webpack_require__(91));
	  var multiplyScalar = load(__webpack_require__(92));
	  var equalScalar = load(__webpack_require__(93));

	  var algorithm11 = load(__webpack_require__(95));
	  var algorithm14 = load(__webpack_require__(96));

	  var DenseMatrix = type.DenseMatrix;
	  var SparseMatrix = type.SparseMatrix;

	  /**
	   * Multiply two values, `x * y`.
	   * For matrices, the matrix product is calculated.
	   *
	   * Syntax:
	   *
	   *    math.multiply(x, y)
	   *
	   * Examples:
	   *
	   *    math.multiply(4, 5.2);        // returns number 20.8
	   *
	   *    var a = math.complex(2, 3);
	   *    var b = math.complex(4, 1);
	   *    math.multiply(a, b);          // returns Complex 5 + 14i
	   *
	   *    var c = [[1, 2], [4, 3]];
	   *    var d = [[1, 2, 3], [3, -4, 7]];
	   *    math.multiply(c, d);          // returns Array [[7, -6, 17], [13, -4, 33]]
	   *
	   *    var e = math.unit('2.1 km');
	   *    math.multiply(3, e);          // returns Unit 6.3 km
	   *
	   * See also:
	   *
	   *    divide
	   *
	   * @param  {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} x First value to multiply
	   * @param  {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} y Second value to multiply
	   * @return {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} Multiplication of `x` and `y`
	   */
	  var multiply = typed('multiply', extend({
	    // we extend the signatures of multiplyScalar with signatures dealing with matrices

	    'Array, Array': function (x, y) {
	      // check dimensions
	      _validateMatrixDimensions(array.size(x), array.size(y));

	      // use dense matrix implementation
	      var m = multiply(matrix(x), matrix(y));
	      // return array or scalar
	      return m && m.isMatrix === true ? m.valueOf() : m;
	    },

	    'Matrix, Matrix': function (x, y) {
	      // dimensions
	      var xsize = x.size();
	      var ysize = y.size();

	      // check dimensions
	      _validateMatrixDimensions(xsize, ysize);

	      // process dimensions
	      if (xsize.length === 1) {
	        // process y dimensions
	        if (ysize.length === 1) {
	          // Vector * Vector
	          return _multiplyVectorVector(x, y, xsize[0]);
	        }
	        // Vector * Matrix
	        return _multiplyVectorMatrix(x, y);
	      }
	      // process y dimensions
	      if (ysize.length === 1) {
	        // Matrix * Vector
	        return _multiplyMatrixVector(x, y);
	      }
	      // Matrix * Matrix
	      return _multiplyMatrixMatrix(x, y);
	    },

	    'Matrix, Array': function (x, y) {
	      // use Matrix * Matrix implementation
	      return multiply(x, matrix(y));
	    },

	    'Array, Matrix': function (x, y) {
	      // use Matrix * Matrix implementation
	      return multiply(matrix(x, y.storage()), y);
	    },

	    'Matrix, any': function (x, y) {
	      // result
	      var c;

	      // process storage format
	      switch (x.storage()) {
	        case 'sparse':
	          c = algorithm11(x, y, multiplyScalar, false);
	          break;
	        case 'dense':
	          c = algorithm14(x, y, multiplyScalar, false);
	          break;
	      }
	      return c;
	    },

	    'any, Matrix': function (x, y) {
	      // result
	      var c;
	      // check storage format
	      switch (y.storage()) {
	        case 'sparse':
	          c = algorithm11(y, x, multiplyScalar, true);
	          break;
	        case 'dense':
	          c = algorithm14(y, x, multiplyScalar, true);
	          break;
	      }
	      return c;
	    },

	    'Array, any': function (x, y) {
	      // use matrix implementation
	      return algorithm14(matrix(x), y, multiplyScalar, false).valueOf();
	    },

	    'any, Array': function (x, y) {
	      // use matrix implementation
	      return algorithm14(matrix(y), x, multiplyScalar, true).valueOf();
	    }
	  }, multiplyScalar.signatures));

	  var _validateMatrixDimensions = function (size1, size2) {
	    // check left operand dimensions
	    switch (size1.length) {
	      case 1:
	        // check size2
	        switch (size2.length) {
	          case 1:
	            // Vector x Vector
	            if (size1[0] !== size2[0]) {
	              // throw error
	              throw new RangeError('Dimension mismatch in multiplication. Vectors must have the same length');
	            }
	            break;
	          case 2:
	            // Vector x Matrix
	            if (size1[0] !== size2[0]) {
	              // throw error
	              throw new RangeError('Dimension mismatch in multiplication. Vector length (' + size1[0] + ') must match Matrix rows (' + size2[0] + ')');
	            }
	            break;
	          default:
	            throw new Error('Can only multiply a 1 or 2 dimensional matrix (Matrix B has ' + size2.length + ' dimensions)');
	        }
	        break;
	      case 2:
	        // check size2
	        switch (size2.length) {
	          case 1:
	            // Matrix x Vector
	            if (size1[1] !== size2[0]) {
	              // throw error
	              throw new RangeError('Dimension mismatch in multiplication. Matrix columns (' + size1[1] + ') must match Vector length (' + size2[0] + ')');
	            }
	            break;
	          case 2:
	            // Matrix x Matrix
	            if (size1[1] !== size2[0]) {
	              // throw error
	              throw new RangeError('Dimension mismatch in multiplication. Matrix A columns (' + size1[1] + ') must match Matrix B rows (' + size2[0] + ')');
	            }
	            break;
	          default:
	            throw new Error('Can only multiply a 1 or 2 dimensional matrix (Matrix B has ' + size2.length + ' dimensions)');
	        }
	        break;
	      default:
	        throw new Error('Can only multiply a 1 or 2 dimensional matrix (Matrix A has ' + size1.length + ' dimensions)');
	    }
	  };

	  /**
	   * C = A * B
	   *
	   * @param {Matrix} a            Dense Vector   (N)
	   * @param {Matrix} b            Dense Vector   (N)
	   *
	   * @return {number}             Scalar value
	   */
	  var _multiplyVectorVector = function (a, b, n) {
	    // check empty vector
	    if (n === 0) throw new Error('Cannot multiply two empty vectors');

	    // a dense
	    var adata = a._data;
	    var adt = a._datatype;
	    // b dense
	    var bdata = b._data;
	    var bdt = b._datatype;

	    // datatype
	    var dt;
	    // addScalar signature to use
	    var af = addScalar;
	    // multiplyScalar signature to use
	    var mf = multiplyScalar;

	    // process data types
	    if (adt && bdt && adt === bdt && typeof adt === 'string') {
	      // datatype
	      dt = adt;
	      // find signatures that matches (dt, dt)
	      af = typed.find(addScalar, [dt, dt]);
	      mf = typed.find(multiplyScalar, [dt, dt]);
	    }

	    // result (do not initialize it with zero)
	    var c = mf(adata[0], bdata[0]);
	    // loop data
	    for (var i = 1; i < n; i++) {
	      // multiply and accumulate
	      c = af(c, mf(adata[i], bdata[i]));
	    }
	    return c;
	  };

	  /**
	   * C = A * B
	   *
	   * @param {Matrix} a            Dense Vector   (M)
	   * @param {Matrix} b            Matrix         (MxN)
	   *
	   * @return {Matrix}             Dense Vector   (N)
	   */
	  var _multiplyVectorMatrix = function (a, b) {
	    // process storage
	    switch (b.storage()) {
	      case 'dense':
	        return _multiplyVectorDenseMatrix(a, b);
	    }
	    throw new Error('Not implemented');
	  };

	  /**
	   * C = A * B
	   *
	   * @param {Matrix} a            Dense Vector   (M)
	   * @param {Matrix} b            Dense Matrix   (MxN)
	   *
	   * @return {Matrix}             Dense Vector   (N)
	   */
	  var _multiplyVectorDenseMatrix = function (a, b) {
	    // a dense
	    var adata = a._data;
	    var asize = a._size;
	    var adt = a._datatype;
	    // b dense
	    var bdata = b._data;
	    var bsize = b._size;
	    var bdt = b._datatype;
	    // rows & columns
	    var alength = asize[0];
	    var bcolumns = bsize[1];

	    // datatype
	    var dt;
	    // addScalar signature to use
	    var af = addScalar;
	    // multiplyScalar signature to use
	    var mf = multiplyScalar;

	    // process data types
	    if (adt && bdt && adt === bdt && typeof adt === 'string') {
	      // datatype
	      dt = adt;
	      // find signatures that matches (dt, dt)
	      af = typed.find(addScalar, [dt, dt]);
	      mf = typed.find(multiplyScalar, [dt, dt]);
	    }

	    // result
	    var c = [];

	    // loop matrix columns
	    for (var j = 0; j < bcolumns; j++) {
	      // sum (do not initialize it with zero)
	      var sum = mf(adata[0], bdata[0][j]);
	      // loop vector
	      for (var i = 1; i < alength; i++) {
	        // multiply & accumulate
	        sum = af(sum, mf(adata[i], bdata[i][j]));
	      }
	      c[j] = sum;
	    }

	    // return matrix
	    return new DenseMatrix({
	      data: c,
	      size: [bcolumns],
	      datatype: dt
	    });
	  };

	  /**
	   * C = A * B
	   *
	   * @param {Matrix} a            Matrix         (MxN)
	   * @param {Matrix} b            Dense Vector   (N)
	   *
	   * @return {Matrix}             Dense Vector   (M)
	   */
	  var _multiplyMatrixVector = function (a, b) {
	    // process storage
	    switch (a.storage()) {
	      case 'dense':
	        return _multiplyDenseMatrixVector(a, b);
	      case 'sparse':
	        return _multiplySparseMatrixVector(a, b);
	    }
	  };

	  /**
	   * C = A * B
	   *
	   * @param {Matrix} a            Matrix         (MxN)
	   * @param {Matrix} b            Matrix         (NxC)
	   *
	   * @return {Matrix}             Matrix         (MxC)
	   */
	  var _multiplyMatrixMatrix = function (a, b) {
	    // process storage
	    switch (a.storage()) {
	      case 'dense':
	        // process storage
	        switch (b.storage()) {
	          case 'dense':
	            return _multiplyDenseMatrixDenseMatrix(a, b);
	          case 'sparse':
	            return _multiplyDenseMatrixSparseMatrix(a, b);
	        }
	        break;
	      case 'sparse':
	        // process storage
	        switch (b.storage()) {
	          case 'dense':
	            return _multiplySparseMatrixDenseMatrix(a, b);
	          case 'sparse':
	            return _multiplySparseMatrixSparseMatrix(a, b);
	        }
	        break;
	    }
	  };

	  /**
	   * C = A * B
	   *
	   * @param {Matrix} a            DenseMatrix  (MxN)
	   * @param {Matrix} b            Dense Vector (N)
	   *
	   * @return {Matrix}             Dense Vector (M)
	   */
	  var _multiplyDenseMatrixVector = function (a, b) {
	    // a dense
	    var adata = a._data;
	    var asize = a._size;
	    var adt = a._datatype;
	    // b dense
	    var bdata = b._data;
	    var bdt = b._datatype;
	    // rows & columns
	    var arows = asize[0];
	    var acolumns = asize[1];

	    // datatype
	    var dt;
	    // addScalar signature to use
	    var af = addScalar;
	    // multiplyScalar signature to use
	    var mf = multiplyScalar;

	    // process data types
	    if (adt && bdt && adt === bdt && typeof adt === 'string') {
	      // datatype
	      dt = adt;
	      // find signatures that matches (dt, dt)
	      af = typed.find(addScalar, [dt, dt]);
	      mf = typed.find(multiplyScalar, [dt, dt]);
	    }

	    // result
	    var c = [];

	    // loop matrix a rows
	    for (var i = 0; i < arows; i++) {
	      // current row
	      var row = adata[i];
	      // sum (do not initialize it with zero)
	      var sum = mf(row[0], bdata[0]);
	      // loop matrix a columns
	      for (var j = 1; j < acolumns; j++) {
	        // multiply & accumulate
	        sum = af(sum, mf(row[j], bdata[j]));
	      }
	      c[i] = sum;
	    }

	    // return matrix
	    return new DenseMatrix({
	      data: c,
	      size: [arows],
	      datatype: dt
	    });
	  };

	  /**
	   * C = A * B
	   *
	   * @param {Matrix} a            DenseMatrix    (MxN)
	   * @param {Matrix} b            DenseMatrix    (NxC)
	   *
	   * @return {Matrix}             DenseMatrix    (MxC)
	   */
	  var _multiplyDenseMatrixDenseMatrix = function (a, b) {
	    // a dense
	    var adata = a._data;
	    var asize = a._size;
	    var adt = a._datatype;
	    // b dense
	    var bdata = b._data;
	    var bsize = b._size;
	    var bdt = b._datatype;
	    // rows & columns
	    var arows = asize[0];
	    var acolumns = asize[1];
	    var bcolumns = bsize[1];

	    // datatype
	    var dt;
	    // addScalar signature to use
	    var af = addScalar;
	    // multiplyScalar signature to use
	    var mf = multiplyScalar;

	    // process data types
	    if (adt && bdt && adt === bdt && typeof adt === 'string') {
	      // datatype
	      dt = adt;
	      // find signatures that matches (dt, dt)
	      af = typed.find(addScalar, [dt, dt]);
	      mf = typed.find(multiplyScalar, [dt, dt]);
	    }

	    // result
	    var c = [];

	    // loop matrix a rows
	    for (var i = 0; i < arows; i++) {
	      // current row
	      var row = adata[i];
	      // initialize row array
	      c[i] = [];
	      // loop matrix b columns
	      for (var j = 0; j < bcolumns; j++) {
	        // sum (avoid initializing sum to zero)
	        var sum = mf(row[0], bdata[0][j]);
	        // loop matrix a columns
	        for (var x = 1; x < acolumns; x++) {
	          // multiply & accumulate
	          sum = af(sum, mf(row[x], bdata[x][j]));
	        }
	        c[i][j] = sum;
	      }
	    }

	    // return matrix
	    return new DenseMatrix({
	      data: c,
	      size: [arows, bcolumns],
	      datatype: dt
	    });
	  };

	  /**
	   * C = A * B
	   *
	   * @param {Matrix} a            DenseMatrix    (MxN)
	   * @param {Matrix} b            SparseMatrix   (NxC)
	   *
	   * @return {Matrix}             SparseMatrix   (MxC)
	   */
	  var _multiplyDenseMatrixSparseMatrix = function (a, b) {
	    // a dense
	    var adata = a._data;
	    var asize = a._size;
	    var adt = a._datatype;
	    // b sparse
	    var bvalues = b._values;
	    var bindex = b._index;
	    var bptr = b._ptr;
	    var bsize = b._size;
	    var bdt = b._datatype;
	    // validate b matrix
	    if (!bvalues) throw new Error('Cannot multiply Dense Matrix times Pattern only Matrix');
	    // rows & columns
	    var arows = asize[0];
	    var bcolumns = bsize[1];

	    // datatype
	    var dt;
	    // addScalar signature to use
	    var af = addScalar;
	    // multiplyScalar signature to use
	    var mf = multiplyScalar;
	    // equalScalar signature to use
	    var eq = equalScalar;
	    // zero value
	    var zero = 0;

	    // process data types
	    if (adt && bdt && adt === bdt && typeof adt === 'string') {
	      // datatype
	      dt = adt;
	      // find signatures that matches (dt, dt)
	      af = typed.find(addScalar, [dt, dt]);
	      mf = typed.find(multiplyScalar, [dt, dt]);
	      eq = typed.find(equalScalar, [dt, dt]);
	      // convert 0 to the same datatype
	      zero = typed.convert(0, dt);
	    }

	    // result
	    var cvalues = [];
	    var cindex = [];
	    var cptr = [];
	    // c matrix
	    var c = new SparseMatrix({
	      values: cvalues,
	      index: cindex,
	      ptr: cptr,
	      size: [arows, bcolumns],
	      datatype: dt
	    });

	    // loop b columns
	    for (var jb = 0; jb < bcolumns; jb++) {
	      // update ptr
	      cptr[jb] = cindex.length;
	      // indeces in column jb
	      var kb0 = bptr[jb];
	      var kb1 = bptr[jb + 1];
	      // do not process column jb if no data exists
	      if (kb1 > kb0) {
	        // last row mark processed
	        var last = 0;
	        // loop a rows
	        for (var i = 0; i < arows; i++) {
	          // column mark
	          var mark = i + 1;
	          // C[i, jb]
	          var cij;
	          // values in b column j
	          for (var kb = kb0; kb < kb1; kb++) {
	            // row
	            var ib = bindex[kb];
	            // check value has been initialized
	            if (last !== mark) {
	              // first value in column jb
	              cij = mf(adata[i][ib], bvalues[kb]);
	              // update mark
	              last = mark;
	            } else {
	              // accumulate value
	              cij = af(cij, mf(adata[i][ib], bvalues[kb]));
	            }
	          }
	          // check column has been processed and value != 0
	          if (last === mark && !eq(cij, zero)) {
	            // push row & value
	            cindex.push(i);
	            cvalues.push(cij);
	          }
	        }
	      }
	    }
	    // update ptr
	    cptr[bcolumns] = cindex.length;

	    // return sparse matrix
	    return c;
	  };

	  /**
	   * C = A * B
	   *
	   * @param {Matrix} a            SparseMatrix    (MxN)
	   * @param {Matrix} b            Dense Vector (N)
	   *
	   * @return {Matrix}             SparseMatrix    (M, 1)
	   */
	  var _multiplySparseMatrixVector = function (a, b) {
	    // a sparse
	    var avalues = a._values;
	    var aindex = a._index;
	    var aptr = a._ptr;
	    var adt = a._datatype;
	    // validate a matrix
	    if (!avalues) throw new Error('Cannot multiply Pattern only Matrix times Dense Matrix');
	    // b dense
	    var bdata = b._data;
	    var bdt = b._datatype;
	    // rows & columns
	    var arows = a._size[0];
	    var brows = b._size[0];
	    // result
	    var cvalues = [];
	    var cindex = [];
	    var cptr = [];

	    // datatype
	    var dt;
	    // addScalar signature to use
	    var af = addScalar;
	    // multiplyScalar signature to use
	    var mf = multiplyScalar;
	    // equalScalar signature to use
	    var eq = equalScalar;
	    // zero value
	    var zero = 0;

	    // process data types
	    if (adt && bdt && adt === bdt && typeof adt === 'string') {
	      // datatype
	      dt = adt;
	      // find signatures that matches (dt, dt)
	      af = typed.find(addScalar, [dt, dt]);
	      mf = typed.find(multiplyScalar, [dt, dt]);
	      eq = typed.find(equalScalar, [dt, dt]);
	      // convert 0 to the same datatype
	      zero = typed.convert(0, dt);
	    }

	    // workspace
	    var x = [];
	    // vector with marks indicating a value x[i] exists in a given column
	    var w = [];

	    // update ptr
	    cptr[0] = 0;
	    // rows in b
	    for (var ib = 0; ib < brows; ib++) {
	      // b[ib]
	      var vbi = bdata[ib];
	      // check b[ib] != 0, avoid loops
	      if (!eq(vbi, zero)) {
	        // A values & index in ib column
	        for (var ka0 = aptr[ib], ka1 = aptr[ib + 1], ka = ka0; ka < ka1; ka++) {
	          // a row
	          var ia = aindex[ka];
	          // check value exists in current j
	          if (!w[ia]) {
	            // ia is new entry in j
	            w[ia] = true;
	            // add i to pattern of C
	            cindex.push(ia);
	            // x(ia) = A
	            x[ia] = mf(vbi, avalues[ka]);
	          } else {
	            // i exists in C already
	            x[ia] = af(x[ia], mf(vbi, avalues[ka]));
	          }
	        }
	      }
	    }
	    // copy values from x to column jb of c
	    for (var p1 = cindex.length, p = 0; p < p1; p++) {
	      // row
	      var ic = cindex[p];
	      // copy value
	      cvalues[p] = x[ic];
	    }
	    // update ptr
	    cptr[1] = cindex.length;

	    // return sparse matrix
	    return new SparseMatrix({
	      values: cvalues,
	      index: cindex,
	      ptr: cptr,
	      size: [arows, 1],
	      datatype: dt
	    });
	  };

	  /**
	   * C = A * B
	   *
	   * @param {Matrix} a            SparseMatrix      (MxN)
	   * @param {Matrix} b            DenseMatrix       (NxC)
	   *
	   * @return {Matrix}             SparseMatrix      (MxC)
	   */
	  var _multiplySparseMatrixDenseMatrix = function (a, b) {
	    // a sparse
	    var avalues = a._values;
	    var aindex = a._index;
	    var aptr = a._ptr;
	    var adt = a._datatype;
	    // validate a matrix
	    if (!avalues) throw new Error('Cannot multiply Pattern only Matrix times Dense Matrix');
	    // b dense
	    var bdata = b._data;
	    var bdt = b._datatype;
	    // rows & columns
	    var arows = a._size[0];
	    var brows = b._size[0];
	    var bcolumns = b._size[1];

	    // datatype
	    var dt;
	    // addScalar signature to use
	    var af = addScalar;
	    // multiplyScalar signature to use
	    var mf = multiplyScalar;
	    // equalScalar signature to use
	    var eq = equalScalar;
	    // zero value
	    var zero = 0;

	    // process data types
	    if (adt && bdt && adt === bdt && typeof adt === 'string') {
	      // datatype
	      dt = adt;
	      // find signatures that matches (dt, dt)
	      af = typed.find(addScalar, [dt, dt]);
	      mf = typed.find(multiplyScalar, [dt, dt]);
	      eq = typed.find(equalScalar, [dt, dt]);
	      // convert 0 to the same datatype
	      zero = typed.convert(0, dt);
	    }

	    // result
	    var cvalues = [];
	    var cindex = [];
	    var cptr = [];
	    // c matrix
	    var c = new SparseMatrix({
	      values: cvalues,
	      index: cindex,
	      ptr: cptr,
	      size: [arows, bcolumns],
	      datatype: dt
	    });

	    // workspace
	    var x = [];
	    // vector with marks indicating a value x[i] exists in a given column
	    var w = [];

	    // loop b columns
	    for (var jb = 0; jb < bcolumns; jb++) {
	      // update ptr
	      cptr[jb] = cindex.length;
	      // mark in workspace for current column
	      var mark = jb + 1;
	      // rows in jb
	      for (var ib = 0; ib < brows; ib++) {
	        // b[ib, jb]
	        var vbij = bdata[ib][jb];
	        // check b[ib, jb] != 0, avoid loops
	        if (!eq(vbij, zero)) {
	          // A values & index in ib column
	          for (var ka0 = aptr[ib], ka1 = aptr[ib + 1], ka = ka0; ka < ka1; ka++) {
	            // a row
	            var ia = aindex[ka];
	            // check value exists in current j
	            if (w[ia] !== mark) {
	              // ia is new entry in j
	              w[ia] = mark;
	              // add i to pattern of C
	              cindex.push(ia);
	              // x(ia) = A
	              x[ia] = mf(vbij, avalues[ka]);
	            } else {
	              // i exists in C already
	              x[ia] = af(x[ia], mf(vbij, avalues[ka]));
	            }
	          }
	        }
	      }
	      // copy values from x to column jb of c
	      for (var p0 = cptr[jb], p1 = cindex.length, p = p0; p < p1; p++) {
	        // row
	        var ic = cindex[p];
	        // copy value
	        cvalues[p] = x[ic];
	      }
	    }
	    // update ptr
	    cptr[bcolumns] = cindex.length;

	    // return sparse matrix
	    return c;
	  };

	  /**
	   * C = A * B
	   *
	   * @param {Matrix} a            SparseMatrix      (MxN)
	   * @param {Matrix} b            SparseMatrix      (NxC)
	   *
	   * @return {Matrix}             SparseMatrix      (MxC)
	   */
	  var _multiplySparseMatrixSparseMatrix = function (a, b) {
	    // a sparse
	    var avalues = a._values;
	    var aindex = a._index;
	    var aptr = a._ptr;
	    var adt = a._datatype;
	    // b sparse
	    var bvalues = b._values;
	    var bindex = b._index;
	    var bptr = b._ptr;
	    var bdt = b._datatype;

	    // rows & columns
	    var arows = a._size[0];
	    var bcolumns = b._size[1];
	    // flag indicating both matrices (a & b) contain data
	    var values = avalues && bvalues;

	    // datatype
	    var dt;
	    // addScalar signature to use
	    var af = addScalar;
	    // multiplyScalar signature to use
	    var mf = multiplyScalar;

	    // process data types
	    if (adt && bdt && adt === bdt && typeof adt === 'string') {
	      // datatype
	      dt = adt;
	      // find signatures that matches (dt, dt)
	      af = typed.find(addScalar, [dt, dt]);
	      mf = typed.find(multiplyScalar, [dt, dt]);
	    }

	    // result
	    var cvalues = values ? [] : undefined;
	    var cindex = [];
	    var cptr = [];
	    // c matrix
	    var c = new SparseMatrix({
	      values: cvalues,
	      index: cindex,
	      ptr: cptr,
	      size: [arows, bcolumns],
	      datatype: dt
	    });

	    // workspace
	    var x = values ? [] : undefined;
	    // vector with marks indicating a value x[i] exists in a given column
	    var w = [];
	    // variables
	    var ka, ka0, ka1, kb, kb0, kb1, ia, ib;
	    // loop b columns
	    for (var jb = 0; jb < bcolumns; jb++) {
	      // update ptr
	      cptr[jb] = cindex.length;
	      // mark in workspace for current column
	      var mark = jb + 1;
	      // B values & index in j
	      for (kb0 = bptr[jb], kb1 = bptr[jb + 1], kb = kb0; kb < kb1; kb++) {
	        // b row
	        ib = bindex[kb];
	        // check we need to process values
	        if (values) {
	          // loop values in a[:,ib]
	          for (ka0 = aptr[ib], ka1 = aptr[ib + 1], ka = ka0; ka < ka1; ka++) {
	            // row
	            ia = aindex[ka];
	            // check value exists in current j
	            if (w[ia] !== mark) {
	              // ia is new entry in j
	              w[ia] = mark;
	              // add i to pattern of C
	              cindex.push(ia);
	              // x(ia) = A
	              x[ia] = mf(bvalues[kb], avalues[ka]);
	            } else {
	              // i exists in C already
	              x[ia] = af(x[ia], mf(bvalues[kb], avalues[ka]));
	            }
	          }
	        } else {
	          // loop values in a[:,ib]
	          for (ka0 = aptr[ib], ka1 = aptr[ib + 1], ka = ka0; ka < ka1; ka++) {
	            // row
	            ia = aindex[ka];
	            // check value exists in current j
	            if (w[ia] !== mark) {
	              // ia is new entry in j
	              w[ia] = mark;
	              // add i to pattern of C
	              cindex.push(ia);
	            }
	          }
	        }
	      }
	      // check we need to process matrix values (pattern matrix)
	      if (values) {
	        // copy values from x to column jb of c
	        for (var p0 = cptr[jb], p1 = cindex.length, p = p0; p < p1; p++) {
	          // row
	          var ic = cindex[p];
	          // copy value
	          cvalues[p] = x[ic];
	        }
	      }
	    }
	    // update ptr
	    cptr[bcolumns] = cindex.length;

	    // return sparse matrix
	    return c;
	  };

	  multiply.toTex = {
	    2: '\\left(${args[0]}' + latex.operators['multiply'] + '${args[1]}\\right)'
	  };

	  return multiply;
	}

	exports.name = 'multiply';
	exports.factory = factory;

/***/ },
/* 83 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';

	var number = __webpack_require__(72);
	var string = __webpack_require__(84);
	var object = __webpack_require__(69);
	var types = __webpack_require__(86);

	var DimensionError = __webpack_require__(87);
	var IndexError = __webpack_require__(88);

	/**
	 * Calculate the size of a multi dimensional array.
	 * This function checks the size of the first entry, it does not validate
	 * whether all dimensions match. (use function `validate` for that)
	 * @param {Array} x
	 * @Return {Number[]} size
	 */
	exports.size = function (x) {
	  var s = [];

	  while (Array.isArray(x)) {
	    s.push(x.length);
	    x = x[0];
	  }

	  return s;
	};

	/**
	 * Recursively validate whether each element in a multi dimensional array
	 * has a size corresponding to the provided size array.
	 * @param {Array} array    Array to be validated
	 * @param {number[]} size  Array with the size of each dimension
	 * @param {number} dim   Current dimension
	 * @throws DimensionError
	 * @private
	 */
	function _validate(array, size, dim) {
	  var i;
	  var len = array.length;

	  if (len != size[dim]) {
	    throw new DimensionError(len, size[dim]);
	  }

	  if (dim < size.length - 1) {
	    // recursively validate each child array
	    var dimNext = dim + 1;
	    for (i = 0; i < len; i++) {
	      var child = array[i];
	      if (!Array.isArray(child)) {
	        throw new DimensionError(size.length - 1, size.length, '<');
	      }
	      _validate(array[i], size, dimNext);
	    }
	  } else {
	    // last dimension. none of the childs may be an array
	    for (i = 0; i < len; i++) {
	      if (Array.isArray(array[i])) {
	        throw new DimensionError(size.length + 1, size.length, '>');
	      }
	    }
	  }
	}

	/**
	 * Validate whether each element in a multi dimensional array has
	 * a size corresponding to the provided size array.
	 * @param {Array} array    Array to be validated
	 * @param {number[]} size  Array with the size of each dimension
	 * @throws DimensionError
	 */
	exports.validate = function (array, size) {
	  var isScalar = size.length == 0;
	  if (isScalar) {
	    // scalar
	    if (Array.isArray(array)) {
	      throw new DimensionError(array.length, 0);
	    }
	  } else {
	    // array
	    _validate(array, size, 0);
	  }
	};

	/**
	 * Test whether index is an integer number with index >= 0 and index < length
	 * when length is provided
	 * @param {number} index    Zero-based index
	 * @param {number} [length] Length of the array
	 */
	exports.validateIndex = function (index, length) {
	  if (!number.isNumber(index) || !number.isInteger(index)) {
	    throw new TypeError('Index must be an integer (value: ' + index + ')');
	  }
	  if (index < 0 || typeof length === 'number' && index >= length) {
	    throw new IndexError(index, length);
	  }
	};

	// a constant used to specify an undefined defaultValue
	exports.UNINITIALIZED = {};

	/**
	 * Resize a multi dimensional array. The resized array is returned.
	 * @param {Array} array         Array to be resized
	 * @param {Array.<number>} size Array with the size of each dimension
	 * @param {*} [defaultValue=0]  Value to be filled in in new entries,
	 *                              zero by default. To leave new entries undefined,
	 *                              specify array.UNINITIALIZED as defaultValue
	 * @return {Array} array         The resized array
	 */
	exports.resize = function (array, size, defaultValue) {
	  // TODO: add support for scalars, having size=[] ?

	  // check the type of the arguments
	  if (!Array.isArray(array) || !Array.isArray(size)) {
	    throw new TypeError('Array expected');
	  }
	  if (size.length === 0) {
	    throw new Error('Resizing to scalar is not supported');
	  }

	  // check whether size contains positive integers
	  size.forEach(function (value) {
	    if (!number.isNumber(value) || !number.isInteger(value) || value < 0) {
	      throw new TypeError('Invalid size, must contain positive integers ' + '(size: ' + string.format(size) + ')');
	    }
	  });

	  // recursively resize the array
	  var _defaultValue = defaultValue !== undefined ? defaultValue : 0;
	  _resize(array, size, 0, _defaultValue);

	  return array;
	};

	/**
	 * Recursively resize a multi dimensional array
	 * @param {Array} array         Array to be resized
	 * @param {number[]} size       Array with the size of each dimension
	 * @param {number} dim          Current dimension
	 * @param {*} [defaultValue]    Value to be filled in in new entries,
	 *                              undefined by default.
	 * @private
	 */
	function _resize(array, size, dim, defaultValue) {
	  var i;
	  var elem;
	  var oldLen = array.length;
	  var newLen = size[dim];
	  var minLen = Math.min(oldLen, newLen);

	  // apply new length
	  array.length = newLen;

	  if (dim < size.length - 1) {
	    // non-last dimension
	    var dimNext = dim + 1;

	    // resize existing child arrays
	    for (i = 0; i < minLen; i++) {
	      // resize child array
	      elem = array[i];
	      if (!Array.isArray(elem)) {
	        elem = [elem]; // add a dimension
	        array[i] = elem;
	      }
	      _resize(elem, size, dimNext, defaultValue);
	    }

	    // create new child arrays
	    for (i = minLen; i < newLen; i++) {
	      // get child array
	      elem = [];
	      array[i] = elem;

	      // resize new child array
	      _resize(elem, size, dimNext, defaultValue);
	    }
	  } else {
	    // last dimension

	    // remove dimensions of existing values
	    for (i = 0; i < minLen; i++) {
	      while (Array.isArray(array[i])) {
	        array[i] = array[i][0];
	      }
	    }

	    if (defaultValue !== exports.UNINITIALIZED) {
	      // fill new elements with the default value
	      for (i = minLen; i < newLen; i++) {
	        array[i] = defaultValue;
	      }
	    }
	  }
	}

	/**
	 * Squeeze a multi dimensional array
	 * @param {Array} array
	 * @param {Array} [size]
	 * @returns {Array} returns the array itself
	 */
	exports.squeeze = function (array, size) {
	  var s = size || exports.size(array);

	  // squeeze outer dimensions
	  while (Array.isArray(array) && array.length === 1) {
	    array = array[0];
	    s.shift();
	  }

	  // find the first dimension to be squeezed
	  var dims = s.length;
	  while (s[dims - 1] === 1) {
	    dims--;
	  }

	  // squeeze inner dimensions
	  if (dims < s.length) {
	    array = _squeeze(array, dims, 0);
	    s.length = dims;
	  }

	  return array;
	};

	/**
	 * Recursively squeeze a multi dimensional array
	 * @param {Array} array
	 * @param {number} dims Required number of dimensions
	 * @param {number} dim  Current dimension
	 * @returns {Array | *} Returns the squeezed array
	 * @private
	 */
	function _squeeze(array, dims, dim) {
	  var i, ii;

	  if (dim < dims) {
	    var next = dim + 1;
	    for (i = 0, ii = array.length; i < ii; i++) {
	      array[i] = _squeeze(array[i], dims, next);
	    }
	  } else {
	    while (Array.isArray(array)) {
	      array = array[0];
	    }
	  }

	  return array;
	}

	/**
	 * Unsqueeze a multi dimensional array: add dimensions when missing
	 *
	 * Paramter `size` will be mutated to match the new, unqueezed matrix size.
	 *
	 * @param {Array} array
	 * @param {number} dims     Desired number of dimensions of the array
	 * @param {number} [outer]  Number of outer dimensions to be added
	 * @param {Array} [size]    Current size of array.
	 * @returns {Array} returns the array itself
	 * @private
	 */
	exports.unsqueeze = function (array, dims, outer, size) {
	  var s = size || exports.size(array);

	  // unsqueeze outer dimensions
	  if (outer) {
	    for (var i = 0; i < outer; i++) {
	      array = [array];
	      s.unshift(1);
	    }
	  }

	  // unsqueeze inner dimensions
	  array = _unsqueeze(array, dims, 0);
	  while (s.length < dims) {
	    s.push(1);
	  }

	  return array;
	};

	/**
	 * Recursively unsqueeze a multi dimensional array
	 * @param {Array} array
	 * @param {number} dims Required number of dimensions
	 * @param {number} dim  Current dimension
	 * @returns {Array | *} Returns the squeezed array
	 * @private
	 */
	function _unsqueeze(array, dims, dim) {
	  var i, ii;

	  if (Array.isArray(array)) {
	    var next = dim + 1;
	    for (i = 0, ii = array.length; i < ii; i++) {
	      array[i] = _unsqueeze(array[i], dims, next);
	    }
	  } else {
	    for (var d = dim; d < dims; d++) {
	      array = [array];
	    }
	  }

	  return array;
	}
	/**
	 * Flatten a multi dimensional array, put all elements in a one dimensional
	 * array
	 * @param {Array} array   A multi dimensional array
	 * @return {Array}        The flattened array (1 dimensional)
	 */
	exports.flatten = function (array) {
	  if (!Array.isArray(array)) {
	    //if not an array, return as is
	    return array;
	  }
	  var flat = [];

	  array.forEach(function callback(value) {
	    if (Array.isArray(value)) {
	      value.forEach(callback); //traverse through sub-arrays recursively
	    } else {
	      flat.push(value);
	    }
	  });

	  return flat;
	};

	/**
	 * Test whether an object is an array
	 * @param {*} value
	 * @return {boolean} isArray
	 */
		exports.isArray = Array.isArray;

/***/ },
/* 84 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';

	var formatNumber = __webpack_require__(72).format;
	var formatBigNumber = __webpack_require__(85).format;

	/**
	 * Test whether value is a string
	 * @param {*} value
	 * @return {boolean} isString
	 */
	exports.isString = function (value) {
	  return typeof value === 'string';
	};

	/**
	 * Check if a text ends with a certain string.
	 * @param {string} text
	 * @param {string} search
	 */
	exports.endsWith = function (text, search) {
	  var start = text.length - search.length;
	  var end = text.length;
	  return text.substring(start, end) === search;
	};

	/**
	 * Format a value of any type into a string.
	 *
	 * Usage:
	 *     math.format(value)
	 *     math.format(value, precision)
	 *
	 * When value is a function:
	 *
	 * - When the function has a property `syntax`, it returns this
	 *   syntax description.
	 * - In other cases, a string `'function'` is returned.
	 *
	 * When `value` is an Object:
	 *
	 * - When the object contains a property `format` being a function, this
	 *   function is invoked as `value.format(options)` and the result is returned.
	 * - When the object has its own `toString` method, this method is invoked
	 *   and the result is returned.
	 * - In other cases the function will loop over all object properties and
	 *   return JSON object notation like '{"a": 2, "b": 3}'.
	 *
	 * Example usage:
	 *     math.format(2/7);                // '0.2857142857142857'
	 *     math.format(math.pi, 3);         // '3.14'
	 *     math.format(new Complex(2, 3));  // '2 + 3i'
	 *     math.format('hello');            // '"hello"'
	 *
	 * @param {*} value             Value to be stringified
	 * @param {Object | number | Function} [options]  Formatting options. See
	 *                                                lib/utils/number:format for a
	 *                                                description of the available
	 *                                                options.
	 * @return {string} str
	 */
	exports.format = function (value, options) {
	  if (typeof value === 'number') {
	    return formatNumber(value, options);
	  }

	  if (value && value.isBigNumber === true) {
	    return formatBigNumber(value, options);
	  }

	  if (value && value.isFraction === true) {
	    if (!options || options.fraction !== 'decimal') {
	      // output as ratio, like '1/3'
	      return value.s * value.n + '/' + value.d;
	    } else {
	      // output as decimal, like '0.(3)'
	      return value.toString();
	    }
	  }

	  if (Array.isArray(value)) {
	    return formatArray(value, options);
	  }

	  if (exports.isString(value)) {
	    return '"' + value + '"';
	  }

	  if (typeof value === 'function') {
	    return value.syntax ? String(value.syntax) : 'function';
	  }

	  if (value && typeof value === 'object') {
	    if (typeof value.format === 'function') {
	      return value.format(options);
	    } else if (value && value.toString() !== {}.toString()) {
	      // this object has a non-native toString method, use that one
	      return value.toString();
	    } else {
	      var entries = [];

	      for (var key in value) {
	        if (value.hasOwnProperty(key)) {
	          entries.push('"' + key + '": ' + exports.format(value[key], options));
	        }
	      }

	      return '{' + entries.join(', ') + '}';
	    }
	  }

	  return String(value);
	};

	/**
	 * Recursively format an n-dimensional matrix
	 * Example output: "[[1, 2], [3, 4]]"
	 * @param {Array} array
	 * @param {Object | number | Function} [options]  Formatting options. See
	 *                                                lib/utils/number:format for a
	 *                                                description of the available
	 *                                                options.
	 * @returns {string} str
	 */
	function formatArray(array, options) {
	  if (Array.isArray(array)) {
	    var str = '[';
	    var len = array.length;
	    for (var i = 0; i < len; i++) {
	      if (i != 0) {
	        str += ', ';
	      }
	      str += formatArray(array[i], options);
	    }
	    str += ']';
	    return str;
	  } else {
	    return exports.format(array, options);
	  }
	}

/***/ },
/* 85 */
/***/ function(module, exports) {

	/**
	 * Convert a BigNumber to a formatted string representation.
	 *
	 * Syntax:
	 *
	 *    format(value)
	 *    format(value, options)
	 *    format(value, precision)
	 *    format(value, fn)
	 *
	 * Where:
	 *
	 *    {number} value   The value to be formatted
	 *    {Object} options An object with formatting options. Available options:
	 *                     {string} notation
	 *                         Number notation. Choose from:
	 *                         'fixed'          Always use regular number notation.
	 *                                          For example '123.40' and '14000000'
	 *                         'exponential'    Always use exponential notation.
	 *                                          For example '1.234e+2' and '1.4e+7'
	 *                         'auto' (default) Regular number notation for numbers
	 *                                          having an absolute value between
	 *                                          `lower` and `upper` bounds, and uses
	 *                                          exponential notation elsewhere.
	 *                                          Lower bound is included, upper bound
	 *                                          is excluded.
	 *                                          For example '123.4' and '1.4e7'.
	 *                     {number} precision   A number between 0 and 16 to round
	 *                                          the digits of the number.
	 *                                          In case of notations 'exponential' and
	 *                                          'auto', `precision` defines the total
	 *                                          number of significant digits returned
	 *                                          and is undefined by default.
	 *                                          In case of notation 'fixed',
	 *                                          `precision` defines the number of
	 *                                          significant digits after the decimal
	 *                                          point, and is 0 by default.
	 *                     {Object} exponential An object containing two parameters,
	 *                                          {number} lower and {number} upper,
	 *                                          used by notation 'auto' to determine
	 *                                          when to return exponential notation.
	 *                                          Default values are `lower=1e-3` and
	 *                                          `upper=1e5`.
	 *                                          Only applicable for notation `auto`.
	 *    {Function} fn    A custom formatting function. Can be used to override the
	 *                     built-in notations. Function `fn` is called with `value` as
	 *                     parameter and must return a string. Is useful for example to
	 *                     format all values inside a matrix in a particular way.
	 *
	 * Examples:
	 *
	 *    format(6.4);                                        // '6.4'
	 *    format(1240000);                                    // '1.24e6'
	 *    format(1/3);                                        // '0.3333333333333333'
	 *    format(1/3, 3);                                     // '0.333'
	 *    format(21385, 2);                                   // '21000'
	 *    format(12.071, {notation: 'fixed'});                // '12'
	 *    format(2.3,    {notation: 'fixed', precision: 2});  // '2.30'
	 *    format(52.8,   {notation: 'exponential'});          // '5.28e+1'
	 *
	 * @param {BigNumber} value
	 * @param {Object | Function | number} [options]
	 * @return {string} str The formatted value
	 */
	exports.format = function (value, options) {
	  if (typeof options === 'function') {
	    // handle format(value, fn)
	    return options(value);
	  }

	  // handle special cases
	  if (!value.isFinite()) {
	    return value.isNaN() ? 'NaN' : value.gt(0) ? 'Infinity' : '-Infinity';
	  }

	  // default values for options
	  var notation = 'auto';
	  var precision = undefined;

	  if (options !== undefined) {
	    // determine notation from options
	    if (options.notation) {
	      notation = options.notation;
	    }

	    // determine precision from options
	    if (typeof options === 'number') {
	      precision = options;
	    } else if (options.precision) {
	      precision = options.precision;
	    }
	  }

	  // handle the various notations
	  switch (notation) {
	    case 'fixed':
	      return exports.toFixed(value, precision);

	    case 'exponential':
	      return exports.toExponential(value, precision);

	    case 'auto':
	      // determine lower and upper bound for exponential notation.
	      // TODO: implement support for upper and lower to be BigNumbers themselves
	      var lower = 1e-3;
	      var upper = 1e5;
	      if (options && options.exponential) {
	        if (options.exponential.lower !== undefined) {
	          lower = options.exponential.lower;
	        }
	        if (options.exponential.upper !== undefined) {
	          upper = options.exponential.upper;
	        }
	      }

	      // adjust the configuration of the BigNumber constructor (yeah, this is quite tricky...)
	      var oldConfig = {
	        toExpNeg: value.constructor.toExpNeg,
	        toExpPos: value.constructor.toExpPos
	      };

	      value.constructor.config({
	        toExpNeg: Math.round(Math.log(lower) / Math.LN10),
	        toExpPos: Math.round(Math.log(upper) / Math.LN10)
	      });

	      // handle special case zero
	      if (value.isZero()) return '0';

	      // determine whether or not to output exponential notation
	      var str;
	      var abs = value.abs();
	      if (abs.gte(lower) && abs.lt(upper)) {
	        // normal number notation
	        str = value.toSignificantDigits(precision).toFixed();
	      } else {
	        // exponential notation
	        str = exports.toExponential(value, precision);
	      }

	      // remove trailing zeros after the decimal point
	      return str.replace(/((\.\d*?)(0+))($|e)/, function () {
	        var digits = arguments[2];
	        var e = arguments[4];
	        return digits !== '.' ? digits + e : e;
	      });

	    default:
	      throw new Error('Unknown notation "' + notation + '". ' + 'Choose "auto", "exponential", or "fixed".');
	  }
	};

	/**
	 * Format a number in exponential notation. Like '1.23e+5', '2.3e+0', '3.500e-3'
	 * @param {BigNumber} value
	 * @param {number} [precision]  Number of digits in formatted output.
	 *                              If not provided, the maximum available digits
	 *                              is used.
	 * @returns {string} str
	 */
	exports.toExponential = function (value, precision) {
	  if (precision !== undefined) {
	    return value.toExponential(precision - 1); // Note the offset of one
	  } else {
	    return value.toExponential();
	  }
	};

	/**
	 * Format a number with fixed notation.
	 * @param {BigNumber} value
	 * @param {number} [precision=0]        Optional number of decimals after the
	 *                                      decimal point. Zero by default.
	 */
	exports.toFixed = function (value, precision) {
	  return value.toFixed(precision || 0);
	  // Note: the (precision || 0) is needed as the toFixed of BigNumber has an
	  // undefined default precision instead of 0.
	};

/***/ },
/* 86 */
/***/ function(module, exports) {

	'use strict';

	/**
	 * Determine the type of a variable
	 *
	 *     type(x)
	 *
	 * The following types are recognized:
	 *
	 *     'undefined'
	 *     'null'
	 *     'boolean'
	 *     'number'
	 *     'string'
	 *     'Array'
	 *     'Function'
	 *     'Date'
	 *     'RegExp'
	 *     'Object'
	 *
	 * @param {*} x
	 * @return {string} Returns the name of the type. Primitive types are lower case,
	 *                  non-primitive types are upper-camel-case.
	 *                  For example 'number', 'string', 'Array', 'Date'.
	 */

	exports.type = function (x) {
	  var type = typeof x;

	  if (type === 'object') {
	    if (x === null) return 'null';
	    if (x instanceof Boolean) return 'boolean';
	    if (x instanceof Number) return 'number';
	    if (x instanceof String) return 'string';
	    if (Array.isArray(x)) return 'Array';
	    if (x instanceof Date) return 'Date';
	    if (x instanceof RegExp) return 'RegExp';

	    return 'Object';
	  }

	  if (type === 'function') return 'Function';

	  return type;
	};

	/**
	 * Test whether a value is a scalar
	 * @param x
	 * @return {boolean} Returns true when x is a scalar, returns false when
	 *                   x is a Matrix or Array.
	 */
	exports.isScalar = function (x) {
	  return !(x && x.isMatrix || Array.isArray(x));
	};

/***/ },
/* 87 */
/***/ function(module, exports) {

	'use strict';

	/**
	 * Create a range error with the message:
	 *     'Dimension mismatch (<actual size> != <expected size>)'
	 * @param {number | number[]} actual        The actual size
	 * @param {number | number[]} expected      The expected size
	 * @param {string} [relation='!=']          Optional relation between actual
	 *                                          and expected size: '!=', '<', etc.
	 * @extends RangeError
	 */

	function DimensionError(actual, expected, relation) {
	  if (!(this instanceof DimensionError)) {
	    throw new SyntaxError('Constructor must be called with the new operator');
	  }

	  this.actual = actual;
	  this.expected = expected;
	  this.relation = relation;

	  this.message = 'Dimension mismatch (' + (Array.isArray(actual) ? '[' + actual.join(', ') + ']' : actual) + ' ' + (this.relation || '!=') + ' ' + (Array.isArray(expected) ? '[' + expected.join(', ') + ']' : expected) + ')';

	  this.stack = new Error().stack;
	}

	DimensionError.prototype = new RangeError();
	DimensionError.prototype.constructor = RangeError;
	DimensionError.prototype.name = 'DimensionError';
	DimensionError.prototype.isDimensionError = true;

	module.exports = DimensionError;

/***/ },
/* 88 */
/***/ function(module, exports) {

	'use strict';

	/**
	 * Create a range error with the message:
	 *     'Index out of range (index < min)'
	 *     'Index out of range (index < max)'
	 *
	 * @param {number} index     The actual index
	 * @param {number} [min=0]   Minimum index (included)
	 * @param {number} [max]     Maximum index (excluded)
	 * @extends RangeError
	 */

	function IndexError(index, min, max) {
	  if (!(this instanceof IndexError)) {
	    throw new SyntaxError('Constructor must be called with the new operator');
	  }

	  this.index = index;
	  if (arguments.length < 3) {
	    this.min = 0;
	    this.max = min;
	  } else {
	    this.min = min;
	    this.max = max;
	  }

	  if (this.min !== undefined && this.index < this.min) {
	    this.message = 'Index out of range (' + this.index + ' < ' + this.min + ')';
	  } else if (this.max !== undefined && this.index >= this.max) {
	    this.message = 'Index out of range (' + this.index + ' > ' + (this.max - 1) + ')';
	  } else {
	    this.message = 'Index out of range (' + this.index + ')';
	  }

	  this.stack = new Error().stack;
	}

	IndexError.prototype = new RangeError();
	IndexError.prototype.constructor = RangeError;
	IndexError.prototype.name = 'IndexError';
	IndexError.prototype.isIndexError = true;

	module.exports = IndexError;

/***/ },
/* 89 */
/***/ function(module, exports) {

	'use strict';

	exports.symbols = {
	  // GREEK LETTERS
	  Alpha: 'A', alpha: '\\alpha',
	  Beta: 'B', beta: '\\beta',
	  Gamma: '\\Gamma', gamma: '\\gamma',
	  Delta: '\\Delta', delta: '\\delta',
	  Epsilon: 'E', epsilon: '\\epsilon', varepsilon: '\\varepsilon',
	  Zeta: 'Z', zeta: '\\zeta',
	  Eta: 'H', eta: '\\eta',
	  Theta: '\\Theta', theta: '\\theta', vartheta: '\\vartheta',
	  Iota: 'I', iota: '\\iota',
	  Kappa: 'K', kappa: '\\kappa', varkappa: '\\varkappa',
	  Lambda: '\\Lambda', lambda: '\\lambda',
	  Mu: 'M', mu: '\\mu',
	  Nu: 'N', nu: '\\nu',
	  Xi: '\\Xi', xi: '\\xi',
	  Omicron: 'O', omicron: 'o',
	  Pi: '\\Pi', pi: '\\pi', varpi: '\\varpi',
	  Rho: 'P', rho: '\\rho', varrho: '\\varrho',
	  Sigma: '\\Sigma', sigma: '\\sigma', varsigma: '\\varsigma',
	  Tau: 'T', tau: '\\tau',
	  Upsilon: '\\Upsilon', upsilon: '\\upsilon',
	  Phi: '\\Phi', phi: '\\phi', varphi: '\\varphi',
	  Chi: 'X', chi: '\\chi',
	  Psi: '\\Psi', psi: '\\psi',
	  Omega: '\\Omega', omega: '\\omega',
	  //logic
	  'true': '\\mathrm{True}',
	  'false': '\\mathrm{False}',
	  //other
	  i: 'i', //TODO use \i ??
	  inf: '\\infty',
	  Inf: '\\infty',
	  infinity: '\\infty',
	  Infinity: '\\infty',
	  oo: '\\infty',
	  lim: '\\lim',
	  'undefined': '\\mathbf{?}'
	};

	exports.operators = {
	  'transpose': '^\\top',
	  'factorial': '!',
	  'pow': '^',
	  'dotPow': '.^\\wedge', //TODO find ideal solution
	  'unaryPlus': '+',
	  'unaryMinus': '-',
	  'bitNot': '~', //TODO find ideal solution
	  'not': '\\neg',
	  'multiply': '\\cdot',
	  'divide': '\\frac', //TODO how to handle that properly?
	  'dotMultiply': '.\\cdot', //TODO find ideal solution
	  'dotDivide': '.:', //TODO find ideal solution
	  'mod': '\\mod',
	  'add': '+',
	  'subtract': '-',
	  'to': '\\rightarrow',
	  'leftShift': '<<',
	  'rightArithShift': '>>',
	  'rightLogShift': '>>>',
	  'equal': '=',
	  'unequal': '\\neq',
	  'smaller': '<',
	  'larger': '>',
	  'smallerEq': '\\leq',
	  'largerEq': '\\geq',
	  'bitAnd': '\\&',
	  'bitXor': '\\underline{|}',
	  'bitOr': '|',
	  'and': '\\wedge',
	  'xor': '\\veebar',
	  'or': '\\vee'
	};

	exports.defaultTemplate = '\\mathrm{${name}}\\left(${args}\\right)';

	var units = {
	  deg: '^\\circ'
	};

	//@param {string} name
	//@param {boolean} isUnit
	exports.toSymbol = function (name, isUnit) {
	  isUnit = typeof isUnit === 'undefined' ? false : isUnit;
	  if (isUnit) {
	    if (units.hasOwnProperty(name)) {
	      return units[name];
	    }
	    return '\\mathrm{' + name + '}';
	  }

	  if (exports.symbols.hasOwnProperty(name)) {
	    return exports.symbols[name];
	  } else if (name.indexOf('_') !== -1) {
	    //symbol with index (eg. alpha_1)
	    var index = name.indexOf('_');
	    return exports.toSymbol(name.substring(0, index)) + '_{' + exports.toSymbol(name.substring(index + 1)) + '}';
	  }
	  return name;
	};

/***/ },
/* 90 */
/***/ function(module, exports) {

	'use strict';

	function factory(type, config, load, typed) {
	  /**
	   * Create a Matrix. The function creates a new `math.type.Matrix` object from
	   * an `Array`. A Matrix has utility functions to manipulate the data in the
	   * matrix, like getting the size and getting or setting values in the matrix.
	   * Supported storage formats are 'dense' and 'sparse'.
	   *
	   * Syntax:
	   *
	   *    math.matrix()                         // creates an empty matrix using default storage format (dense).
	   *    math.matrix(data)                     // creates a matrix with initial data using default storage format (dense).
	   *    math.matrix('dense')                  // creates an empty matrix using the given storage format.
	   *    math.matrix(data, 'dense')            // creates a matrix with initial data using the given storage format.
	   *    math.matrix(data, 'sparse')           // creates a sparse matrix with initial data.
	   *    math.matrix(data, 'sparse', 'number') // creates a sparse matrix with initial data, number data type.
	   *
	   * Examples:
	   *
	   *    var m = math.matrix([[1, 2], [3, 4]]);
	   *    m.size();                        // Array [2, 2]
	   *    m.resize([3, 2], 5);
	   *    m.valueOf();                     // Array [[1, 2], [3, 4], [5, 5]]
	   *    m.get([1, 0])                    // number 3
	   *
	   * See also:
	   *
	   *    bignumber, boolean, complex, index, number, string, unit, sparse
	   *
	   * @param {Array | Matrix} [data]    A multi dimensional array
	   * @param {string} [format]          The Matrix storage format
	   *
	   * @return {Matrix} The created matrix
	   */
	  var matrix = typed('matrix', {
	    '': function () {
	      return _create([]);
	    },

	    'string': function (format) {
	      return _create([], format);
	    },

	    'string, string': function (format, datatype) {
	      return _create([], format, datatype);
	    },

	    'Array': function (data) {
	      return _create(data);
	    },

	    'Matrix': function (data) {
	      return _create(data, data.storage());
	    },

	    'Array | Matrix, string': _create,

	    'Array | Matrix, string, string': _create
	  });

	  matrix.toTex = {
	    0: '\\begin{bmatrix}\\end{bmatrix}',
	    1: '\\left(${args[0]}\\right)',
	    2: '\\left(${args[0]}\\right)'
	  };

	  return matrix;

	  /**
	   * Create a new Matrix with given storage format
	   * @param {Array} data
	   * @param {string} [format]
	   * @param {string} [datatype]
	   * @returns {Matrix} Returns a new Matrix
	   * @private
	   */
	  function _create(data, format, datatype) {
	    // get storage format constructor
	    var M = type.Matrix.storage(format || 'default');

	    // create instance
	    return new M(data, datatype);
	  }
	}

	exports.name = 'matrix';
	exports.factory = factory;

/***/ },
/* 91 */
/***/ function(module, exports) {

	'use strict';

	function factory(type, config, load, typed) {

	  /**
	   * Add two scalar values, `x + y`.
	   * This function is meant for internal use: it is used by the public function
	   * `add`
	   *
	   * This function does not support collections (Array or Matrix), and does
	   * not validate the number of of inputs.
	   *
	   * @param  {number | BigNumber | Fraction | Complex | Unit} x   First value to add
	   * @param  {number | BigNumber | Fraction | Complex} y          Second value to add
	   * @return {number | BigNumber | Fraction | Complex | Unit}                      Sum of `x` and `y`
	   * @private
	   */
	  var add = typed('add', {

	    'number, number': function (x, y) {
	      return x + y;
	    },

	    'Complex, Complex': function (x, y) {
	      return x.add(y);
	    },

	    'BigNumber, BigNumber': function (x, y) {
	      return x.plus(y);
	    },

	    'Fraction, Fraction': function (x, y) {
	      return x.add(y);
	    },

	    'Unit, Unit': function (x, y) {
	      if (x.value == null) throw new Error('Parameter x contains a unit with undefined value');
	      if (y.value == null) throw new Error('Parameter y contains a unit with undefined value');
	      if (!x.equalBase(y)) throw new Error('Units do not match');

	      var res = x.clone();
	      res.value = add(res.value, y.value);
	      res.fixPrefix = false;
	      return res;
	    }
	  });

	  return add;
	}

	exports.factory = factory;

/***/ },
/* 92 */
/***/ function(module, exports) {

	'use strict';

	function factory(type, config, load, typed) {

	  /**
	   * Multiply two scalar values, `x * y`.
	   * This function is meant for internal use: it is used by the public function
	   * `multiply`
	   *
	   * This function does not support collections (Array or Matrix), and does
	   * not validate the number of of inputs.
	   *
	   * @param  {number | BigNumber | Fraction | Complex | Unit} x   First value to multiply
	   * @param  {number | BigNumber | Fraction | Complex} y          Second value to multiply
	   * @return {number | BigNumber | Fraction | Complex | Unit}                      Multiplication of `x` and `y`
	   * @private
	   */
	  var multiplyScalar = typed('multiplyScalar', {

	    'number, number': function (x, y) {
	      return x * y;
	    },

	    'Complex, Complex': function (x, y) {
	      return x.mul(y);
	    },

	    'BigNumber, BigNumber': function (x, y) {
	      return x.times(y);
	    },

	    'Fraction, Fraction': function (x, y) {
	      return x.mul(y);
	    },

	    'number | Fraction | BigNumber | Complex, Unit': function (x, y) {
	      var res = y.clone();
	      res.value = res.value === null ? res._normalize(x) : multiplyScalar(res.value, x);
	      return res;
	    },

	    'Unit, number | Fraction | BigNumber | Complex': function (x, y) {
	      var res = x.clone();
	      res.value = res.value === null ? res._normalize(y) : multiplyScalar(res.value, y);
	      return res;
	    },

	    'Unit, Unit': function (x, y) {
	      return x.multiply(y);
	    }

	  });

	  return multiplyScalar;
	}

	exports.factory = factory;

/***/ },
/* 93 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';

	var nearlyEqual = __webpack_require__(72).nearlyEqual;
	var bigNearlyEqual = __webpack_require__(94);

	function factory(type, config, load, typed) {

	  /**
	   * Test whether two values are equal.
	   *
	   * @param  {number | BigNumber | Fraction | boolean | Complex | Unit} x   First value to compare
	   * @param  {number | BigNumber | Fraction | boolean | Complex} y          Second value to compare
	   * @return {boolean}                                                  Returns true when the compared values are equal, else returns false
	   * @private
	   */
	  var equalScalar = typed('equalScalar', {

	    'boolean, boolean': function (x, y) {
	      return x === y;
	    },

	    'number, number': function (x, y) {
	      return x === y || nearlyEqual(x, y, config.epsilon);
	    },

	    'BigNumber, BigNumber': function (x, y) {
	      return x.eq(y) || bigNearlyEqual(x, y, config.epsilon);
	    },

	    'Fraction, Fraction': function (x, y) {
	      return x.equals(y);
	    },

	    'Complex, Complex': function (x, y) {
	      return x.equals(y);
	    },

	    'Unit, Unit': function (x, y) {
	      if (!x.equalBase(y)) {
	        throw new Error('Cannot compare units with different base');
	      }
	      return equalScalar(x.value, y.value);
	    },

	    'string, string': function (x, y) {
	      return x === y;
	    }
	  });

	  return equalScalar;
	}

	exports.factory = factory;

/***/ },
/* 94 */
/***/ function(module, exports) {

	'use strict';

	/**
	 * Compares two BigNumbers.
	 * @param {BigNumber} x       First value to compare
	 * @param {BigNumber} y       Second value to compare
	 * @param {number} [epsilon]  The maximum relative difference between x and y
	 *                            If epsilon is undefined or null, the function will
	 *                            test whether x and y are exactly equal.
	 * @return {boolean} whether the two numbers are nearly equal
	 */

	module.exports = function nearlyEqual(x, y, epsilon) {
	  // if epsilon is null or undefined, test whether x and y are exactly equal
	  if (epsilon == null) {
	    return x.eq(y);
	  }

	  // use "==" operator, handles infinities
	  if (x.eq(y)) {
	    return true;
	  }

	  // NaN
	  if (x.isNaN() || y.isNaN()) {
	    return false;
	  }

	  // at this point x and y should be finite
	  if (x.isFinite() && y.isFinite()) {
	    // check numbers are very close, needed when comparing numbers near zero
	    var diff = x.minus(y).abs();
	    if (diff.isZero()) {
	      return true;
	    } else {
	      // use relative error
	      var max = x.constructor.max(x.abs(), y.abs());
	      return diff.lte(max.times(epsilon));
	    }
	  }

	  // Infinite and Number or negative Infinite and positive Infinite cases
	  return false;
	};

/***/ },
/* 95 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';

	function factory(type, config, load, typed) {

	  var equalScalar = load(__webpack_require__(93));

	  var SparseMatrix = type.SparseMatrix;

	  /**
	   * Iterates over SparseMatrix S nonzero items and invokes the callback function f(Sij, b).
	   * Callback function invoked NZ times (number of nonzero items in S).
	   *
	   *
	   *          ┌  f(Sij, b)  ; S(i,j) !== 0
	   * C(i,j) = ┤
	   *          â””  0          ; otherwise
	   *
	   *
	   * @param {Matrix}   s                 The SparseMatrix instance (S)
	   * @param {Scalar}   b                 The Scalar value
	   * @param {Function} callback          The f(Aij,b) operation to invoke
	   * @param {boolean}  inverse           A true value indicates callback should be invoked f(b,Sij)
	   *
	   * @return {Matrix}                    SparseMatrix (C)
	   *
	   * https://github.com/josdejong/mathjs/pull/346#issuecomment-97626813
	   */
	  var algorithm11 = function (s, b, callback, inverse) {
	    // sparse matrix arrays
	    var avalues = s._values;
	    var aindex = s._index;
	    var aptr = s._ptr;
	    var asize = s._size;
	    var adt = s._datatype;

	    // sparse matrix cannot be a Pattern matrix
	    if (!avalues) throw new Error('Cannot perform operation on Pattern Sparse Matrix and Scalar value');

	    // rows & columns
	    var rows = asize[0];
	    var columns = asize[1];

	    // datatype
	    var dt;
	    // equal signature to use
	    var eq = equalScalar;
	    // zero value
	    var zero = 0;
	    // callback signature to use
	    var cf = callback;

	    // process data types
	    if (typeof adt === 'string') {
	      // datatype
	      dt = adt;
	      // find signature that matches (dt, dt)
	      eq = typed.find(equalScalar, [dt, dt]);
	      // convert 0 to the same datatype
	      zero = typed.convert(0, dt);
	      // convert b to the same datatype
	      b = typed.convert(b, dt);
	      // callback
	      cf = typed.find(callback, [dt, dt]);
	    }

	    // result arrays
	    var cvalues = [];
	    var cindex = [];
	    var cptr = [];
	    // matrix
	    var c = new SparseMatrix({
	      values: cvalues,
	      index: cindex,
	      ptr: cptr,
	      size: [rows, columns],
	      datatype: dt
	    });

	    // loop columns
	    for (var j = 0; j < columns; j++) {
	      // initialize ptr
	      cptr[j] = cindex.length;
	      // values in j
	      for (var k0 = aptr[j], k1 = aptr[j + 1], k = k0; k < k1; k++) {
	        // row
	        var i = aindex[k];
	        // invoke callback
	        var v = inverse ? cf(b, avalues[k]) : cf(avalues[k], b);
	        // check value is zero
	        if (!eq(v, zero)) {
	          // push index & value
	          cindex.push(i);
	          cvalues.push(v);
	        }
	      }
	    }
	    // update ptr
	    cptr[columns] = cindex.length;

	    // return sparse matrix
	    return c;
	  };

	  return algorithm11;
	}

	exports.name = 'algorithm11';
	exports.factory = factory;

/***/ },
/* 96 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';

	var clone = __webpack_require__(69).clone;

	function factory(type, config, load, typed) {

	  var DenseMatrix = type.DenseMatrix;

	  /**
	   * Iterates over DenseMatrix items and invokes the callback function f(Aij..z, b).
	   * Callback function invoked MxN times.
	   *
	   * C(i,j,...z) = f(Aij..z, b)
	   *
	   * @param {Matrix}   a                 The DenseMatrix instance (A)
	   * @param {Scalar}   b                 The Scalar value
	   * @param {Function} callback          The f(Aij..z,b) operation to invoke
	   * @param {boolean}  inverse           A true value indicates callback should be invoked f(b,Aij..z)
	   *
	   * @return {Matrix}                    DenseMatrix (C)
	   *
	   * https://github.com/josdejong/mathjs/pull/346#issuecomment-97659042
	   */
	  var algorithm14 = function (a, b, callback, inverse) {
	    // a arrays
	    var adata = a._data;
	    var asize = a._size;
	    var adt = a._datatype;

	    // datatype
	    var dt;
	    // callback signature to use
	    var cf = callback;

	    // process data types
	    if (typeof adt === 'string') {
	      // datatype
	      dt = adt;
	      // convert b to the same datatype
	      b = typed.convert(b, dt);
	      // callback
	      cf = typed.find(callback, [dt, dt]);
	    }

	    // populate cdata, iterate through dimensions
	    var cdata = asize.length > 0 ? _iterate(cf, 0, asize, asize[0], adata, b, inverse) : [];

	    // c matrix
	    return new DenseMatrix({
	      data: cdata,
	      size: clone(asize),
	      datatype: dt
	    });
	  };

	  // recursive function
	  var _iterate = function (f, level, s, n, av, bv, inverse) {
	    // initialize array for this level
	    var cv = [];
	    // check we reach the last level
	    if (level === s.length - 1) {
	      // loop arrays in last level
	      for (var i = 0; i < n; i++) {
	        // invoke callback and store value
	        cv[i] = inverse ? f(bv, av[i]) : f(av[i], bv);
	      }
	    } else {
	      // iterate current level
	      for (var j = 0; j < n; j++) {
	        // iterate next level
	        cv[j] = _iterate(f, level + 1, s, s[level + 1], av[j], bv, inverse);
	      }
	    }
	    return cv;
	  };

	  return algorithm14;
	}

	exports.name = 'algorithm14';
	exports.factory = factory;

/***/ },
/* 97 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';

	var isInteger = __webpack_require__(72).isInteger;
	var size = __webpack_require__(83).size;

	function factory(type, config, load, typed) {
	  var latex = __webpack_require__(89);
	  var eye = load(__webpack_require__(98));
	  var multiply = load(__webpack_require__(82));
	  var matrix = load(__webpack_require__(90));
	  var fraction = load(__webpack_require__(99));
	  var number = load(__webpack_require__(100));

	  /**
	   * Calculates the power of x to y, `x ^ y`.
	   * Matrix exponentiation is supported for square matrices `x`, and positive
	   * integer exponents `y`.
	   *
	   * For cubic roots of negative numbers, the function returns the principal
	   * root by default. In order to let the function return the real root,
	   * math.js can be configured with `math.config({predictable: true})`.
	   * To retrieve all cubic roots of a value, use `math.cbrt(x, true)`.
	   *
	   * Syntax:
	   *
	   *    math.pow(x, y)
	   *
	   * Examples:
	   *
	   *    math.pow(2, 3);               // returns number 8
	   *
	   *    var a = math.complex(2, 3);
	   *    math.pow(a, 2)                // returns Complex -5 + 12i
	   *
	   *    var b = [[1, 2], [4, 3]];
	   *    math.pow(b, 2);               // returns Array [[9, 8], [16, 17]]
	   *
	   * See also:
	   *
	   *    multiply, sqrt, cbrt, nthRoot
	   *
	   * @param  {number | BigNumber | Complex | Array | Matrix} x  The base
	   * @param  {number | BigNumber | Complex} y                   The exponent
	   * @return {number | BigNumber | Complex | Array | Matrix} The value of `x` to the power `y`
	   */
	  var pow = typed('pow', {
	    'number, number': _pow,

	    'Complex, Complex': function (x, y) {
	      return x.pow(y);
	    },

	    'BigNumber, BigNumber': function (x, y) {
	      if (y.isInteger() || x >= 0 || config.predictable) {
	        return x.pow(y);
	      } else {
	        return new type.Complex(x.toNumber(), 0).pow(y.toNumber(), 0);
	      }
	    },

	    'Fraction, Fraction': function (x, y) {
	      if (y.d !== 1) {
	        if (config.predictable) {
	          throw new Error('Function pow does not support non-integer exponents for fractions.');
	        } else {
	          return _pow(x.valueOf(), y.valueOf());
	        }
	      } else {
	        return x.pow(y);
	      }
	    },

	    'Array, number': _powArray,

	    'Array, BigNumber': function (x, y) {
	      return _powArray(x, y.toNumber());
	    },

	    'Matrix, number': _powMatrix,

	    'Matrix, BigNumber': function (x, y) {
	      return _powMatrix(x, y.toNumber());
	    },

	    'Unit, number': function (x, y) {
	      return x.pow(y);
	    }

	  });

	  /**
	   * Calculates the power of x to y, x^y, for two numbers.
	   * @param {number} x
	   * @param {number} y
	   * @return {number | Complex} res
	   * @private
	   */
	  function _pow(x, y) {

	    // Alternatively could define a 'realmode' config option or something, but
	    // 'predictable' will work for now
	    if (config.predictable && !isInteger(y) && x < 0) {
	      // Check to see if y can be represented as a fraction
	      try {
	        var yFrac = fraction(y);
	        var yNum = number(yFrac);
	        if (y === yNum || Math.abs((y - yNum) / y) < 1e-14) {
	          if (yFrac.d % 2 === 1) {
	            return (yFrac.n % 2 === 0 ? 1 : -1) * Math.pow(-x, y);
	          }
	        }
	      } catch (ex) {}
	      // fraction() throws an error if y is Infinity, etc.


	      // Unable to express y as a fraction, so continue on
	    }

	    if (isInteger(y) || x >= 0 || config.predictable) {
	      return Math.pow(x, y);
	    } else {
	      return new type.Complex(x, 0).pow(y, 0);
	    }
	  }

	  /**
	   * Calculate the power of a 2d array
	   * @param {Array} x     must be a 2 dimensional, square matrix
	   * @param {number} y    a positive, integer value
	   * @returns {Array}
	   * @private
	   */
	  function _powArray(x, y) {
	    if (!isInteger(y) || y < 0) {
	      throw new TypeError('For A^b, b must be a positive integer (value is ' + y + ')');
	    }
	    // verify that A is a 2 dimensional square matrix
	    var s = size(x);
	    if (s.length != 2) {
	      throw new Error('For A^b, A must be 2 dimensional (A has ' + s.length + ' dimensions)');
	    }
	    if (s[0] != s[1]) {
	      throw new Error('For A^b, A must be square (size is ' + s[0] + 'x' + s[1] + ')');
	    }

	    var res = eye(s[0]).valueOf();
	    var px = x;
	    while (y >= 1) {
	      if ((y & 1) == 1) {
	        res = multiply(px, res);
	      }
	      y >>= 1;
	      px = multiply(px, px);
	    }
	    return res;
	  }

	  /**
	   * Calculate the power of a 2d matrix
	   * @param {Matrix} x     must be a 2 dimensional, square matrix
	   * @param {number} y    a positive, integer value
	   * @returns {Matrix}
	   * @private
	   */
	  function _powMatrix(x, y) {
	    return matrix(_powArray(x.valueOf(), y));
	  }

	  pow.toTex = {
	    2: '\\left(${args[0]}\\right)' + latex.operators['pow'] + '{${args[1]}}'
	  };

	  return pow;
	}

	exports.name = 'pow';
	exports.factory = factory;

/***/ },
/* 98 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';

	var array = __webpack_require__(83);
	var isInteger = __webpack_require__(72).isInteger;

	function factory(type, config, load, typed) {

	  var matrix = load(__webpack_require__(90));

	  /**
	   * Create a 2-dimensional identity matrix with size m x n or n x n.
	   * The matrix has ones on the diagonal and zeros elsewhere.
	   *
	   * Syntax:
	   *
	   *    math.eye(n)
	   *    math.eye(n, format)
	   *    math.eye(m, n)
	   *    math.eye(m, n, format)
	   *    math.eye([m, n])
	   *    math.eye([m, n], format)
	   *
	   * Examples:
	   *
	   *    math.eye(3);                    // returns [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
	   *    math.eye(3, 2);                 // returns [[1, 0], [0, 1], [0, 0]]
	   *
	   *    var A = [[1, 2, 3], [4, 5, 6]];
	   *    math.eye(math.size(A));         // returns [[1, 0, 0], [0, 1, 0]]
	   *
	   * See also:
	   *
	   *    diag, ones, zeros, size, range
	   *
	   * @param {...number | Matrix | Array} size   The size for the matrix
	   * @param {string} [format]                   The Matrix storage format
	   *
	   * @return {Matrix | Array | number} A matrix with ones on the diagonal.
	   */
	  var eye = typed('eye', {
	    '': function () {
	      return config.matrix === 'Matrix' ? matrix([]) : [];
	    },

	    'string': function (format) {
	      return matrix(format);
	    },

	    'number | BigNumber': function (rows) {
	      return _eye(rows, rows, config.matrix === 'Matrix' ? 'default' : undefined);
	    },

	    'number | BigNumber, string': function (rows, format) {
	      return _eye(rows, rows, format);
	    },

	    'number | BigNumber, number | BigNumber': function (rows, cols) {
	      return _eye(rows, cols, config.matrix === 'Matrix' ? 'default' : undefined);
	    },

	    'number | BigNumber, number | BigNumber, string': function (rows, cols, format) {
	      return _eye(rows, cols, format);
	    },

	    'Array': function (size) {
	      return _eyeVector(size);
	    },

	    'Array, string': function (size, format) {
	      return _eyeVector(size, format);
	    },

	    'Matrix': function (size) {
	      return _eyeVector(size.valueOf(), size.storage());
	    },

	    'Matrix, string': function (size, format) {
	      return _eyeVector(size.valueOf(), format);
	    }
	  });

	  eye.toTex = undefined; // use default template

	  return eye;

	  function _eyeVector(size, format) {
	    switch (size.length) {
	      case 0:
	        return format ? matrix(format) : [];
	      case 1:
	        return _eye(size[0], size[0], format);
	      case 2:
	        return _eye(size[0], size[1], format);
	      default:
	        throw new Error('Vector containing two values expected');
	    }
	  }

	  /**
	   * Create an identity matrix
	   * @param {number | BigNumber} rows
	   * @param {number | BigNumber} cols
	   * @param {string} [format]
	   * @returns {Matrix}
	   * @private
	   */
	  function _eye(rows, cols, format) {
	    // BigNumber constructor with the right precision
	    var Big = rows && rows.isBigNumber === true ? type.BigNumber : cols && cols.isBigNumber === true ? type.BigNumber : null;

	    if (rows && rows.isBigNumber === true) rows = rows.toNumber();
	    if (cols && cols.isBigNumber === true) cols = cols.toNumber();

	    if (!isInteger(rows) || rows < 1) {
	      throw new Error('Parameters in function eye must be positive integers');
	    }
	    if (!isInteger(cols) || cols < 1) {
	      throw new Error('Parameters in function eye must be positive integers');
	    }

	    var one = Big ? new type.BigNumber(1) : 1;
	    var defaultValue = Big ? new Big(0) : 0;
	    var size = [rows, cols];

	    // check we need to return a matrix
	    if (format) {
	      // get matrix storage constructor
	      var F = type.Matrix.storage(format);
	      // create diagonal matrix (use optimized implementation for storage format)
	      return F.diagonal(size, one, 0, defaultValue);
	    }

	    // create and resize array
	    var res = array.resize([], size, defaultValue);
	    // fill in ones on the diagonal
	    var minimum = rows < cols ? rows : cols;
	    // fill diagonal
	    for (var d = 0; d < minimum; d++) {
	      res[d][d] = one;
	    }
	    return res;
	  }
	}

	exports.name = 'eye';
	exports.factory = factory;

/***/ },
/* 99 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';

	var deepMap = __webpack_require__(80);

	function factory(type, config, load, typed) {
	  /**
	   * Create a fraction convert a value to a fraction.
	   *
	   * Syntax:
	   *     math.fraction(numerator, denominator)
	   *     math.fraction({n: numerator, d: denominator})
	   *     math.fraction(matrix: Array | Matrix)         Turn all matrix entries
	   *                                                   into fractions
	   *
	   * Examples:
	   *
	   *     math.fraction(1, 3);
	   *     math.fraction('2/3');
	   *     math.fraction({n: 2, d: 3});
	   *     math.fraction([0.2, 0.25, 1.25]);
	   *
	   * See also:
	   *
	   *    bignumber, number, string, unit
	   *
	   * @param {number | string | Fraction | BigNumber | Array | Matrix} [args]
	   *            Arguments specifying the numerator and denominator of
	   *            the fraction
	   * @return {Fraction | Array | Matrix} Returns a fraction
	   */
	  var fraction = typed('fraction', {
	    'number': function (x) {
	      if (!isFinite(x) || isNaN(x)) {
	        throw new Error(x + ' cannot be represented as a fraction');
	      }

	      return new type.Fraction(x);
	    },

	    'string': function (x) {
	      return new type.Fraction(x);
	    },

	    'number, number': function (numerator, denominator) {
	      return new type.Fraction(numerator, denominator);
	    },

	    'BigNumber': function (x) {
	      return new type.Fraction(x.toString());
	    },

	    'Fraction': function (x) {
	      return x; // fractions are immutable
	    },

	    'Object': function (x) {
	      return new type.Fraction(x);
	    },

	    'Array | Matrix': function (x) {
	      return deepMap(x, fraction);
	    }
	  });

	  return fraction;
	}

	exports.name = 'fraction';
	exports.factory = factory;

/***/ },
/* 100 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';

	var deepMap = __webpack_require__(80);

	function factory(type, config, load, typed) {
	  /**
	   * Create a number or convert a string, boolean, or unit to a number.
	   * When value is a matrix, all elements will be converted to number.
	   *
	   * Syntax:
	   *
	   *    math.number(value)
	   *    math.number(unit, valuelessUnit)
	   *
	   * Examples:
	   *
	   *    math.number(2);                         // returns number 2
	   *    math.number('7.2');                     // returns number 7.2
	   *    math.number(true);                      // returns number 1
	   *    math.number([true, false, true, true]); // returns [1, 0, 1, 1]
	   *    math.number(math.unit('52cm'), 'm');    // returns 0.52
	   *
	   * See also:
	   *
	   *    bignumber, boolean, complex, index, matrix, string, unit
	   *
	   * @param {string | number | BigNumber | Fraction | boolean | Array | Matrix | Unit | null} [value]  Value to be converted
	   * @param {Unit | string} [valuelessUnit] A valueless unit, used to convert a unit to a number
	   * @return {number | Array | Matrix} The created number
	   */
	  var number = typed('number', {
	    '': function () {
	      return 0;
	    },

	    'number': function (x) {
	      return x;
	    },

	    'string': function (x) {
	      var num = Number(x);
	      if (isNaN(num)) {
	        throw new SyntaxError('String "' + x + '" is no valid number');
	      }
	      return num;
	    },

	    'BigNumber': function (x) {
	      return x.toNumber();
	    },

	    'Fraction': function (x) {
	      return x.valueOf();
	    },

	    'Unit': function (x) {
	      throw new Error('Second argument with valueless unit expected');
	    },

	    'Unit, string | Unit': function (unit, valuelessUnit) {
	      return unit.toNumber(valuelessUnit);
	    },

	    'Array | Matrix': function (x) {
	      return deepMap(x, number);
	    }
	  });

	  number.toTex = {
	    0: '0',
	    1: '\\left(${args[0]}\\right)',
	    2: '\\left(\\left(${args[0]}\\right)${args[1]}\\right)'
	  };

	  return number;
	}

	exports.name = 'number';
	exports.factory = factory;

/***/ },
/* 101 */
/***/ function(module, exports) {

	module.exports = function get_previous_zoom(params) {
	  var prev_zoom = {};

	  var inst_trans = d3.select(params.root + ' .clust_group').attr('transform');

	  if (inst_trans != null) {

	    // prevent from crashing if no scaling was done
	    if (inst_trans.indexOf('scale') > 0) {
	      prev_zoom.zoom_x = parseFloat(inst_trans.split('scale')[1].replace('(', '').replace(')', '').split(',')[0]);

	      prev_zoom.zoom_y = parseFloat(inst_trans.split('scale')[1].replace('(', '').replace(')', '').split(',')[1]);
	    } else {
	      prev_zoom.zoom_x = 1;
	      prev_zoom.zoom_y = 1;
	    }
	  } else {
	    prev_zoom.zoom_x = 1;
	    prev_zoom.zoom_y = 1;
	  }

	  return prev_zoom;
		};

/***/ },
/* 102 */
/***/ function(module, exports, __webpack_require__) {

	var d3_tip_custom = __webpack_require__(48);

	module.exports = function make_row_tooltips(params) {

	  if (params.labels.show_label_tooltips) {

	    // remove old tooltips
	    d3.selectAll(params.viz.root_tips + '_row_tip').remove();

	    var root_tip_selector = params.viz.root_tips.replace('.', '');

	    // d3-tooltip
	    var row_tip = d3_tip_custom().attr('class', function () {
	      var class_string = root_tip_selector + ' d3-tip ' + root_tip_selector + '_row_tip';
	      return class_string;
	    }).direction('e').offset([0, 10]).style('display', 'none').html(function (d) {
	      var inst_name = d.name.replace(/_/g, ' ').split('#')[0];
	      return "<span>" + inst_name + "</span>";
	    });

	    d3.select(params.viz.viz_wrapper).select(params.root + ' .row_container').call(row_tip);

	    d3.select(params.root + ' .row_label_zoom_container').selectAll('g').on('mouseover', function (d) {

	      d3.select(params.viz.root_tips + '_row_tip').classed(d.name, true);

	      d3.selectAll(params.viz.root_tips + '_row_tip').style('display', 'block');

	      d3.select(this).select('text').classed('active', true);

	      row_tip.show(d);

	      if (params.row_tip_callback != null) {
	        params.row_tip_callback(params.viz.root_tips, d);
	      }
	    }).on('mouseout', function mouseout(d) {

	      d3.selectAll(params.viz.root_tips + '_row_tip').style('display', 'none').classed(d.name, false);

	      d3.select(this).select('text').classed('active', false);

	      row_tip.hide(d);
	    });
	  } else {

	    d3.select(params.root + ' .row_label_zoom_container').selectAll('g').on('mouseover', function () {
	      d3.select(this).select('text').classed('active', true);
	    }).on('mouseout', function mouseout() {
	      d3.select(this).select('text').classed('active', false);
	    });
	  }
		};

/***/ },
/* 103 */
/***/ function(module, exports, __webpack_require__) {

	var utils = __webpack_require__(2);
	var add_col_click_hlight = __webpack_require__(104);
	var col_reorder = __webpack_require__(105);
	var row_reorder = __webpack_require__(52);
	var make_col_tooltips = __webpack_require__(109);
	var col_viz_aid_triangle = __webpack_require__(110);

	module.exports = function make_col_label_container(cgm, text_delay = 0) {

	  var params = cgm.params;
	  var col_container;

	  var col_nodes = params.network_data.col_nodes;

	  // offset click group column label
	  var x_offset_click = params.viz.x_scale.rangeBand() / 2 + params.viz.border_width.x;
	  // reduce width of rotated rects


	  // make container to pre-position zoomable elements
	  if (d3.select(params.root + ' .col_container').empty()) {

	    col_container = d3.select(params.viz.viz_svg).append('g').attr('class', 'col_container').attr('transform', 'translate(' + params.viz.clust.margin.left + ',' + params.viz.norm_labels.margin.top + ')');

	    // white background rect for col labels
	    col_container.append('rect').attr('fill', params.viz.background_color) //!! prog_colors
	    .attr('width', 30 * params.viz.clust.dim.width + 'px').attr('height', params.viz.label_background.col).attr('class', 'white_bars');

	    // col labels
	    col_container.append('g').attr('class', 'col_label_outer_container')
	    // position the outer col label group
	    .attr('transform', 'translate(0,' + params.viz.norm_labels.width.col + ')').append('g').attr('class', 'col_zoom_container');
	  } else {

	    col_container = d3.select(params.root + ' .col_container').attr('transform', 'translate(' + params.viz.clust.margin.left + ',' + params.viz.norm_labels.margin.top + ')');

	    // white background rect for col labels
	    col_container.select('.white_bars').attr('fill', params.viz.background_color) //!! prog_colors
	    .attr('width', 30 * params.viz.clust.dim.width + 'px').attr('height', params.viz.label_background.col);

	    // col labels
	    col_container.select(params.root + ' .col_label_outer_container');
	  }

	  // add main column label group
	  var col_label_obj = d3.select(params.root + ' .col_zoom_container').selectAll('.col_label_text').data(col_nodes, function (d) {
	    return d.name;
	  }).enter().append('g').attr('class', 'col_label_text').attr('transform', function (d) {
	    var inst_index = d.col_index;
	    return 'translate(' + params.viz.x_scale(inst_index) + ', 0) rotate(-90)';
	  });

	  // append group for individual column label
	  var col_label_group = col_label_obj
	  // append new group for rect and label (not white lines)
	  .append('g').attr('class', 'col_label_group')
	  // rotate column labels
	  .attr('transform', 'translate(' + params.viz.x_scale.rangeBand() / 2 + ',' + x_offset_click + ') rotate(45)').on('mouseover', function () {
	    d3.select(this).select('text').classed('active', true);
	  }).on('mouseout', function () {
	    d3.select(this).select('text').classed('active', false);
	  });

	  // append column value bars
	  if (utils.has(params.network_data.col_nodes[0], 'value')) {

	    col_label_group.append('rect').attr('class', 'col_bars').attr('width', function (d) {
	      var inst_value = 0;
	      if (d.value > 0) {
	        inst_value = params.labels.bar_scale_col(d.value);
	      }
	      return inst_value;
	    })
	    // rotate labels - reduce width if rotating
	    .attr('height', params.viz.x_scale.rangeBand() * 0.66).style('fill', function (d) {
	      return d.value > 0 ? params.matrix.bar_colors[0] : params.matrix.bar_colors[1];
	    }).attr('opacity', 0.6);
	  }

	  // add column label
	  col_label_group.append('text').attr('x', 0)
	  // manually tuned
	  .attr('y', params.viz.x_scale.rangeBand() * 0.64).attr('dx', params.viz.border_width.x).attr('text-anchor', 'start').attr('full_name', function (d) {
	    return d.name;
	  })
	  // original font size
	  .style('font-size', params.labels.default_fs_col + 'px').style('cursor', 'default').text(function (d) {
	    return utils.normal_name(d);
	  })
	  // .attr('pointer-events','none')
	  .style('opacity', 0).transition().delay(text_delay).duration(text_delay).style('opacity', 1);

	  make_col_tooltips(params);

	  // add triangle under rotated labels
	  col_label_group.append('path').style('stroke-width', 0).attr('d', function () {
	    return col_viz_aid_triangle(params);
	  }).attr('fill', '#eee').style('opacity', 0).transition().delay(text_delay).duration(text_delay).style('opacity', params.viz.triangle_opacity);

	  // add col callback function
	  d3.selectAll(params.root + ' .col_label_text').on('click', function (d) {

	    if (typeof params.click_label == 'function') {
	      params.click_label(d.name, 'col');
	      add_col_click_hlight(params, this, d.ini);
	    } else {

	      if (params.tile_click_hlight) {
	        add_col_click_hlight(params, this, d.ini);
	      }
	    }
	  }).on('dblclick', function (d) {

	    var data_attr = '__data__';
	    var col_name = this[data_attr].name;

	    if (params.sim_mat) {
	      col_reorder(cgm, this, col_name);

	      var row_selection = d3.selectAll(params.root + ' .row_label_group').filter(function (d) {
	        return d.name == col_name;
	      })[0][0];

	      row_reorder(cgm, row_selection, col_name);
	    } else {
	      col_reorder(cgm, this, col_name);
	    }

	    if (params.tile_click_hlight) {
	      add_col_click_hlight(params, this, d.ini);
	    }
	  });
		};

/***/ },
/* 104 */
/***/ function(module, exports) {

	module.exports = function (params, clicked_col, id_clicked_col) {

	  if (id_clicked_col != params.click_hlight_col) {

	    params.click_hlight_col = id_clicked_col;

	    var rel_width_hlight = 6;
	    var opacity_hlight = 0.85;
	    var hlight_width = rel_width_hlight * params.viz.border_width.x;

	    d3.selectAll(params.root + ' .click_hlight').remove();

	    // // highlight selected column
	    // ///////////////////////////////
	    // // unhilight and unbold all columns (already unbolded earlier)
	    // d3.selectAll('.col_label_text')
	    //   .select('rect')
	    //   .style('opacity', 0);
	    // // highlight column name
	    // d3.select(clicked_col)
	    //   .select('rect')
	    //   .style('opacity', 1);

	    d3.select(clicked_col).append('rect').classed('click_hlight', true).classed('col_top_hlight', true).attr('width', params.viz.clust.dim.height).attr('height', hlight_width).attr('fill', params.matrix.hlight_color).attr('opacity', opacity_hlight).attr('transform', function () {
	      var tmp_translate_y = 0;
	      var tmp_translate_x = -(params.viz.clust.dim.height + params.viz.cat_room.col + params.viz.uni_margin);
	      return 'translate(' + tmp_translate_x + ',' + tmp_translate_y + ')';
	    });

	    d3.select(clicked_col).append('rect').classed('click_hlight', true).classed('col_bottom_hlight', true).attr('width', params.viz.clust.dim.height).attr('height', hlight_width).attr('fill', params.matrix.hlight_color).attr('opacity', opacity_hlight).attr('transform', function () {
	      // reverse x and y since rotated
	      var tmp_translate_y = params.viz.x_scale.rangeBand() - hlight_width;
	      var tmp_translate_x = -(params.viz.clust.dim.height + params.viz.cat_room.col + params.viz.uni_margin);
	      return 'translate(' + tmp_translate_x + ',' + tmp_translate_y + ')';
	    });
	  } else {
	    d3.selectAll(params.root + ' .click_hlight').remove();
	    params.click_hlight_col = -666;
	  }
		};

/***/ },
/* 105 */
/***/ function(module, exports, __webpack_require__) {

	// var utils = require('../Utils_clust');
	var reposition_tile_highlight = __webpack_require__(53);
	var toggle_dendro_view = __webpack_require__(54);
	var show_visible_area = __webpack_require__(106);
	var ini_zoom_info = __webpack_require__(36);
	var get_previous_zoom = __webpack_require__(101);
	var calc_downsampled_levels = __webpack_require__(27);

	module.exports = function col_reorder(cgm, col_selection, inst_term) {

	  var params = cgm.params;
	  var prev_zoom = get_previous_zoom(params);

	  if (prev_zoom.zoom_y === 1 && prev_zoom.zoom_x === 1) {

	    params.viz.inst_order.col = 'custom';

	    toggle_dendro_view(cgm, 'col');

	    d3.selectAll(params.root + ' .toggle_row_order .btn').classed('active', false);

	    params.viz.run_trans = true;

	    var mat = $.extend(true, {}, params.matrix.matrix);
	    var row_nodes = params.network_data.row_nodes;
	    var col_nodes = params.network_data.col_nodes;

	    // find the column number of col_selection term from col_nodes
	    // gather column node names
	    var tmp_arr = [];
	    col_nodes.forEach(function (node) {
	      tmp_arr.push(node.name);
	    });

	    // find index
	    var inst_col = _.indexOf(tmp_arr, inst_term);

	    // gather the values of the input genes
	    tmp_arr = [];
	    row_nodes.forEach(function (node, index) {
	      tmp_arr.push(mat[index].row_data[inst_col].value);
	    });

	    // sort the cols
	    var tmp_sort = d3.range(tmp_arr.length).sort(function (a, b) {
	      return tmp_arr[b] - tmp_arr[a];
	    });

	    // resort rows (rows are reorderd by double clicking a col)
	    params.viz.y_scale.domain(tmp_sort);

	    // save to custom row order
	    params.matrix.orders.custom_col = tmp_sort;

	    var t;

	    var row_nodes_names = params.network_data.row_nodes_names;

	    // reorder
	    if (params.network_data.links.length > params.matrix.def_large_matrix) {
	      t = d3.select(params.root + ' .viz_svg');
	    } else {
	      t = d3.select(params.root + ' .viz_svg').transition().duration(2500);
	    }

	    // reorder row_label_triangle groups
	    t.selectAll('.row_cat_group').attr('transform', function (d) {
	      var inst_index = _.indexOf(row_nodes_names, d.name);
	      return 'translate(0,' + params.viz.y_scale(inst_index) + ')';
	    });

	    // Move Row Labels
	    t.select('.row_label_zoom_container').selectAll('.row_label_group').attr('transform', function (d) {
	      var inst_index = _.indexOf(row_nodes_names, d.name);
	      return 'translate(0,' + params.viz.y_scale(inst_index) + ')';
	    });

	    // only update matri if not downsampled
	    if (params.viz.ds_level === -1) {
	      // reorder matrix rows
	      t.selectAll('.row').attr('transform', function (d) {
	        var inst_index = _.indexOf(row_nodes_names, d.name);
	        return 'translate(0,' + params.viz.y_scale(inst_index) + ')';
	      });
	    }

	    // highlight selected column
	    ///////////////////////////////
	    // unhilight and unbold all columns (already unbolded earlier)
	    d3.selectAll(params.root + ' .col_label_text').select('.highlight_rect').style('opacity', 0);
	    // highlight column name
	    d3.select(col_selection).select('.highlight_rect').style('opacity', 1);

	    // redefine x and y positions
	    params.network_data.links.forEach(function (d) {
	      d.x = params.viz.x_scale(d.target);
	      d.y = params.viz.y_scale(d.source);
	    });

	    reposition_tile_highlight(params);

	    params.zoom_info = ini_zoom_info();

	    setTimeout(function () {
	      params.viz.run_trans = false;
	    }, 2500);

	    // calculate downsmapling if necessary
	    if (params.viz.ds_num_levels > 0 && params.viz.ds_level >= 0) {

	      calc_downsampled_levels(params);

	      var zooming_stopped = true;
	      var zooming_out = true;
	      var make_all_rows = true;
	      // show_visible_area is also run with two_translate_zoom, but at that point
	      // the parameters were not updated and two_translate_zoom if only run
	      // if needed to reset zoom
	      show_visible_area(cgm, zooming_stopped, zooming_out, make_all_rows);
	    }
	  }
		};

/***/ },
/* 106 */
/***/ function(module, exports, __webpack_require__) {

	var find_viz_rows = __webpack_require__(107);
	var make_matrix_rows = __webpack_require__(41);
	var make_row_labels = __webpack_require__(50);
	var make_row_visual_aid_triangles = __webpack_require__(108);

	module.exports = function show_visible_area(cgm, zooming_stopped = false, zooming_out = false, make_all_rows = false) {

	  // console.log('show_visible_area stopped: ' + String(zooming_stopped));

	  var params = cgm.params;
	  var zoom_info = params.zoom_info;

	  // update ds_level if necessary
	  //////////////////////////////////////////////
	  var check_ds_level = params.viz.ds_level;
	  var old_ds_level = params.viz.ds_level;

	  // toggle the downsampling level (if necessary)
	  if (params.viz.ds === null) {
	    check_ds_level = -1;
	  } else {

	    check_ds_level = Math.floor(Math.log(zoom_info.zoom_y) / Math.log(params.viz.ds_zt));

	    if (check_ds_level > params.viz.ds_num_levels - 1) {
	      check_ds_level = -1;
	    }
	  }

	  // check if override_ds is necessary
	  //////////////////////////////////////////////
	  // force update of view if moving to more coarse view
	  var override_ds = false;

	  if (old_ds_level == -1) {
	    // transitioning to more coarse downsampling view (from real data)
	    if (check_ds_level >= 0) {
	      override_ds = true;
	    }
	  } else {
	    // transitioning to more coarse downsampling view
	    if (check_ds_level < old_ds_level) {
	      override_ds = true;
	    }
	  }

	  // update level if zooming has stopped or if transitioning to more coarse view
	  var new_ds_level;

	  if (zooming_stopped === true || override_ds === true) {

	    // update new_ds_level if necessary (if decreasing detail, zooming out)
	    new_ds_level = check_ds_level;

	    // set zooming_stopped to true in case of override_ds
	    zooming_stopped = true;

	    params.viz.ds_level = new_ds_level;
	  } else {
	    // keep the old level (zooming is still occuring and not zooming out)
	    new_ds_level = old_ds_level;
	  }

	  var viz_area = {};
	  var buffer_size = 5;
	  // get translation vector absolute values
	  viz_area.min_x = Math.abs(zoom_info.trans_x) / zoom_info.zoom_x - (buffer_size + 1) * params.viz.rect_width;
	  viz_area.min_y = Math.abs(zoom_info.trans_y) / zoom_info.zoom_y - (buffer_size + 1) * params.viz.rect_height;

	  viz_area.max_x = Math.abs(zoom_info.trans_x) / zoom_info.zoom_x + params.viz.clust.dim.width / zoom_info.zoom_x + buffer_size * params.viz.rect_width;

	  viz_area.max_y = Math.abs(zoom_info.trans_y) / zoom_info.zoom_y + params.viz.clust.dim.height / zoom_info.zoom_y + buffer_size * params.viz.rect_height;

	  // generate lists of visible rows/cols
	  find_viz_rows(params, viz_area);

	  var missing_rows;
	  if (make_all_rows === false) {
	    missing_rows = _.difference(params.viz.viz_nodes.row, params.viz.viz_nodes.curr_row);
	  } else {
	    // make all rows (reordering)
	    missing_rows = 'all';

	    // remove downsampled rows
	    d3.selectAll(params.root + ' .ds' + String(new_ds_level) + '_row').remove();
	  }

	  if (params.viz.ds != null) {
	    var ds_row_class = '.ds' + String(params.viz.ds_level) + '_row';
	    d3.selectAll(ds_row_class).style('display', 'block');
	  }

	  // if downsampling
	  if (new_ds_level >= 0) {
	    // remove old rows
	    d3.selectAll(params.root + ' .row').remove();
	    // remove tile tooltips and row tooltips
	    d3.selectAll(params.viz.root_tips + '_tile_tip').remove();
	    d3.selectAll(params.viz.root_tips + '_row_tip').remove();
	  }

	  // default state for downsampling
	  var inst_matrix;

	  if (new_ds_level < 0) {
	    // set matrix to default matrix
	    inst_matrix = params.matrix.matrix;

	    // make row visual-aid triangles
	    make_row_visual_aid_triangles(params);
	  } else {
	    // set matrix to downsampled matrix
	    inst_matrix = params.matrix.ds_matrix[new_ds_level];

	    d3.selectAll(params.root + ' .row_cat_group path').remove();
	  }

	  // also remove row visual aid triangles if zooming out
	  if (zooming_out === true) {
	    d3.selectAll(params.root + ' .row_cat_group path').remove();
	  }

	  // remove rows and labels that are not visible and change ds_level
	  /* run when zooming has stopped */
	  if (zooming_stopped === true) {

	    // remove not visible matrix rows
	    if (new_ds_level >= 0) {

	      // remove downsampled rows
	      d3.selectAll(params.root + ' .ds' + String(new_ds_level) + '_row').each(function (d) {
	        if (_.contains(params.viz.viz_nodes.row, d.name) === false) {
	          d3.select(this).remove();
	        }
	      });
	    } else {
	      // remove real data rows
	      d3.selectAll(params.root + ' .row').each(function (d) {
	        if (_.contains(params.viz.viz_nodes.row, d.name) === false) {
	          d3.select(this).remove();
	        }
	      });
	    }

	    // remove not visible row labels
	    d3.selectAll(params.root + ' .row_label_group').each(function (d) {
	      if (_.contains(params.viz.viz_nodes.row, d.name) === false) {
	        d3.select(this).remove();
	      }
	    });

	    // level change
	    if (new_ds_level != old_ds_level) {

	      // console.log('old: ' + String(old_ds_level) + ' new: '+ String(new_ds_level));

	      // all visible rows are missing at new downsampling level
	      missing_rows = params.viz.viz_nodes.row;

	      // remove old level rows
	      d3.selectAll(params.root + ' .ds' + String(old_ds_level) + '_row').remove();
	    }
	  }

	  // console.log('missing_rows: ' + String(missing_rows))
	  // console.log(missing_rows)

	  // only make new matrix_rows if there are missing rows
	  if (missing_rows.length >= 1 || missing_rows === 'all') {
	    make_matrix_rows(params, inst_matrix, missing_rows, new_ds_level);
	  }

	  // only make new row_labels if there are missing row_labels, downsampled, and
	  // not zooming out or zooming has stopped
	  if (new_ds_level === -1) {

	    if (zooming_out === false || zooming_stopped) {

	      // check if labels need to be made
	      ///////////////////////////////////
	      // get the names visible row_labels
	      var visible_row_labels = [];
	      d3.selectAll(params.root + ' .row_label_group').each(function (d) {
	        visible_row_labels.push(d.name);
	      });

	      // find missing labels
	      var missing_row_labels = _.difference(params.viz.viz_nodes.row, visible_row_labels);

	      // make labels
	      //////////////////////////////////
	      // only make row labels if there are any missing
	      var addback_thresh = 1;
	      if (missing_row_labels.length > addback_thresh) {
	        make_row_labels(cgm, missing_row_labels);
	      }
	    }
	  }
		};

/***/ },
/* 107 */
/***/ function(module, exports) {

	module.exports = function find_viz_rows(params, viz_area) {

	  var should_be_rows = [];
	  var curr_rows = [];

	  // find rows that should be visible
	  var y_trans;

	  // default y_scale (no downsampling)
	  var y_scale = params.viz.y_scale;
	  var ds_level = params.viz.ds_level;
	  var row_names = params.network_data.row_nodes_names;
	  var row_class = '.row';

	  // if downsampling redefine variables
	  if (ds_level >= 0) {
	    y_scale = params.viz.ds[ds_level].y_scale;
	    row_names = d3.range(params.matrix.ds_matrix[ds_level].length).map(String);
	    row_class = '.ds' + String(ds_level) + '_row';
	  }

	  // find rows that should be visible
	  for (var i = 0; i < row_names.length; i++) {
	    y_trans = y_scale(i);
	    if (y_trans < viz_area.max_y && y_trans > viz_area.min_y) {
	      should_be_rows.push(row_names[i]);
	    }
	  }

	  // find currently visible rows
	  d3.selectAll(params.root + ' ' + row_class).each(function (d) {
	    curr_rows.push(d.name);
	  });

	  // nodes that should be visible
	  params.viz.viz_nodes.row = should_be_rows;
	  // nodes that are visible
	  params.viz.viz_nodes.curr_row = curr_rows;
		};

/***/ },
/* 108 */
/***/ function(module, exports) {

	module.exports = function make_row_visual_aid_triangles(params) {

	  if (d3.select(params.root + ' .row_cat_group path').empty() === true) {
	    d3.selectAll(params.root + ' .row_cat_group').append('path').attr('d', function () {
	      var origin_x = params.viz.cat_room.symbol_width - 1;
	      var origin_y = 0;
	      var mid_x = 1;
	      var mid_y = params.viz.y_scale.rangeBand() / 2;
	      var final_x = params.viz.cat_room.symbol_width - 1;
	      var final_y = params.viz.y_scale.rangeBand();
	      var output_string = 'M ' + origin_x + ',' + origin_y + ' L ' + mid_x + ',' + mid_y + ', L ' + final_x + ',' + final_y + ' Z';
	      return output_string;
	    }).attr('fill', '#eee').style('opacity', params.viz.triangle_opacity);
	  }
		};

/***/ },
/* 109 */
/***/ function(module, exports, __webpack_require__) {

	var d3_tip_custom = __webpack_require__(48);

	module.exports = function make_col_tooltips(params) {

	  if (params.labels.show_label_tooltips) {

	    // remove old col tooltips
	    d3.selectAll(params.viz.root_tips + '_col_tip').remove();

	    // d3-tooltip
	    var col_tip = d3_tip_custom().attr('class', function () {
	      var root_tip_selector = params.viz.root_tips.replace('.', '');
	      var class_string = root_tip_selector + ' d3-tip ' + root_tip_selector + '_col_tip';
	      return class_string;
	    }).direction('w').offset([20, 0]).style('display', 'none').html(function (d) {
	      var inst_name = d.name.replace(/_/g, ' ').split('#')[0];
	      return "<span>" + inst_name + "</span>";
	    });

	    d3.select(params.viz.viz_wrapper).select('svg').select(params.root + ' .col_zoom_container').selectAll('.col_label_group').select('text').call(col_tip);

	    d3.select(params.root + ' .col_zoom_container').selectAll('.col_label_group').on('mouseover', function (d) {

	      d3.selectAll(params.viz.root_tips + '_col_tip').style('display', 'block');

	      col_tip.show(d);
	      if (params.col_tip_callback != null) {
	        params.col_tip_callback(d);
	      }
	    }).on('mouseout', function () {
	      col_tip.hide(this);

	      d3.selectAll(params.viz.root_tips + '_col_tip').style('display', 'none');
	    });
	  }
		};

/***/ },
/* 110 */
/***/ function(module, exports) {

	module.exports = function col_viz_aid_triangle(params) {

	  // x and y are flipped since its rotated
	  var reduce_rect_width = params.viz.x_scale.rangeBand() * 0.36;
	  var origin_y = -params.viz.border_width.x;
	  var start_x = 0;
	  var final_x = params.viz.x_scale.rangeBand() - reduce_rect_width;
	  var start_y = -(params.viz.x_scale.rangeBand() - reduce_rect_width + params.viz.border_width.x);
	  var final_y = -params.viz.border_width.x;
	  var output_string = 'M ' + origin_y + ',0 L ' + start_y + ',' + start_x + ', L ' + final_y + ',' + final_x + ' Z';
	  return output_string;
	};

/***/ },
/* 111 */
/***/ function(module, exports) {

	module.exports = function (params) {

	  d3.select(params.viz.viz_svg).append('rect').attr('fill', params.viz.background_color).attr('height', params.viz.super_labels.dim.width + 'px').attr('width', '3000px').classed('super_col_bkg', true).classed('white_bars', true).attr('transform', 'translate(' + params.viz.clust.margin.left + ',' + params.viz.super_labels.margin.top + ')');

	  d3.select(params.viz.viz_svg).append('text').attr('class', 'super_col').text(params.labels.super.col).attr('text-anchor', 'center').attr('transform', function () {

	    var inst_text_width = d3.select(this)[0][0].getBBox().width;

	    var inst_x = params.viz.clust.dim.width / 2 + params.viz.norm_labels.width.row - inst_text_width / 2;
	    var inst_y = params.viz.super_labels.dim.width;
	    return 'translate(' + inst_x + ',' + inst_y + ')';
	  }).style('font-size', function () {
	    var inst_font_size = params.labels.super_label_fs * params.labels.super_label_scale;
	    return inst_font_size + 'px';
	  }).style('font-weight', 300);

	  d3.select(params.viz.viz_svg).append('rect').attr('fill', params.viz.background_color).attr('width', params.viz.super_labels.dim.width + 'px').attr('height', '3000px').classed('super_row_bkg', true).classed('white_bars', true).attr('transform', 'translate(' + params.viz.super_labels.margin.left + ',0)');

	  // append super title row group - used to separate translation from rotation
	  d3.select(params.viz.viz_svg).append('g').classed('super_row', true).attr('transform', function () {
	    // position in the middle of the clustergram
	    var inst_x = params.viz.super_labels.dim.width;
	    var inst_y = params.viz.clust.dim.height / 2 + params.viz.norm_labels.width.col;
	    return 'translate(' + inst_x + ',' + inst_y + ')';
	  });

	  // super row label (rotate the already translated title )
	  d3.select(params.root + ' .super_row').append('text').text(params.labels.super.row).attr('text-anchor', 'center').attr('transform', function () {
	    var inst_text_width = d3.select(this)[0][0].getBBox().width;
	    var inst_x_offset = inst_text_width / 2 + params.viz.norm_labels.width.col;
	    var inst_offset = 'translate(0,' + inst_x_offset + '), rotate(-90)';
	    return inst_offset;
	  }).style('font-size', function () {
	    var inst_font_size = params.labels.super_label_fs * params.labels.super_label_scale;
	    return inst_font_size + 'px';
	  }).style('font-weight', 300)
			.attr("dy", "1em");
		};

/***/ },
/* 112 */
/***/ function(module, exports, __webpack_require__) {

	var get_cat_title = __webpack_require__(113);
	var ini_cat_reorder = __webpack_require__(114);
	var make_row_cat_super_labels = __webpack_require__(122);
	var make_dendro_crop_buttons = __webpack_require__(60);

	module.exports = function Spillover(cgm) {

	  var params = cgm.params;

	  var viz = params.viz;

	  // hide spillover from slanted column labels on right side
	  d3.select(viz.root + ' .col_container').append('path').style('stroke-width', '0').attr('d', 'M 0,0 L 1000,-1000, L 1000,0 Z').attr('fill', viz.background_color) //!! prog_colors
	  .attr('class', 'right_slant_triangle').attr('transform', 'translate(' + viz.clust.dim.width + ',' + viz.norm_labels.width.col + ')');

	  // hide spillover from slanted column labels on left side
	  d3.select(viz.root + ' .col_container').append('path').style('stroke-width', '0').attr('d', 'M 0,0 L 500,-500, L 0,-500 Z').attr('fill', viz.background_color).attr('class', 'left_slant_triangle')
	  // shift left by 1 px to prevent cutting off labels
	  .attr('transform', 'translate(-1,' + viz.norm_labels.width.col + ')');

	  var rect_height = viz.clust.margin.top + viz.uni_margin / 5;
	  // white rect to cover excess labels
	  d3.select(viz.viz_svg).append('rect').attr('fill', viz.background_color) //!! prog_colors
	  .attr('width', viz.clust.margin.left).attr('height', rect_height).attr('class', 'top_left_white');

	  var inst_height = viz.cat_room.col + 1.5 * viz.uni_margin;
	  // white rect to cover excess labels
	  d3.select(viz.viz_svg).append('rect').attr('fill', viz.background_color).attr('width', 2 * viz.clust.dim.width).attr('height', inst_height).attr('class', 'top_right_white').attr('transform', function () {
	    var tmp_left = viz.clust.margin.left + viz.clust.dim.width;
	    var tmp_top = viz.norm_labels.width.col + viz.norm_labels.margin.top - viz.uni_margin;
	    return 'translate(' + tmp_left + ', ' + tmp_top + ')';
	  });

	  x_offset = viz.clust.margin.left + viz.clust.dim.width + viz.uni_margin;
	  y_offset = viz.norm_labels.margin.top + viz.norm_labels.width.col + 2.5 * viz.uni_margin;
	  var cat_text_size = 1.15 * viz.cat_room.symbol_width;
	  var cat_super_opacity = 0.65;
	  var extra_y_room = 1.25;

	  // col category super labels
	  if (viz.show_categories.col) {

	    d3.select(viz.viz_svg).selectAll().data(viz.all_cats.col).enter().append('text').classed('col_cat_super', true).style('font-size', cat_text_size + 'px').style('opacity', cat_super_opacity).style('cursor', 'default').attr('transform', function (d) {
	      var inst_cat = parseInt(d.split('-')[1], 10);
	      var inst_y = y_offset + extra_y_room * viz.cat_room.symbol_width * inst_cat;
	      return 'translate(' + x_offset + ',' + inst_y + ')';
	    }).text(function (d) {
	      return get_cat_title(viz, d, 'col');
	    });
	  }

	  // row category super labels
	  make_row_cat_super_labels(cgm);

	  // white border bottom - prevent clustergram from hitting border
	  if (viz.show_dendrogram) {
	    // quick fix to make room for crop buttons
	    y_offset = viz.clust.margin.top + viz.clust.dim.height + viz.dendro_room.col - 2 * viz.uni_margin;
	  } else {
	    y_offset = viz.clust.margin.top + viz.clust.dim.height;
	  }

	  var b_spill_container = d3.select(viz.viz_svg).append('g').classed('bottom_spillover_container', true).attr('transform', function () {
	    // shift up enough to show the entire border width
	    return 'translate(0,' + y_offset + ')';
	  });

	  b_spill_container.append('rect').attr('class', 'bottom_spillover').attr('fill', viz.background_color) //!! prog_colors
	  .attr('width', viz.svg_dim.width).attr('height', 2 * viz.svg_dim.height);

	  x_offset = viz.clust.margin.left;
	  y_offset = 0;
	  b_spill_container.append('g').classed('col_dendro_icons_container', true).attr('transform', 'translate(' + x_offset + ',' + y_offset + ')').append('g').classed('col_dendro_icons_group', true);

	  make_dendro_crop_buttons(cgm, 'col');

	  var x_offset = viz.clust.margin.left + viz.clust.dim.width;
	  var y_offset = viz.clust.margin.top + viz.clust.dim.height;
	  var tmp_width = viz.cat_room.col + viz.clust.dim.width;
	  var tmp_height = viz.cat_room.row + 10 * viz.uni_margin;
	  d3.select(viz.viz_svg).append('rect').attr('fill', viz.background_color).attr('width', tmp_width).attr('height', tmp_height).attr('transform', function () {
	    return 'translate(' + x_offset + ',' + y_offset + ')';
	  }).classed('white_bars', true).classed('dendro_corner_spillover', true);

	  // hide spillover left top of col dendrogram
	  x_offset = 0;
	  y_offset = viz.clust.margin.top + viz.clust.dim.height;
	  tmp_width = viz.clust.margin.left;
	  tmp_height = viz.clust.dim.height * 10;
	  d3.select(viz.viz_svg).append('rect').attr('fill', viz.background_color).attr('width', tmp_width).attr('height', tmp_height).attr('transform', function () {
	    return 'translate(' + x_offset + ',' + y_offset + ')';
	  }).classed('white_bars', true).classed('dendro_col_spillover', true);

	  ini_cat_reorder(cgm);
		};

/***/ },
/* 113 */
/***/ function(module, exports) {

	module.exports = function get_cat_title(viz, inst_cat, inst_rc) {
	  var cat_title;

	  // make default title if none is given
	  if (viz.cat_names[inst_rc][inst_cat] === inst_cat) {
	    var inst_num = parseInt(inst_cat.split('-')[1], 10) + 1;
	    // generate placeholder title
	    cat_title = 'Category ' + inst_num;
	  } else {
	    // make real title
	    cat_title = viz.cat_names[inst_rc][inst_cat];
	  }

	  return cat_title;
		};

/***/ },
/* 114 */
/***/ function(module, exports, __webpack_require__) {

	var all_reorder = __webpack_require__(115);

	module.exports = function ini_cat_reorder(cgm) {
	  /* eslint-disable */

	  var params = cgm.params;

	  _.each(['row', 'col'], function (inst_rc) {

	    if (params.viz.show_categories[inst_rc]) {
	      d3.selectAll(params.root + ' .' + inst_rc + '_cat_super').on('dblclick', function () {

	        if (params.sim_mat) {
	          inst_rc = 'both';
	        }

	        d3.selectAll(params.root + ' .toggle_' + inst_rc + '_order .btn').classed('active', false);

	        var order_id = this.__data__.replace('-', '_') + '_index';
	        if (params.viz.sim_mat) {
	          all_reorder(cgm, order_id, 'row');
	          all_reorder(cgm, order_id, 'col');
	        } else {
	          all_reorder(cgm, order_id, inst_rc);
	        }
	      });
	    }
	  });
	};

/***/ },
/* 115 */
/***/ function(module, exports, __webpack_require__) {

	var toggle_dendro_view = __webpack_require__(54);
	var show_visible_area = __webpack_require__(106);
	var ini_zoom_info = __webpack_require__(36);
	var calc_downsampled_levels = __webpack_require__(27);
	var two_translate_zoom = __webpack_require__(116);
	var get_previous_zoom = __webpack_require__(101);

	module.exports = function (cgm, inst_order, inst_rc) {

	  var params = cgm.params;

	  var prev_zoom = get_previous_zoom(params);

	  var delay_reorder = 0;
	  if (prev_zoom.zoom_y != 1 || prev_zoom.zoom_x != 1) {
	    // reset zoom before reordering
	    two_translate_zoom(cgm, 0, 0, 1);
	    delay_reorder = 1200;
	  }

	  // row/col names are swapped, will improve later
	  var other_rc;
	  if (inst_rc === 'row') {
	    other_rc = 'col';
	  } else if (inst_rc === 'col') {
	    other_rc = 'row';
	  }

	  params.viz.run_trans = true;

	  // save order state
	  if (other_rc === 'row') {
	    params.viz.inst_order.row = inst_order;
	  } else if (other_rc === 'col') {
	    params.viz.inst_order.col = inst_order;
	  }

	  if (params.viz.show_dendrogram) {
	    toggle_dendro_view(cgm, inst_rc);
	  }

	  if (other_rc === 'row') {
	    params.viz.x_scale.domain(params.matrix.orders[params.viz.inst_order.row + '_row']);
	  } else if (other_rc == 'col') {
	    params.viz.y_scale.domain(params.matrix.orders[params.viz.inst_order.col + '_col']);
	  }

	  // only animate transition if there are a small number of tiles
	  var t;
	  if (d3.selectAll(params.root + ' .tile')[0].length < params.matrix.def_large_matrix) {
	    t = d3.select(params.root + ' .viz_svg').transition().duration(2500).delay(delay_reorder);
	  } else {
	    t = d3.select(params.root + ' .viz_svg');
	  }

	  var row_nodes_names = params.network_data.row_nodes_names;
	  var col_nodes_names = params.network_data.col_nodes_names;

	  // only update matrix if not downsampled (otherwise rows are updated)
	  if (params.viz.ds_level === -1) {

	    t.selectAll('.row').attr('transform', function (d) {
	      var inst_index = _.indexOf(row_nodes_names, d.name);
	      return 'translate(0,' + params.viz.y_scale(inst_index) + ')';
	    }).selectAll('.tile').attr('transform', function (d) {
	      return 'translate(' + params.viz.x_scale(d.pos_x) + ' , 0)';
	    });

	    t.selectAll('.tile_up').attr('transform', function (d) {
	      return 'translate(' + params.viz.x_scale(d.pos_x) + ' , 0)';
	    });

	    t.selectAll('.tile_dn').attr('transform', function (d) {
	      return 'translate(' + params.viz.x_scale(d.pos_x) + ' , 0)';
	    });
	  }

	  // Move Row Labels
	  t.select('.row_label_zoom_container').selectAll('.row_label_group').attr('transform', function (d) {
	    var inst_index = _.indexOf(row_nodes_names, d.name);
	    return 'translate(0,' + params.viz.y_scale(inst_index) + ')';
	  });

	  // Move Col Labels
	  t.select('.col_zoom_container').selectAll('.col_label_text').attr('transform', function (d) {
	    var inst_index = _.indexOf(col_nodes_names, d.name);
	    return 'translate(' + params.viz.x_scale(inst_index) + ') rotate(-90)';
	  });

	  // reorder row categories
	  t.selectAll('.row_cat_group').attr('transform', function (d) {
	    var inst_index = _.indexOf(row_nodes_names, d.name);
	    return 'translate(0,' + params.viz.y_scale(inst_index) + ')';
	  });

	  // reorder col_class groups
	  t.selectAll('.col_cat_group').attr('transform', function (d) {
	    var inst_index = _.indexOf(col_nodes_names, d.name);
	    return 'translate(' + params.viz.x_scale(inst_index) + ',0)';
	  });

	  // redefine x and y positions
	  params.network_data.links.forEach(function (d) {
	    d.x = params.viz.x_scale(d.target);
	    d.y = params.viz.y_scale(d.source);
	  });

	  params.zoom_info = ini_zoom_info();

	  // calculate downsmapling if necessary
	  if (params.viz.ds_num_levels > 0 && params.viz.ds_level >= 0) {

	    calc_downsampled_levels(params);
	    var zooming_stopped = true;
	    var zooming_out = true;
	    var make_all_rows = true;

	    // show_visible_area is also run with two_translate_zoom, but at that point
	    // the parameters were not updated and two_translate_zoom if only run
	    // if needed to reset zoom
	    show_visible_area(cgm, zooming_stopped, zooming_out, make_all_rows);
	  }

	  setTimeout(function () {
	    params.viz.run_trans = false;
	  }, 2500);
		};

/***/ },
/* 116 */
/***/ function(module, exports, __webpack_require__) {

	var utils = __webpack_require__(2);
	var label_constrain_and_trim = __webpack_require__(117);
	var show_visible_area = __webpack_require__(106);
	var ini_zoom_info = __webpack_require__(36);
	var toggle_grid_lines = __webpack_require__(121);

	module.exports = function two_translate_zoom(cgm, pan_dx, pan_dy, fin_zoom) {

	  // console.log('pan_dy: ' + String(pan_dy))

	  var params = cgm.params;

	  d3.selectAll(params.viz.root_tips).style('display', 'none');

	  params.zoom_info = ini_zoom_info();

	  show_visible_area(cgm);

	  // do not allow while transitioning, e.g. reordering
	  if (!params.viz.run_trans) {

	    // define the commonly used variable half_height
	    var half_height = params.viz.clust.dim.height / 2;

	    // y pan room, the pan room has to be less than half_height since
	    // zooming in on a gene that is near the top of the clustergram also causes
	    // panning out of the visible region
	    var y_pan_room = half_height / fin_zoom;

	    // prevent visualization from panning down too much
	    // when zooming into genes near the top of the clustergram
	    if (pan_dy >= half_height - y_pan_room) {

	      // console.log(' prevent visualization from panning down too much')

	      // explanation of panning rules
	      /////////////////////////////////
	      /*
	        prevent the clustergram from panning down too much
	        if the amount of panning is equal to the half_height then it needs to be reduced
	        effectively, the the visualization needs to be moved up (negative) by some factor
	        of the half-width-of-the-visualization.
	         If there was no zooming involved, then the
	        visualization would be centered first, then panned to center the top term
	        this would require a
	        correction to re-center it. However, because of the zooming the offset is
	        reduced by the zoom factor (this is because the panning is occurring on something
	        that will be zoomed into - this is why the pan_dy value is not scaled in the two
	        translate transformations, but it has to be scaled afterwards to set the translate
	        vector)
	        pan_dy = half_height - (half_height)/fin_zoom
	         if pan_dy is greater than the pan room, then panning has to be restricted
	        start by shifting back up (negative) by half_height/fin_zoom then shift back down
	        by the difference between half_height and pan_dy (so that the top of the clustergram is
	        visible)
	      */

	      var shift_top_viz = half_height - pan_dy;
	      var shift_up_viz = -half_height / fin_zoom + shift_top_viz;

	      // reduce pan_dy so that the visualization does not get panned to far down
	      pan_dy = pan_dy + shift_up_viz;
	    }

	    // prevent visualization from panning up too much
	    // when zooming into genes at the bottom of the clustergram
	    if (pan_dy < -(half_height - y_pan_room)) {

	      shift_top_viz = half_height + pan_dy;

	      shift_up_viz = half_height / fin_zoom - shift_top_viz; //- move_up_one_row;

	      // reduce pan_dy so that the visualization does not get panned to far down
	      pan_dy = pan_dy + shift_up_viz;
	    }

	    // will improve this !!
	    var zoom_y = fin_zoom;
	    var zoom_x = 1;

	    // search duration - the duration of zooming and panning
	    var search_duration = 700;

	    // center_y
	    var center_y = -(zoom_y - 1) * half_height;

	    // transform clust group
	    ////////////////////////////
	    d3.select(params.root + ' .clust_group').transition().duration(search_duration)
	    // first apply the margin transformation
	    // then zoom, then apply the final transformation
	    .attr('transform', 'translate(' + [0, 0 + center_y] + ')' + ' scale(' + zoom_x + ',' + zoom_y + ')' + 'translate(' + [pan_dx, pan_dy] + ')');

	    // transform row labels
	    d3.select(params.root + ' .row_label_zoom_container').transition().duration(search_duration).attr('transform', 'translate(' + [0, center_y] + ')' + ' scale(' + zoom_y + ',' + zoom_y + ')' + 'translate(' + [0, pan_dy] + ')');

	    // transform row_cat_container
	    // use the offset saved in params, only zoom in the y direction
	    d3.select(params.root + ' .row_cat_container').transition().duration(search_duration).attr('transform', 'translate(' + [0, center_y] + ')' + ' scale(' + 1 + ',' + zoom_y + ')' + 'translate(' + [0, pan_dy] + ')');

	    d3.select(params.root + ' .row_dendro_container').transition().duration(search_duration).attr('transform', 'translate(' + [0, center_y] + ')' + ' scale(' + zoom_x + ',' + zoom_y + ')' + 'translate(' + [params.viz.uni_margin / 2, pan_dy] + ')');

	    // toggle crop buttons
	    var inst_button_opacity;
	    _.each(['row', 'col'], function (inst_rc) {

	      inst_button_opacity = d3.select(params.root + ' .' + inst_rc + '_dendro_crop_buttons').style('opacity');
	      d3.selectAll(params.root + ' .' + inst_rc + '_dendro_crop_buttons').style('opacity', 0);
	      setTimeout(show_crop_buttons, 700, inst_rc, inst_button_opacity);
	    });

	    // transform col labels
	    d3.select(params.root + ' .col_zoom_container').transition().duration(search_duration).attr('transform', ' scale(' + zoom_x + ',' + zoom_x + ')' + 'translate(' + [pan_dx, 0] + ')');

	    // transform col_class
	    d3.select(params.root + ' .col_cat_container').transition().duration(search_duration).attr('transform', ' scale(' + zoom_x + ',' + 1 + ')' + 'translate(' + [pan_dx, 0] + ')');

	    d3.select(params.root + ' .col_dendro_container').transition().duration(search_duration).attr('transform', ' scale(' + zoom_x + ',' + 1 + ')' + 'translate(' + [pan_dx, params.viz.uni_margin / 2] + ')');

	    // set y translate: center_y is positive, positive moves the visualization down
	    // the translate vector has the initial margin, the first y centering, and pan_dy
	    // times the scaling zoom_y
	    var net_y_offset = params.viz.clust.margin.top + center_y + pan_dy * zoom_y;
	    var net_x_offset = params.viz.clust.margin.left + pan_dx;

	    // reset the zoom and translate
	    params.zoom_behavior.scale(zoom_y).translate([net_x_offset, net_y_offset]);

	    label_constrain_and_trim(params);

	    // re-size of the highlighting rects
	    /////////////////////////////////////////
	    if (d3.select(params.root + ' .row_label_zoom_container text').empty() === false) {
	      d3.select(params.root + ' .row_label_zoom_container').each(function () {
	        // get the bounding box of the row label text
	        var bbox = d3.select(this).select('text')[0][0].getBBox();

	        // use the bounding box to set the size of the rect
	        d3.select(this).select('rect').attr('x', bbox.x * 0.5).attr('y', 0).attr('width', bbox.width * 0.5).attr('height', params.viz.y_scale.rangeBand()).style('fill', 'yellow');
	      });
	    }

	    // reset crop button zooming
	    d3.select(params.root + ' .row_dendro_icons_group').attr('transform', 'translate(' + [0, 0 + center_y] + ')' + ' scale(' + zoom_x + ',' + zoom_y + ')' + 'translate(' + [pan_dx, pan_dy] + ')');

	    d3.select(params.root + ' .row_dendro_icons_group').selectAll('path').attr('transform', function (d) {
	      var inst_x = params.viz.uni_margin;
	      var inst_y = d.pos_mid;
	      return 'translate(' + inst_x + ',' + inst_y + ') ' + 'scale(1, ' + 1 / zoom_y + ')';
	    });

	    // console.log('zooming x and y')
	    // console.log(zoom_x)
	    // console.log(zoom_y)

	    // need to improve behavior
	    d3.select(params.root + ' .col_dendro_icons_group').attr('transform', function () {
	      var inst_trans =
	      // 'translate(' + [0, 0 + center_y] + ')' +
	      ' scale(' + zoom_x + ',' + zoom_y + ')';
	      // + 'translate(' + [pan_dx, pan_dy ] + ')';
	      return inst_trans;
	    });

	    d3.select(params.root + ' .col_dendro_icons_group').selectAll('path').attr('transform', function (d) {
	      var inst_x = d.pos_mid;
	      var inst_y = params.viz.uni_margin;
	      // return 'translate('+ inst_x +',' + inst_y + ') ' + 'scale('+1/zoom_x+',1)';
	      return 'translate(' + inst_x + ',' + inst_y + ') ' + 'scale(1,1)';
	    });

	    // column value bars
	    ///////////////////////
	    // reduce the height of the column value bars based on the zoom applied
	    // recalculate the height and divide by the zooming scale
	    // col_label_obj.select('rect')
	    if (utils.has(params.network_data.col_nodes[0], 'value')) {

	      d3.selectAll(params.root + ' .col_bars').attr('width', function (d) {
	        var inst_value = 0;
	        if (d.value > 0) {
	          inst_value = params.labels.bar_scale_col(d.value) / zoom_x;
	        }
	        return inst_value;
	      });
	    }

	    if (utils.has(params.network_data.row_nodes[0], 'value')) {

	      d3.selectAll(params.root + ' .row_bars').transition().duration(search_duration).attr('width', function (d) {
	        var inst_value = 0;
	        inst_value = params.labels.bar_scale_row(Math.abs(d.value)) / zoom_y;
	        return inst_value;
	      }).attr('x', function (d) {
	        var inst_value = 0;
	        inst_value = -params.labels.bar_scale_row(Math.abs(d.value)) / zoom_y;
	        return inst_value;
	      });
	    }

	    toggle_grid_lines(params);
	  }

	  function show_crop_buttons(inst_rc, inst_button_opacity) {
	    d3.selectAll(params.root + ' .' + inst_rc + '_dendro_crop_buttons').transition().duration(search_duration).style('opacity', inst_button_opacity);
	  }
		};

/***/ },
/* 117 */
/***/ function(module, exports, __webpack_require__) {

	var utils = __webpack_require__(2);
	var trim_text = __webpack_require__(118);
	var constrain_font_size = __webpack_require__(119);

	module.exports = function label_constrain_and_trim(params) {

	  // console.log('label_constrain_and_trim');

	  // reset text in rows and columns
	  d3.selectAll(params.root + ' .row_label_group').select('text').text(function (d) {
	    return utils.normal_name(d);
	  });

	  d3.selectAll(params.root + ' .col_label_text').select('text').text(function (d) {
	    return utils.normal_name(d);
	  });

	  constrain_font_size(params);

	  d3.selectAll(params.root + ' .row_label_group').each(function () {
	    trim_text(params, this, 'row');
	  });

	  d3.selectAll(params.root + ' .col_label_group').each(function () {
	    trim_text(params, this, 'col');
	  });
		};

/***/ },
/* 118 */
/***/ function(module, exports) {


	module.exports = function (params, inst_selection, inst_rc) {
	  if (d3.select(inst_selection).style('display') != 'none') {

	    // trim text that is longer than the container
	    var inst_zoom;
	    var inst_width;
	    var trimmed_text;
	    var current_num_char;
	    var inst_text;
	    var original_text;
	    var keep_num_char;
	    var i;

	    var max_width = params.viz.norm_labels.width[inst_rc];

	    if (inst_rc === 'row') {
	      if (params.viz.zoom_ratio.y) {
	        inst_zoom = params.zoom_behavior.scale() / params.viz.zoom_ratio.y;
	      } else {
	        inst_zoom = params.zoom_behavior.scale();
	      }
	      // num_trims = params.labels.row_max_char;
	    } else {
	      if (params.viz.zoom_ratio.x > 1) {
	        inst_zoom = params.zoom_behavior.scale() / params.viz.zoom_ratio.x;
	      } else {
	        inst_zoom = params.zoom_behavior.scale();
	      }
	      // num_trims = params.labels.col_max_char;
	    }

	    var num_trims;
	    d3.select(inst_selection).select('text').each(function (d) {
	      num_trims = d.name.length;
	    });

	    var tmp_width = d3.select(inst_selection).select('text').node().getBBox().width;

	    inst_width = calc_width(tmp_width, inst_zoom);

	    if (inst_width > max_width) {

	      for (i = 1; i < num_trims; i++) {
	        if (inst_width > max_width) {

	          d3.select(inst_selection).select('text').text(trim);

	          tmp_width = d3.select(inst_selection).select('text').node().getBBox().width;

	          inst_width = calc_width(tmp_width, inst_zoom);
	        }
	      }
	    } else if (inst_width < max_width * 0.75) {

	      for (i = 1; i < num_trims; i++) {
	        if (inst_width < max_width * 0.75) {

	          d3.select(inst_selection).select('text').text(add_back);

	          tmp_width = d3.select(inst_selection).select('text').node().getBBox().width;

	          inst_width = calc_width(tmp_width, inst_zoom);
	        }
	      }
	    }
	  }

	  function trim() {
	    inst_text = d3.select(this).text();
	    current_num_char = inst_text.length;
	    keep_num_char = current_num_char - 3;
	    trimmed_text = inst_text.substring(0, keep_num_char) + '..';
	    return trimmed_text;
	  }

	  function add_back(d) {
	    inst_text = d3.select(this).text();
	    if (inst_text.slice(-2) === '..') {
	      current_num_char = inst_text.length - 2;
	    } else {
	      current_num_char = inst_text.length;
	    }

	    original_text = d.name;
	    keep_num_char = current_num_char + 2;
	    trimmed_text = original_text.substring(0, keep_num_char) + '..';

	    // if '..' was added to original text
	    if (trimmed_text.length > original_text.length) {
	      trimmed_text = original_text;
	    }

	    return trimmed_text;
	  }

	  function calc_width(tmp_width, inst_zoom) {
	    if (inst_zoom < 1) {
	      inst_width = tmp_width;
	    } else {
	      inst_width = tmp_width * inst_zoom;
	    }

	    return inst_width;
	  }
		};

/***/ },
/* 119 */
/***/ function(module, exports, __webpack_require__) {

	var calc_real_font_size = __webpack_require__(120);

	module.exports = function constrain_font_size(params) {

	  var tmp_font_size = params.labels.default_fs_row;
	  var inst_zoom;
	  var min_font_size = 3;

	  var real_font_size = calc_real_font_size(params);

	  // rows
	  ////////////////////////////////////
	  if (real_font_size.row > min_font_size) {

	    if (real_font_size.row > params.labels.max_allow_fs) {

	      if (params.viz.zoom_ratio.y) {
	        inst_zoom = params.zoom_behavior.scale() / params.viz.zoom_ratio.y;
	      } else {
	        inst_zoom = params.zoom_behavior.scale();
	      }

	      if (inst_zoom < 1) {
	        inst_zoom = 1;
	      }

	      tmp_font_size = params.labels.max_allow_fs / inst_zoom;

	      d3.selectAll(params.root + ' .row_label_group').select('text').style('font-size', tmp_font_size + 'px').attr('y', params.viz.rect_height * 0.5 + tmp_font_size * 0.35);
	    } else {
	      d3.selectAll(params.root + ' .row_label_group').select('text').style('font-size', params.labels.default_fs_row + 'px').attr('y', params.viz.rect_height * 0.5 + params.labels.default_fs_row * 0.35);
	    }
	  }

	  // columns
	  //////////////////////////////////////
	  if (real_font_size.col > min_font_size) {

	    if (real_font_size.col > params.labels.max_allow_fs) {

	      if (params.viz.zoom_ratio.x > 1) {
	        inst_zoom = params.zoom_behavior.scale() / params.viz.zoom_ratio.x;
	      } else {
	        inst_zoom = params.zoom_behavior.scale();
	      }

	      if (inst_zoom < 1) {
	        inst_zoom = 1;
	      }

	      tmp_font_size = params.labels.max_allow_fs / inst_zoom;

	      if (tmp_font_size > 0.7 * params.viz.rect_width) {
	        tmp_font_size = 0.7 * params.viz.rect_width;
	      }

	      d3.selectAll(params.root + ' .col_label_text').select('text').style('font-size', tmp_font_size + 'px');
	    } else {
	      d3.selectAll(params.root + ' .col_label_text').select('text').style('font-size', params.labels.default_fs_col + 'px');
	    }
	  }
		};

/***/ },
/* 120 */
/***/ function(module, exports) {

	module.exports = function calc_real_font_size(params) {

	  var real_font_size = {};
	  // zoom_switch behavior has to change with zoom_ratio.y
	  if (params.viz.zoom_ratio.x > 1) {
	    real_font_size.row = params.labels.default_fs_row * params.zoom_behavior.scale();
	    real_font_size.col = params.labels.default_fs_col * params.zoom_behavior.scale();
	  } else {
	    real_font_size.row = params.labels.default_fs_row * params.zoom_behavior.scale() / params.viz.zoom_ratio.y;
	    real_font_size.col = params.labels.default_fs_col * params.zoom_behavior.scale();
	  }

	  return real_font_size;
		};

/***/ },
/* 121 */
/***/ function(module, exports) {

	module.exports = function toggle_grid_lines(params) {

	  if (params.zoom_info.zoom_x * params.viz.border_width.x > 1) {
	    d3.selectAll(params.root + ' .vert_lines').select('line').style('display', 'block').style('opacity', 0).transition().style('opacity', 1);
	  } else {
	    d3.selectAll(params.root + ' .vert_lines').select('line').style('display', 'none');
	  }

	  if (params.zoom_info.zoom_y * params.viz.border_width.y > 1) {
	    d3.selectAll(params.root + ' .horz_lines').select('line').style('display', 'block').style('opacity', 0).transition().style('opacity', 1);
	  } else {
	    d3.selectAll(params.root + ' .horz_lines').select('line').style('display', 'none');
	  }
	};

/***/ },
/* 122 */
/***/ function(module, exports, __webpack_require__) {

	var get_cat_title = __webpack_require__(113);
	var d3_tip_custom = __webpack_require__(48);

	module.exports = function make_row_cat_super_labels(cgm) {

	  var params = cgm.params;

	  var viz = params.viz;
	  var extra_x_room = 2.75;

	  if (d3.select(params.root + ' .row_cat_label_container').empty()) {

	    d3.select(cgm.params.viz.viz_svg).append('g').classed('row_cat_label_container', true);

	    // append background section for optional value-bars (e.g. enrichment pvals)
	    d3.select(cgm.params.viz.viz_svg + ' .row_cat_label_container').append('g').classed('row_cat_label_bar_container', true);
	  }

	  var x_offset = viz.clust.margin.left + viz.clust.dim.width + viz.uni_margin;
	  var y_offset = viz.norm_labels.margin.top + viz.norm_labels.width.col + 2.5 * viz.uni_margin;
	  var cat_text_size = 1.15 * viz.cat_room.symbol_width;
	  var cat_super_opacity = 0.65;
	  var extra_y_room = 1.25;

	  d3.select(params.root + ' .row_cat_label_container').attr('transform', function () {
	    x_offset = viz.norm_labels.margin.left + viz.norm_labels.width.row + viz.cat_room.symbol_width + extra_x_room * viz.uni_margin;
	    y_offset = viz.clust.margin.top - viz.uni_margin;
	    return 'translate(' + x_offset + ',' + y_offset + ') rotate(-90)';
	  });

	  // clear old categories
	  d3.selectAll(params.root + ' .row_cat_label_container text').remove();
	  d3.selectAll(params.root + ' .row_cat_selection_bar').remove();
	  // d3.selectAll(params.root+' .row_cat_label_bar_container rect').remove();

	  // remove any old row_cat_super tooltips from this visualization
	  d3.selectAll(cgm.params.viz.root_tips + '_row_cat_super').remove();

	  // d3-tooltip
	  var tmp_y_offset = 50; // viz.clust.margin.top - viz.uni_margin;
	  var tmp_x_offset = -75;
	  var cat_tip = d3_tip_custom().attr('class', function () {
	    var root_tip_selector = params.viz.root_tips.replace('.', '');
	    var class_string = root_tip_selector + ' d3-tip ' + root_tip_selector + '_row_cat_super';
	    return class_string;
	  }).direction('south_custom').offset([tmp_y_offset, tmp_x_offset]).style('display', 'none').style('opacity', 0).html(function (d) {

	    var full_string;

	    var tmp_string = params.network_data.row_nodes[0][d];

	    if (tmp_string.indexOf('<p>') > -1) {

	      var start_string = tmp_string.split(': ')[0];
	      var end_string = tmp_string.split('<p>')[1];

	      full_string = start_string + '<p>' + end_string;
	    } else {

	      full_string = get_cat_title(viz, d, 'row');
	    }

	    return full_string;
	  });

	  var unit_length = extra_y_room * viz.cat_room.symbol_width;
	  var bar_width = unit_length * 0.9;

	  // show row label categories even if viewing a simmilarity matrix

	  d3.select(params.root + ' .row_cat_label_container').selectAll().data(viz.all_cats.row).enter().append('text').style('width', '100px').style('height', bar_width + 'px').classed('row_cat_super', true).style('font-size', cat_text_size + 'px').style('opacity', cat_super_opacity).style('cursor', 'default').attr('transform', function (d) {
	    var inst_y = extra_y_room * viz.cat_room.symbol_width * parseInt(d.split('-')[1], 10);
	    return 'translate(0,' + inst_y + ')';
	  }).text(function (d) {

	    return get_cat_title(viz, d, 'row');
	  });

	  // selection bar
	  ///////////////////////////////
	  d3.select(params.root + ' .row_cat_label_container').selectAll().data(viz.all_cats.row).enter().append('rect').classed('row_cat_super', true).classed('row_cat_selection_bar', true).style('height', bar_width + 'px').style('fill', 'green').style('width', '120px').style('opacity', 0).attr('transform', function (d) {
	    var inst_y = unit_length * (parseInt(d.split('-')[1], 10) - 0.75);
	    return 'translate(0,' + inst_y + ')';
	  }).on('mouseover', function (d) {

	    d3.selectAll(params.viz.root_tips + '_row_cat_super').style('display', 'block').style('opacity', 1);

	    cat_tip.show(d);
	  }).on('mouseout', function () {
	    cat_tip.hide(this);
	    // might not need
	    d3.selectAll('.d3-tip').style('display', 'none');

	    d3.selectAll(params.viz.root_tips + '_row_cat_super').style('display', 'none').style('opacity', 0);
	  });

	  // row category super-label mouseover
	  //////////////////////////////////////
	  if (d3.select(params.root + ' .row_cat_selection_bar').empty() === false) {
	    d3.selectAll(params.root + ' .row_cat_selection_bar').call(cat_tip);
	  }

	  if (_.has(params.network_data, 'row_cat_bars')) {

	    // Enrichrgram title
	    /////////////////////
	    d3.select(params.root + ' .enr_title').remove();

	    var enr_title = d3.select(params.root + ' .viz_svg').append('g').classed('enr_title', true).attr('transform', function () {
	      var trans = d3.select(params.root + ' .row_cat_label_container').attr('transform').split('(')[1].split(')')[0];
	      var x_offset = Number(trans.split(',')[0]) - 10;

	      return 'translate(' + String(x_offset) + ', 0)';
	    });

	    enr_title.append('rect').attr('width', params.viz.cat_room.row).attr('height', 25).attr('fill', 'white');

	    var library_string = params.network_data.enrichrgram_lib.substring(0, 40);

	    enr_title.append('text').attr('transform', 'translate(0, 17)').text(library_string.replace(/_/g, ' ')).style('font-size', '15px').attr('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif');

	    // Enrichr bars
	    ////////////////////
	    d3.selectAll(params.root + ' .enrichr_bars').remove();

	    var bar_height = params.viz.clust.margin.top - 35;
	    var max_score = params.network_data.row_cat_bars[0];
	    var bar_scale = d3.scale.linear().domain([0, max_score]).range([0, bar_height]);

	    d3.select(params.root + ' .row_cat_label_bar_container').selectAll().data(params.network_data.row_cat_bars).enter().append('rect').classed('enrichr_bars', true).attr('height', bar_width + 'px').attr('fill', 'red').attr('width', function (d) {
	      var bar_length = bar_scale(d);
	      return bar_length + 'px';
	    }).attr('opacity', 0.4).attr('transform', function (d, i) {
	      var inst_y = unit_length * (i - 0.75);
	      return 'translate(0, ' + inst_y + ')';
	    });
	  }
		};

/***/ },
/* 123 */
/***/ function(module, exports, __webpack_require__) {

	var resize_viz = __webpack_require__(124);

	module.exports = function initialize_resizing(cgm) {

	  var params = cgm.params;

	  var exp_button;

	  // d3.select(window).on('resize', null);

	  // // resize window
	  // if (params.viz.resize) {
	  //   d3.select(window).on('resize', function () {

	  //     d3.select(params.viz.viz_svg).style('opacity', 0.5);

	  //     var wait_time = 500;
	  //     if (params.viz.run_trans === true) {
	  //       wait_time = 2500;
	  //     }

	  //     setTimeout(resize_viz, wait_time, params);
	  //   });
	  // }

	  // if (params.viz.expand_button) {

	  d3.select(params.root + ' .expand_button').on('click', null);
	  var expand_opacity = 0.4;

	  if (d3.select(params.root + ' .expand_button').empty()) {
	    exp_button = d3.select(params.viz.viz_svg).append('text').attr('class', 'expand_button');
	  } else {
	    exp_button = d3.select(params.root + ' .expand_button');
	  }

	  exp_button.attr('text-anchor', 'middle').attr('dominant-baseline', 'central').attr('font-family', 'FontAwesome').attr('font-size', '30px').text(function () {
	    if (params.viz.is_expand === false) {
	      // expand button
	      return '\uf0b2';
	    } else {
	      // menu button
	      return '\uf0c9';
	    }
	  }).attr('y', '25px').attr('x', '25px').style('cursor', 'pointer').style('opacity', expand_opacity).on('mouseover', function () {
	    d3.select(this).style('opacity', 0.75);
	  }).on('mouseout', function () {
	    d3.select(this).style('opacity', expand_opacity);
	  }).on('click', function () {

	    // expand view
	    if (params.viz.is_expand === false) {

	      d3.select(this).text(function () {
	        // menu button
	        return '\uf0c9';
	      });
	      params.viz.is_expand = true;

	      d3.selectAll(params.root + ' .borders').style('fill', 'white');
	      // d3.select(params.root+' .footer_section').style('display', 'none');
	      d3.select(params.root + ' .sidebar_wrapper').style('display', 'none');

	      // contract view
	    } else {

	      d3.select(this).text(function () {
	        // expand button
	        return '\uf0b2';
	      });

	      params.viz.is_expand = false;

	      d3.selectAll(params.root + ' .borders').style('fill', '#eee');
	      // d3.select(params.root+' .footer_section').style('display', 'block');
	      d3.select(params.root + ' .viz_wrapper').style('width', '100px');
	      d3.select(params.root + ' .sidebar_wrapper').style('display', 'block');
	    }

	    // // resize parent div
	    // set_viz_wrapper_size(params);

	    d3.select(params.viz.viz_svg).style('opacity', 0.5);
	    var wait_time = 500;
	    if (params.viz.run_trans == true) {
	      wait_time = 2500;
	    }
	    setTimeout(resize_viz, wait_time, cgm);
	  });
	  // }
	};

/***/ },
/* 124 */
/***/ function(module, exports, __webpack_require__) {

	var utils = __webpack_require__(2);
	var run_zoom = __webpack_require__(125);
	var ini_doubleclick = __webpack_require__(133);
	var reset_zoom = __webpack_require__(134);
	var resize_dendro = __webpack_require__(135);
	var resize_super_labels = __webpack_require__(136);
	var resize_spillover = __webpack_require__(137);
	var resize_borders = __webpack_require__(138);
	var resize_row_labels = __webpack_require__(139);
	var resize_highlights = __webpack_require__(140);
	var resize_row_viz = __webpack_require__(141);
	var resize_col_labels = __webpack_require__(142);
	var resize_col_text = __webpack_require__(143);
	var resize_col_triangle = __webpack_require__(144);
	var resize_col_hlight = __webpack_require__(145);
	var recalc_params_for_resize = __webpack_require__(146);
	var resize_row_tiles = __webpack_require__(147);
	var resize_label_bars = __webpack_require__(148);
	var label_constrain_and_trim = __webpack_require__(117);
	var make_dendro_triangles = __webpack_require__(55);
	var toggle_dendro_view = __webpack_require__(54);
	var show_visible_area = __webpack_require__(106);
	var calc_viz_dimensions = __webpack_require__(18);
	var position_play_button = __webpack_require__(149);
	var make_row_cat_super_labels = __webpack_require__(122);
	var ini_cat_reorder = __webpack_require__(114);
	var position_svg_dendro_slider = __webpack_require__(150);
	var ini_zoom_info = __webpack_require__(36);
	var grid_lines_viz = __webpack_require__(151);

	module.exports = function resize_viz(cgm) {

	  var params = cgm.params;

	  var cont_dim = calc_viz_dimensions(params);

	  d3.select(params.root + ' .play_button');
	  // .style('opacity', 0.2);


	  d3.select(params.root + ' .sidebar_wrapper').style('height', cont_dim.height + 'px');

	  d3.select(params.viz.viz_wrapper)
	  // .style('float', 'left')
	  .style('margin-top', cont_dim.top + 'px').style('width', cont_dim.width + 'px').style('height', cont_dim.height + 'px');

	  params = recalc_params_for_resize(params);

	  params.zoom_info = ini_zoom_info();

	  reset_zoom(params);

	  var svg_group = d3.select(params.viz.viz_svg);

	  // redefine x and y positions
	  _.each(params.network_data.links, function (d) {
	    d.x = params.viz.x_scale(d.target);
	    d.y = params.viz.y_scale(d.source);
	  });

	  // disable zoom while transitioning
	  svg_group.on('.zoom', null);

	  params.zoom_behavior.scaleExtent([1, params.viz.square_zoom * params.viz.zoom_ratio.x]).on('zoom', function () {
	    run_zoom(cgm);
	  });

	  // reenable zoom after transition
	  if (params.viz.do_zoom) {
	    svg_group.call(params.zoom_behavior);
	  }

	  // prevent normal double click zoom etc
	  ini_doubleclick(cgm);

	  svg_group.attr('width', params.viz.svg_dim.width).attr('height', params.viz.svg_dim.height);

	  svg_group.select('.super_background').style('width', params.viz.svg_dim.width).style('height', params.viz.svg_dim.height);

	  svg_group.select('.grey_background').attr('width', params.viz.clust.dim.width).attr('height', params.viz.clust.dim.height);

	  setTimeout(position_play_button, 100, params);

	  var row_nodes = params.network_data.row_nodes;
	  var row_nodes_names = utils.pluck(row_nodes, 'name');

	  resize_row_tiles(params, svg_group);

	  svg_group.selectAll('.highlighting_rect').attr('width', params.viz.x_scale.rangeBand() * 0.80).attr('height', params.viz.y_scale.rangeBand() * 0.80);

	  resize_highlights(params);

	  // resize row labels
	  ///////////////////////////

	  resize_row_labels(params, svg_group);
	  resize_row_viz(params, svg_group);

	  // change the size of the highlighting rects
	  svg_group.selectAll('.row_label_group').each(function () {
	    var bbox = d3.select(this).select('text')[0][0].getBBox();
	    d3.select(this).select('rect').attr('x', bbox.x).attr('y', 0).attr('width', bbox.width).attr('height', params.viz.rect_height).style('fill', 'yellow').style('opacity', function (d) {
	      var inst_opacity = 0;
	      // highlight target genes
	      if (d.target === 1) {
	        inst_opacity = 1;
	      }
	      return inst_opacity;
	    });
	  });

	  // necessary to properly position row labels vertically
	  svg_group.selectAll('.row_label_group').select('text').attr('y', params.viz.rect_height * 0.5 + params.labels.default_fs_row * 0.35);

	  if (utils.has(params.network_data.row_nodes[0], 'value')) {
	    resize_label_bars(cgm, svg_group);
	  }

	  svg_group.selectAll('.row_cat_group').attr('transform', function (d) {
	    var inst_index = _.indexOf(row_nodes_names, d.name);
	    return 'translate(0, ' + params.viz.y_scale(inst_index) + ')';
	  });

	  svg_group.selectAll('.row_cat_group').select('path').attr('d', function () {
	    var origin_x = params.viz.cat_room.symbol_width - 1;
	    var origin_y = 0;
	    var mid_x = 1;
	    var mid_y = params.viz.rect_height / 2;
	    var final_x = params.viz.cat_room.symbol_width - 1;
	    var final_y = params.viz.rect_height;
	    var output_string = 'M ' + origin_x + ',' + origin_y + ' L ' + mid_x + ',' + mid_y + ', L ' + final_x + ',' + final_y + ' Z';
	    return output_string;
	  });

	  var is_resize = true;
	  if (params.viz.show_dendrogram) {
	    make_dendro_triangles(cgm, 'row', is_resize);
	    make_dendro_triangles(cgm, 'col', is_resize);
	    resize_dendro(params, svg_group);

	    toggle_dendro_view(cgm, 'row', 0);
	    toggle_dendro_view(cgm, 'col', 0);
	  } else {
	    resize_dendro(params, svg_group);
	  }

	  resize_col_labels(params, svg_group);
	  resize_col_text(params, svg_group);
	  resize_col_triangle(params, svg_group);
	  resize_col_hlight(params, svg_group);

	  resize_super_labels(params, svg_group);
	  resize_spillover(params.viz, svg_group);

	  grid_lines_viz(params);

	  resize_borders(params, svg_group);

	  // reset zoom and translate
	  params.zoom_behavior.scale(1).translate([params.viz.clust.margin.left, params.viz.clust.margin.top]);

	  label_constrain_and_trim(params);

	  // reposition matrix
	  d3.select(params.root + ' .clust_container').attr('transform', 'translate(' + params.viz.clust.margin.left + ',' + params.viz.clust.margin.top + ')');

	  // removed, this was causing bugs
	  if (cgm.params.viz.ds_level === -1) {
	    show_visible_area(cgm);
	  }

	  make_row_cat_super_labels(cgm);

	  d3.select(params.viz.viz_svg).style('opacity', 1);

	  ini_cat_reorder(cgm);

	  d3.select(cgm.params.root + ' .row_slider_group').style('opacity', 0);
	  d3.select(cgm.params.root + ' .col_slider_group').style('opacity', 0);

	  setTimeout(position_svg_dendro_slider, 500, cgm, 'row');
	  setTimeout(position_svg_dendro_slider, 500, cgm, 'col');
		};

/***/ },
/* 125 */
/***/ function(module, exports, __webpack_require__) {

	var run_transformation = __webpack_require__(126);
	var zoom_rules_y = __webpack_require__(131);
	var zoom_rules_x = __webpack_require__(132);

	module.exports = function zoomed(cgm) {

	  var params = cgm.params;

	  var zoom_info = {};
	  zoom_info.zoom_x = d3.event.scale;
	  zoom_info.zoom_y = d3.event.scale;

	  // subtract away the margin to easily calculate pan_room etc.
	  zoom_info.trans_x = params.zoom_behavior.translate()[0] - params.viz.clust.margin.left;
	  zoom_info.trans_y = params.zoom_behavior.translate()[1] - params.viz.clust.margin.top;

	  d3.selectAll(params.viz.root_tips).style('display', 'none');

	  // transfer zoom_info to params
	  params.zoom_info = zoom_rules_y(params, zoom_info);
	  params.zoom_info = zoom_rules_x(params, zoom_info);

	  // do not run transformation if moving slider
	  if (params.is_slider_drag === false && params.is_cropping === false) {

	    // reset translate vector - add back margins to trans_x and trans_y
	    var new_x = params.zoom_info.trans_x + params.viz.clust.margin.left;
	    var new_y = params.zoom_info.trans_y + params.viz.clust.margin.top;

	    params.zoom_behavior.translate([new_x, new_y]);
	    cgm.params = params;

	    run_transformation(cgm);
	  }
		};

/***/ },
/* 126 */
/***/ function(module, exports, __webpack_require__) {

	var constrain_font_size = __webpack_require__(119);
	var show_visible_area = __webpack_require__(106);
	var resize_label_val_bars = __webpack_require__(127);
	var zoom_crop_triangles = __webpack_require__(62);
	var get_previous_zoom = __webpack_require__(101);
	var run_when_zoom_stopped = __webpack_require__(128);
	var check_zoom_stop_status = __webpack_require__(130);

	module.exports = function run_transformation(cgm) {

	  var params = cgm.params;

	  var zoom_info = params.zoom_info;

	  var prev_zoom = get_previous_zoom(params);

	  d3.select(params.root + ' .clust_group').attr('transform', 'translate(' + [zoom_info.trans_x, zoom_info.trans_y] + ') scale(' + zoom_info.zoom_x + ',' + zoom_info.zoom_y + ')');

	  d3.select(params.root + ' .row_label_zoom_container').attr('transform', 'translate(' + [0, zoom_info.trans_y] + ') scale(' + zoom_info.zoom_y + ')');

	  d3.select(params.root + ' .col_zoom_container').attr('transform', 'translate(' + [zoom_info.trans_x, 0] + ') scale(' + zoom_info.zoom_x + ')');

	  d3.select(params.root + ' .row_cat_container').attr('transform', 'translate(' + [0, zoom_info.trans_y] + ') scale( 1,' + zoom_info.zoom_y + ')');

	  d3.select(params.root + ' .row_dendro_container').attr('transform', 'translate(' + [params.viz.uni_margin / 2, zoom_info.trans_y] + ') ' + 'scale( 1,' + zoom_info.zoom_y + ')');

	  d3.select(params.root + ' .row_dendro_icons_group').attr('transform', function () {
	    var inst_y = zoom_info.trans_y;
	    var inst_translate = 'translate(' + [0, inst_y] + ') ';
	    var inst_zoom = 'scale(1, ' + zoom_info.zoom_y + ')';
	    var transform_string = inst_translate + inst_zoom;
	    return transform_string;
	  });

	  d3.select(params.root + ' .col_dendro_icons_group').attr('transform', function () {
	    var inst_x = zoom_info.trans_x;
	    var inst_translate = 'translate(' + [inst_x, 0] + ')';
	    var inst_zoom = 'scale(' + zoom_info.zoom_x + ', 1)';
	    var transform_string = inst_translate + inst_zoom;
	    return transform_string;
	  });

	  zoom_crop_triangles(params, zoom_info, 'row');
	  zoom_crop_triangles(params, zoom_info, 'col');

	  d3.select(params.root + ' .col_cat_container').attr('transform', 'translate(' + [zoom_info.trans_x, 0] + ') scale(' + zoom_info.zoom_x + ',1)');

	  d3.select(params.root + ' .col_dendro_container').attr('transform', 'translate(' + [zoom_info.trans_x, params.viz.uni_margin / 2] + ') scale(' + zoom_info.zoom_x + ',1)');

	  resize_label_val_bars(params, zoom_info);

	  d3.select(params.root + ' .viz_svg').attr('is_zoom', function () {
	    var inst_zoom = Number(d3.select(params.root + ' .viz_svg').attr('is_zoom'));
	    d3.select(params.root + ' .viz_svg').attr('stopped_zoom', 1);
	    return inst_zoom + 1;
	  });

	  // this function runs with a slight delay and tells the visualization that
	  // this particular zoom event is over, reducing the total number of zoom
	  // events that need to finish
	  var not_zooming = function () {

	    d3.select(params.root + ' .viz_svg').attr('is_zoom', function () {
	      var inst_zoom = Number(d3.select(params.root + ' .viz_svg').attr('is_zoom'));
	      return inst_zoom - 1;
	    });
	  };

	  constrain_font_size(params);

	  if (zoom_info.zoom_y <= prev_zoom.zoom_y) {

	    var zooming_out = false;
	    if (zoom_info.zoom_y < prev_zoom.zoom_y) {
	      zooming_out = true;
	    }

	    // zooming has not stopped and zooming out is true
	    var zooming_stopped = false;
	    show_visible_area(cgm, zooming_stopped, zooming_out);
	  }

	  setTimeout(not_zooming, 50);
	  setTimeout(check_if_zooming_has_stopped, 100, cgm);

	  function check_if_zooming_has_stopped(cgm) {
	    var params = cgm.params;

	    var stop_attributes = check_zoom_stop_status(params);

	    if (stop_attributes === true) {
	      // wait and double check that zooming has stopped
	      setTimeout(run_when_zoom_stopped, 50, cgm);
	    }
	  }
		};

/***/ },
/* 127 */
/***/ function(module, exports, __webpack_require__) {

	var utils = __webpack_require__(2);

	module.exports = function resize_label_val_bars(params) {

	  var zoom_info = params.zoom_info;

	  // resize label bars if necessary
	  if (utils.has(params.network_data.row_nodes[0], 'value')) {
	    d3.selectAll(params.root + ' .row_bars').attr('width', function (d) {
	      var inst_value = 0;
	      inst_value = params.labels.bar_scale_row(Math.abs(d.value)) / zoom_info.zoom_y;
	      return inst_value;
	    }).attr('x', function (d) {
	      var inst_value = 0;
	      inst_value = -params.labels.bar_scale_row(Math.abs(d.value)) / zoom_info.zoom_y;
	      return inst_value;
	    });
	  }

	  if (utils.has(params.network_data.col_nodes[0], 'value')) {
	    d3.selectAll(params.root + ' .col_bars').attr('width', function (d) {
	      var inst_value = 0;
	      if (d.value > 0) {
	        inst_value = params.labels.bar_scale_col(d.value) / zoom_info.zoom_x;
	      }
	      return inst_value;
	    });
	  }
		};

/***/ },
/* 128 */
/***/ function(module, exports, __webpack_require__) {

	var constrain_font_size = __webpack_require__(119);
	var trim_text = __webpack_require__(118);
	var num_visible_labels = __webpack_require__(129);
	var toggle_grid_lines = __webpack_require__(121);
	var show_visible_area = __webpack_require__(106);
	var check_zoom_stop_status = __webpack_require__(130);

	module.exports = function run_when_zoom_stopped(cgm) {

	  var params = cgm.params;

	  var stop_attributes = check_zoom_stop_status(params);

	  if (stop_attributes === true) {

	    // ///////////////////////////////////////////////
	    // // zooming has stopped
	    // ///////////////////////////////////////////////
	    // console.log('\nZOOMING HAS ACTUALLY STOPPED\n============================');
	    // console.log(params.zoom_info.zoom_y)

	    _.each(['row', 'col'], function (inst_rc) {

	      d3.selectAll(params.root + ' .' + inst_rc + '_label_group').select('text').style('opacity', 1);

	      d3.selectAll(params.root + ' .' + inst_rc + '_cat_group').select('path').style('display', 'block');
	    });

	    show_visible_area(cgm, true);

	    d3.selectAll(params.viz.root_tips).style('display', 'block');

	    d3.selectAll(params.root + ' .row_label_group').select('text').style('display', 'none');
	    d3.selectAll(params.root + ' .row_label_group').select('text').style('display', 'block');

	    d3.select(params.root + ' .viz_svg').attr('stopped_zoom', 0);

	    d3.selectAll(params.root + ' .row_label_group').select('text').style('display', 'block');
	    d3.selectAll(params.root + ' .col_label_group').select('text').style('display', 'block');

	    toggle_grid_lines(params);

	    // reset x_offset
	    cgm.params.viz.x_offset = 0;

	    var max_labels_to_trim = 150;
	    // probably do not need
	    /////////////////////////
	    _.each(['row', 'col'], function (inst_rc) {

	      var inst_num_visible = num_visible_labels(params, inst_rc);

	      if (inst_num_visible < max_labels_to_trim) {
	        d3.selectAll(params.root + ' .' + inst_rc + '_label_group').each(function () {
	          trim_text(params, this, inst_rc);
	        });
	      }
	    });

	    text_patch();

	    constrain_font_size(params);

	    // this makes sure that the text is visible after zooming and trimming
	    // there is buggy behavior in chrome when zooming into large matrices
	    // I'm running it twice in quick succession
	    setTimeout(text_patch, 100);
	  }

	  function text_patch() {

	    _.each(['row', 'col'], function (inst_rc) {

	      d3.selectAll(params.root + ' .' + inst_rc + '_label_group').filter(function () {
	        return d3.select(this).style('display') != 'none';
	      }).select('text').style('font-size', function () {
	        var inst_fs = Number(d3.select(this).style('font-size').replace('px', ''));
	        return inst_fs;
	      });
	    });
	  }
		};

/***/ },
/* 129 */
/***/ function(module, exports) {

	module.exports = function num_visible_labels(params, inst_rc) {

	  // counting the number of visible labels, probably not necessary

	  var num_visible;
	  if (inst_rc === 'row') {

	    // initialize at high number
	    num_visible = 10000;

	    // only count visible rows if no downsampling
	    if (params.viz.ds_level === -1) {
	      num_visible = d3.selectAll(params.root + ' .row')[0].length;
	    }
	  } else if (inst_rc === 'col') {

	    num_visible = d3.selectAll(params.root + ' .' + inst_rc + '_label_text').filter(function () {
	      return d3.select(this).style('display') != 'none';
	    })[0].length;
	  }

	  return num_visible;
	};

/***/ },
/* 130 */
/***/ function(module, exports) {

	module.exports = function check_zoom_stop_status(params) {

	  var inst_zoom = Number(d3.select(params.root + ' .viz_svg').attr('is_zoom'));

	  var check_stop = Number(d3.select(params.root + ' .viz_svg').attr('stopped_zoom'));

	  var stop_attributes = false;
	  if (inst_zoom === 0 && check_stop != 0) {
	    stop_attributes = true;
	  }

	  return stop_attributes;
	};

/***/ },
/* 131 */
/***/ function(module, exports) {

	module.exports = function zoom_rules_y(params, zoom_info) {

	  var viz = params.viz;
	  // zoom in the x direction before zooming in the y direction
	  if (viz.zoom_ratio.y > 1) {
	    if (zoom_info.zoom_y < viz.zoom_ratio.y) {
	      zoom_info.trans_y = 0;
	      zoom_info.zoom_y = 1;
	    } else {
	      zoom_info.zoom_y = zoom_info.zoom_y / viz.zoom_ratio.y;
	    }
	  }

	  // calculate panning room available in the y direction
	  zoom_info.pan_room_y = (zoom_info.zoom_y - 1) * viz.clust.dim.height;

	  // console.log( 'pan_room_y: ' +  String(zoom_info.pan_room_y) + ' ' + String(-zoom_info.trans_y))

	  // no positive panning or panning more than pan_room
	  if (zoom_info.trans_y >= 0) {
	    zoom_info.trans_y = 0;
	    // console.log('y no positive panning\n\n')
	  } else if (zoom_info.trans_y <= -zoom_info.pan_room_y) {
	    zoom_info.trans_y = -zoom_info.pan_room_y;
	    // console.log('y restrict pan room \n\n')
	  }

	  return zoom_info;
	};

/***/ },
/* 132 */
/***/ function(module, exports) {

	module.exports = function zoom_rules_x(params, zoom_info) {

	  var viz = params.viz;

	  // zoom in the y direction before zooming in the x direction
	  if (viz.zoom_ratio.x > 1) {

	    if (zoom_info.zoom_x < viz.zoom_ratio.x) {

	      // remove this
	      // zoom_info.trans_x = - params.viz.clust.margin.left;

	      zoom_info.zoom_x = 1;
	    } else {
	      zoom_info.zoom_x = zoom_info.zoom_x / viz.zoom_ratio.x;

	      // console.log('********* zoom_x: ' + String(zoom_info.zoom_x))

	      // zoom_info.trans_x = zoom_info.trans_x + params.viz.x_offset;
	      // zoom_info.trans_x = zoom_info.trans_x * (params.zoom_info.zoom_x/params.zoom_info.zoom_y);
	    }
	  }

	  // calculate panning room available in the x direction
	  zoom_info.pan_room_x = (zoom_info.zoom_x - 1) * viz.clust.dim.width;

	  // console.log( 'pan_room_x: ' +  String(zoom_info.pan_room_x) + ' trans_x: ' + String(-zoom_info.trans_x))

	  // no positive panning or panning more than pan_room
	  if (zoom_info.trans_x > 0) {
	    zoom_info.trans_x = 0;
	    // console.log('no positive panning\n\n')
	  } else if (zoom_info.trans_x <= -zoom_info.pan_room_x) {
	    zoom_info.trans_x = -zoom_info.pan_room_x;
	    // console.log('******* restrict pan room\n\n')
	  }

	  return zoom_info;
	};

/***/ },
/* 133 */
/***/ function(module, exports, __webpack_require__) {

	var two_translate_zoom = __webpack_require__(116);

	module.exports = function ini_doubleclick(cgm) {

	  var params = cgm.params;
	  // disable double-click zoom
	  d3.selectAll(params.viz.zoom_element).on('dblclick.zoom', null);

	  d3.select(params.viz.zoom_element).on('dblclick', function () {
	    two_translate_zoom(cgm, 0, 0, 1);
	  });
	};

/***/ },
/* 134 */
/***/ function(module, exports) {

	module.exports = function (params) {

	  // reset zoom
	  //////////////////////////////
	  var zoom_y = 1;
	  // var zoom_x = 1;
	  var pan_dx = 0;
	  var pan_dy = 0;

	  var half_height = params.viz.clust.dim.height / 2;
	  var center_y = -(zoom_y - 1) * half_height;

	  d3.select(params.root + ' .clust_group').attr('transform', 'translate(' + [0, 0 + center_y] + ')' + ' scale(' + 1 + ',' + zoom_y + ')' + 'translate(' + [pan_dx, pan_dy] + ')');

	  d3.select(params.root + ' .row_label_zoom_container').attr('transform', 'translate(' + [0, center_y] + ')' + ' scale(' + zoom_y + ',' + zoom_y + ')' + 'translate(' + [0, pan_dy] + ')');

	  d3.select(params.root + ' .row_cat_container').attr('transform', 'translate(' + [0, center_y] + ')' + ' scale(' + 1 + ',' + zoom_y + ')' + 'translate(' + [0, pan_dy] + ')');

	  d3.select(params.root + ' .row_dendro_container').attr('transform', 'translate(' + [0, center_y] + ')' + ' scale(' + zoom_y + ',' + zoom_y + ')' + 'translate(' + [params.viz.uni_margin / 2, pan_dy] + ')');

	  d3.select(params.root + ' .col_zoom_container').attr('transform', ' scale(' + 1 + ',' + 1 + ')' + 'translate(' + [pan_dx, 0] + ')');

	  d3.select(params.root + ' .col_cat_container').attr('transform', ' scale(' + 1 + ',' + 1 + ')' + 'translate(' + [pan_dx, 0] + ')');

	  d3.select(params.root + ' .col_dendro_container').attr('transform', ' scale(' + 1 + ',' + 1 + ')' + 'translate(' + [pan_dx, params.viz.uni_margin / 2] + ')');

	  // reset crop button zooming
	  d3.select(params.root + ' .row_dendro_icons_group').attr('transform', function () {
	    return 'translate(0,0) scale(1)';
	  });

	  d3.select(params.root + ' .row_dendro_icons_group').selectAll('path').attr('transform', function (d) {
	    var inst_x = 7;
	    var inst_y = d.pos_mid;
	    return 'translate(' + inst_x + ',' + inst_y + ') ' + 'scale(1, 1)';
	  });
		};

/***/ },
/* 135 */
/***/ function(module, exports) {

	module.exports = function resize_dendro(params, svg_group, delay_info = false) {

	  // resize dendrogram
	  ///////////////////

	  var delays = {};

	  if (delay_info === false) {
	    delays.run_transition = false;
	  } else {
	    delays = delay_info;
	  }

	  var duration = params.viz.duration;
	  var col_nodes = params.network_data.col_nodes;
	  var col_nodes_names = params.network_data.col_nodes_names;

	  var dendro_group;
	  if (delays.run_transition) {

	    dendro_group = svg_group.transition().delay(delays.update).duration(duration);

	    svg_group.selectAll('.col_cat_group')
	    // data binding needed for loss/gain of columns
	    .data(col_nodes, function (d) {
	      return d.name;
	    }).transition().delay(delays.update).duration(duration).attr('transform', function (d) {
	      var inst_index = _.indexOf(col_nodes_names, d.name);
	      return 'translate(' + params.viz.x_scale(inst_index) + ',0)';
	    });

	    svg_group.selectAll('.col_dendro_group')
	    // data binding needed for loss/gain of columns
	    .data(col_nodes, function (d) {
	      return d.name;
	    }).transition().delay(delays.update).duration(duration).attr('transform', function (d) {
	      var inst_index = _.indexOf(col_nodes_names, d.name);
	      return 'translate(' + params.viz.x_scale(inst_index) + ',0)';
	    });
	  } else {

	    dendro_group = svg_group;

	    svg_group.selectAll('.col_cat_group')
	    // data binding needed for loss/gain of columns
	    .data(col_nodes, function (d) {
	      return d.name;
	    }).attr('transform', function (d) {
	      var inst_index = _.indexOf(col_nodes_names, d.name);
	      return 'translate(' + params.viz.x_scale(inst_index) + ',0)';
	    });

	    d3.select(params.root).selectAll('.col_dendro_group')
	    // data binding needed for loss/gain of columns
	    .data(col_nodes, function (d) {
	      return d.name;
	    }).attr('transform', function (d) {
	      var inst_index = _.indexOf(col_nodes_names, d.name);
	      return 'translate(' + params.viz.x_scale(inst_index) + ',0)';
	    });
	  }

	  var i;
	  var inst_class;

	  _.each(['row', 'col'], function (inst_rc) {

	    var num_cats = params.viz.all_cats[inst_rc].length;

	    for (i = 0; i < num_cats; i++) {
	      inst_class = '.' + inst_rc + '_cat_rect_' + String(i);

	      if (inst_rc === 'row') {
	        dendro_group.selectAll(inst_class).attr('height', params.viz.y_scale.rangeBand());
	      } else {
	        dendro_group.selectAll(inst_class).attr('width', params.viz.x_scale.rangeBand());
	      }
	    }
	  });

	  // position row_dendro_outer_container
	  var x_offset = params.viz.clust.margin.left + params.viz.clust.dim.width;
	  var y_offset = params.viz.clust.margin.top;
	  var spillover_width = params.viz.dendro_room.row + params.viz.uni_margin;

	  d3.select(params.root + ' .viz_svg').select('row_dendro_outer_container').attr('transform', 'translate(' + x_offset + ',' + y_offset + ')');

	  d3.select(params.root + ' .row_dendro_outer_container').select('.row_dendro_spillover').attr('width', spillover_width + 'px').attr('height', params.viz.svg_dim.height);

	  x_offset = params.viz.clust.margin.left;
	  y_offset = params.viz.clust.margin.top + params.viz.clust.dim.height;
	  var spillover_height = params.viz.dendro_room.col + params.viz.uni_margin;

	  d3.select(params.root + ' .col_dendro_outer_container').select('.col_dendro_spillover').attr('width', params.viz.svg_dim.width).attr('height', spillover_height + 'px');

	  d3.select(params.root + ' .col_dendro_outer_container').select('.col_dendro_spillover_top').attr('width', params.viz.svg_dim.width).attr('height', params.viz.svg_dim.height).attr('transform', 'translate(0,' + params.viz.dendro_room.col + ')');

	  x_offset = params.viz.clust.margin.left;
	  y_offset = 0;
	  d3.select(params.root + ' .col_dendro_icons_container').attr('transform', 'translate(' + x_offset + ',' + y_offset + ')');
		};

/***/ },
/* 136 */
/***/ function(module, exports) {

	module.exports = function resize_super_labels(params, ini_svg_group, delay_info = false) {

	  var delays = {};
	  var duration = params.viz.duration;
	  var svg_group;

	  if (delay_info === false) {
	    delays.run_transition = false;
	  } else {
	    delays = delay_info;
	  }

	  if (delays.run_transition) {
	    svg_group = ini_svg_group.transition().delay(delays.update).duration(duration);
	  } else {
	    svg_group = ini_svg_group;
	  }

	  svg_group.select('.super_col_bkg').attr('height', params.viz.super_labels.dim.width + 'px').attr('transform', 'translate(' + params.viz.clust.margin.left + ',' + params.viz.grey_border_width + ')');

	  // super col title
	  svg_group.select('.super_col').attr('transform', function () {
	    var inst_x = params.viz.clust.dim.width / 2 + params.viz.norm_labels.width.row;
	    var inst_y = params.viz.super_labels.dim.width;
	    return 'translate(' + inst_x + ',' + inst_y + ')';
	  });

	  svg_group.select('.super_row_bkg').attr('width', params.viz.super_labels.dim.width + 'px').attr('transform', 'translate(' + params.viz.grey_border_width + ',0)');

	  svg_group.select('.super_row').attr('transform', function () {
	    var inst_x = params.viz.super_labels.dim.width;
	    var inst_y = params.viz.clust.dim.height / 2 + params.viz.norm_labels.width.col;
	    return 'translate(' + inst_x + ',' + inst_y + ')';
	  });
		};

/***/ },
/* 137 */
/***/ function(module, exports) {

	module.exports = function resize_spillover(viz, ini_svg_group, delay_info = false) {

	  var delays = {};
	  var duration = viz.duration;
	  var svg_group;

	  if (delay_info === false) {
	    delays.run_transition = false;
	  } else {
	    delays = delay_info;
	  }

	  if (delays.run_transition) {
	    svg_group = ini_svg_group.transition().delay(delays.update).duration(duration);
	  } else {
	    svg_group = ini_svg_group;
	  }

	  svg_group.select(viz.root + ' .right_slant_triangle').attr('transform', 'translate(' + viz.clust.dim.width + ',' + viz.norm_labels.width.col + ')');

	  svg_group.select(viz.root + ' .left_slant_triangle').attr('transform', 'translate(-1,' + viz.norm_labels.width.col + ')');

	  var rect_height = viz.clust.margin.top + viz.uni_margin / 5;
	  svg_group.select(viz.root + ' .top_left_white').attr('width', viz.clust.margin.left).attr('height', rect_height);

	  var tmp_left = viz.clust.margin.left + viz.clust.dim.width + viz.uni_margin + viz.dendro_room.row;
	  var tmp_top = viz.norm_labels.margin.top + viz.norm_labels.width.col;

	  svg_group.select(viz.root + ' .right_spillover_container').attr('transform', function () {
	    return 'translate(' + tmp_left + ', 0)';
	  });

	  tmp_top = viz.norm_labels.margin.top + viz.norm_labels.width.col;

	  svg_group.select(viz.root + ' .right_spillover_container rect').attr('transform', function () {
	    return 'translate( 0,' + tmp_top + ')';
	  });

	  svg_group.select(viz.root + ' .right_spillover').attr('height', viz.svg_dim.height + 'px');

	  // resize dendro spillovers
	  var x_offset = viz.clust.margin.left + viz.clust.dim.width;
	  var y_offset = tmp_top;
	  var tmp_width = viz.dendro_room.row + viz.uni_margin;
	  var tmp_height = viz.cat_room.col + viz.uni_margin;
	  d3.select(viz.root + ' .dendro_row_spillover').attr('width', tmp_width).attr('height', tmp_height).attr('transform', function () {
	    return 'translate(' + x_offset + ',' + y_offset + ')';
	  });

	  // hide spillover left top of col dendrogram
	  x_offset = 0;
	  y_offset = viz.clust.margin.top + viz.clust.dim.height;
	  tmp_width = viz.clust.margin.left;
	  tmp_height = viz.clust.dim.height * 10;

	  svg_group.select('.dendro_col_spillover').attr('width', tmp_width).attr('height', tmp_height).attr('transform', function () {
	    return 'translate(' + x_offset + ',' + y_offset + ')';
	  });

	  x_offset = viz.clust.margin.left + viz.clust.dim.width;
	  y_offset = viz.clust.margin.top + viz.clust.dim.height;
	  tmp_width = viz.cat_room.col + viz.clust.dim.width;
	  tmp_height = viz.cat_room.row + viz.uni_margin;

	  svg_group.select('.dendro_corner_spillover').attr('width', tmp_width).attr('height', tmp_height).attr('transform', function () {
	    return 'translate(' + x_offset + ',' + y_offset + ')';
	  });

	  x_offset = viz.clust.margin.left + viz.clust.dim.width + viz.uni_margin;
	  y_offset = viz.norm_labels.margin.top + viz.norm_labels.width.col + 2.5 * viz.uni_margin;
	  var extra_x_room = 2.75;
	  var extra_y_room = 1.2;

	  // reposition category superlabels
	  if (viz.show_categories.col) {

	    d3.selectAll(viz.root + ' .col_cat_super').attr('transform', function (d) {
	      var inst_cat = parseInt(d.split('-')[1], 10);
	      var inst_y = y_offset + extra_y_room * viz.cat_room.symbol_width * inst_cat;
	      return 'translate(' + x_offset + ',' + inst_y + ')';
	    });
	  }

	  if (viz.show_categories.row) {
	    d3.select(viz.root + ' .row_cat_label_container').attr('transform', function () {
	      x_offset = viz.norm_labels.margin.left + viz.norm_labels.width.row + viz.cat_room.symbol_width + extra_x_room * viz.uni_margin;
	      y_offset = viz.clust.margin.top - viz.uni_margin;
	      return 'translate(' + x_offset + ',' + y_offset + ') rotate(-90)';
	    });
	  }

	  // white border bottom - prevent clustergram from hitting border
	  if (viz.show_dendrogram) {
	    y_offset = viz.clust.margin.top + viz.clust.dim.height + viz.dendro_room.col - 2 * viz.uni_margin;
	  } else {
	    y_offset = viz.clust.margin.top + viz.clust.dim.height;
	  }

	  d3.select(viz.root + ' .bottom_spillover_container').attr('transform', function () {
	    // shift up enough to show the entire border width
	    return 'translate(0,' + y_offset + ')';
	  });

	  svg_group.select(viz.root + ' .bottom_spillover').attr('width', viz.svg_dim.width).attr('height', 2 * viz.svg_dim.height);

	  var inst_height = viz.cat_room.col + 1.5 * viz.uni_margin;
	  // white rect to cover excess labels
	  d3.select(viz.viz_svg + ' .top_right_white').attr('fill', viz.background_color).attr('width', 2 * viz.clust.dim.width).attr('height', inst_height).attr('transform', function () {
	    var tmp_left = viz.clust.margin.left + viz.clust.dim.width;
	    var tmp_top = viz.norm_labels.width.col + viz.norm_labels.margin.top - viz.uni_margin;
	    return 'translate(' + tmp_left + ', ' + tmp_top + ')';
	  });
		};

/***/ },
/* 138 */
/***/ function(module, exports) {

	module.exports = function resize_borders(params, svg_group) {

	  // left border
	  svg_group.select('.left_border').attr('width', params.viz.grey_border_width).attr('height', params.viz.svg_dim.height).attr('transform', 'translate(0,0)');

	  // right border
	  svg_group.select('.right_border').attr('width', params.viz.grey_border_width).attr('height', params.viz.svg_dim.height).attr('transform', function () {
	    var inst_offset = params.viz.svg_dim.width - params.viz.grey_border_width;
	    return 'translate(' + inst_offset + ',0)';
	  });

	  // top border
	  svg_group.select('.top_border').attr('width', params.viz.svg_dim.width).attr('height', params.viz.grey_border_width).attr('transform', function () {
	    var inst_offset = 0;
	    return 'translate(' + inst_offset + ',0)';
	  });

	  // bottom border
	  svg_group.select('.bottom_border').attr('width', params.viz.svg_dim.width).attr('height', params.viz.grey_border_width).attr('transform', function () {
	    var inst_offset = params.viz.svg_dim.height - params.viz.grey_border_width;
	    return 'translate(0,' + inst_offset + ')';
	  });
		};

/***/ },
/* 139 */
/***/ function(module, exports) {

	module.exports = function resize_row_labels(params, ini_svg_group, delay_info = false) {

	  var delays = {};
	  var duration = params.viz.duration;
	  var svg_group;

	  var row_nodes = params.network_data.row_nodes;
	  var row_nodes_names = params.network_data.row_nodes_names;

	  if (delay_info === false) {
	    delays.run_transition = false;
	  } else {
	    delays = delay_info;
	  }

	  if (delays.run_transition) {

	    ini_svg_group.selectAll('.row_label_group')
	    // data bind necessary for loss/gain of rows
	    .data(row_nodes, function (d) {
	      return d.name;
	    }).transition().delay(delays.update).duration(duration).attr('transform', function (d) {
	      var inst_index = _.indexOf(row_nodes_names, d.name);
	      return 'translate(0,' + params.viz.y_scale(inst_index) + ')';
	    }).attr('y', params.viz.rect_height * 0.5 + params.labels.default_fs_row * 0.35);

	    svg_group = ini_svg_group.transition().delay(delays.update).duration(duration);
	  } else {

	    ini_svg_group.selectAll('.row_label_group')
	    // data bind necessary for loss/gain of rows
	    .data(row_nodes, function (d) {
	      return d.name;
	    }).attr('transform', function (d) {
	      var inst_index = _.indexOf(row_nodes_names, d.name);
	      return 'translate(0,' + params.viz.y_scale(inst_index) + ')';
	    }).attr('y', params.viz.rect_height * 0.5 + params.labels.default_fs_row * 0.35);

	    svg_group = ini_svg_group;
	  }

	  svg_group.select(params.root + ' .row_container').attr('transform', 'translate(' + params.viz.norm_labels.margin.left + ',' + params.viz.clust.margin.top + ')');

	  svg_group.select(params.root + ' .row_container').select('.white_bars').attr('width', params.viz.label_background.row).attr('height', 30 * params.viz.clust.dim.height + 'px');

	  svg_group.select(params.root + ' .row_container').select('.row_label_container').attr('transform', 'translate(' + params.viz.norm_labels.width.row + ',0)');
		};

/***/ },
/* 140 */
/***/ function(module, exports) {

	module.exports = function resize_highlights(params) {

	  // reposition tile highlight
	  ////////////////////////////////

	  var rel_width_hlight = 6;
	  // var opacity_hlight = 0.85;
	  var hlight_width = rel_width_hlight * params.viz.border_width.x;
	  var hlight_height = rel_width_hlight * params.viz.border_width.y;

	  // top highlight
	  d3.select(params.root + ' .top_hlight').attr('width', params.viz.rect_width).attr('height', hlight_height).attr('transform', function () {
	    return 'translate(' + params.viz.x_scale(params.matrix.click_hlight_x) + ',0)';
	  });

	  // left highlight
	  d3.select(params.root + ' .left_hlight').attr('width', hlight_width).attr('height', params.viz.rect_width - hlight_height * 0.99).attr('transform', function () {
	    return 'translate(' + params.viz.x_scale(params.matrix.click_hlight_x) + ',' + hlight_height * 0.99 + ')';
	  });

	  // right highlight
	  d3.select(params.root + ' .right_hlight').attr('width', hlight_width).attr('height', params.viz.rect_height - hlight_height * 0.99).attr('transform', function () {
	    var tmp_translate = params.viz.x_scale(params.matrix.click_hlight_x) + params.viz.rect_width - hlight_width;
	    return 'translate(' + tmp_translate + ',' + hlight_height * 0.99 + ')';
	  });

	  // bottom highlight
	  d3.select(params.root + ' .bottom_hlight').attr('width', function () {
	    return params.viz.rect_width - 1.98 * hlight_width;
	  }).attr('height', hlight_height).attr('transform', function () {
	    var tmp_translate_x = params.viz.x_scale(params.matrix.click_hlight_x) + hlight_width * 0.99;
	    var tmp_translate_y = params.viz.rect_height - hlight_height;
	    return 'translate(' + tmp_translate_x + ',' + tmp_translate_y + ')';
	  });

	  // resize row highlight
	  /////////////////////////
	  d3.select(params.root + ' .row_top_hlight').attr('width', params.viz.svg_dim.width).attr('height', hlight_height);

	  d3.select(params.root + ' .row_bottom_hlight').attr('width', params.viz.svg_dim.width).attr('height', hlight_height).attr('transform', function () {
	    var tmp_translate_y = params.viz.rect_height - hlight_height;
	    return 'translate(0,' + tmp_translate_y + ')';
	  });

	  // resize col highlight
	  /////////////////////////
	  d3.select(params.root + ' .col_top_hlight').attr('width', params.viz.clust.dim.height).attr('height', hlight_width).attr('transform', function () {
	    var tmp_translate_y = 0;
	    var tmp_translate_x = -(params.viz.clust.dim.height + params.viz.cat_room.col + params.viz.uni_margin);
	    return 'translate(' + tmp_translate_x + ',' + tmp_translate_y + ')';
	  });

	  d3.select(params.root + ' .col_bottom_hlight').attr('width', params.viz.clust.dim.height).attr('height', hlight_width).attr('transform', function () {
	    var tmp_translate_y = params.viz.rect_width - hlight_width;
	    var tmp_translate_x = -(params.viz.clust.dim.height + params.viz.cat_room.col + params.viz.uni_margin);
	    return 'translate(' + tmp_translate_x + ',' + tmp_translate_y + ')';
	  });
		};

/***/ },
/* 141 */
/***/ function(module, exports) {

	module.exports = function resize_row_viz(params, ini_svg_group, delay_info = false) {

	  var delays = {};
	  var duration = params.viz.duration;
	  var svg_group;

	  if (delay_info === false) {
	    delays.run_transition = false;
	  } else {
	    delays = delay_info;
	  }

	  if (delays.run_transition) {
	    svg_group = ini_svg_group.transition().delay(delays.update).duration(duration);
	  } else {
	    svg_group = ini_svg_group;
	  }

	  svg_group.select('.row_cat_outer_container').attr('transform', 'translate(' + params.viz.norm_labels.width.row + ',0)').select('white_bars').attr('width', params.viz.cat_room.row + 'px').attr('height', function () {
	    var inst_height = params.viz.clust.dim.height;
	    return inst_height;
	  });

	  var x_offset = params.viz.clust.margin.left + params.viz.clust.dim.width;
	  var y_offset = params.viz.clust.margin.top;
	  svg_group.select('.row_dendro_outer_container').attr('transform', 'translate(' + x_offset + ',' + y_offset + ')');

	  // !! tmp resize col dendro
	  x_offset = params.viz.clust.margin.left;
	  y_offset = params.viz.clust.margin.top + params.viz.clust.dim.height;

	  svg_group.select(' .col_dendro_outer_container').attr('transform', function () {
	    return 'translate(' + x_offset + ',' + y_offset + ')';
	  });
		};

/***/ },
/* 142 */
/***/ function(module, exports) {

	module.exports = function (params, ini_svg_group, delay_info = false) {

	  var delays = {};
	  var duration = params.viz.duration;
	  var svg_group;

	  var col_nodes = params.network_data.col_nodes;
	  var col_nodes_names = params.network_data.col_nodes_names;

	  if (delay_info === false) {
	    delays.run_transition = false;
	  } else {
	    delays = delay_info;
	  }

	  if (delays.run_transition) {
	    svg_group = ini_svg_group.transition().delay(delays.update).duration(duration);

	    ini_svg_group.selectAll('.col_label_text').data(col_nodes, function (d) {
	      return d.name;
	    }).transition().delay(delays.update).duration(duration).attr('transform', function (d) {
	      var inst_index = _.indexOf(col_nodes_names, d.name);
	      return 'translate(' + params.viz.x_scale(inst_index) + ', 0) rotate(-90)';
	    });
	  } else {
	    svg_group = ini_svg_group;

	    ini_svg_group.selectAll('.col_label_text').data(col_nodes, function (d) {
	      return d.name;
	    }).attr('transform', function (d) {
	      var inst_index = _.indexOf(col_nodes_names, d.name);
	      return 'translate(' + params.viz.x_scale(inst_index) + ', 0) rotate(-90)';
	    });
	  }

	  // offset click group column label
	  var x_offset_click = params.viz.x_scale.rangeBand() / 2 + params.viz.border_width.x;

	  svg_group.select(params.root + ' .col_container').attr('transform', 'translate(' + params.viz.clust.margin.left + ',' + params.viz.norm_labels.margin.top + ')');

	  svg_group.select(params.root + ' .col_container').select('.white_bars').attr('width', 30 * params.viz.clust.dim.width + 'px').attr('height', params.viz.label_background.col);

	  svg_group.select(params.root + ' .col_container').select('.col_label_outer_container').attr('transform', 'translate(0,' + params.viz.norm_labels.width.col + ')');

	  svg_group.selectAll('.col_label_group').attr('transform', 'translate(' + params.viz.x_scale.rangeBand() / 2 + ',' + x_offset_click + ') rotate(45)');

	  svg_group.selectAll('.col_label_group').select('text').attr('y', params.viz.x_scale.rangeBand() * 0.60).attr('dx', 2 * params.viz.border_width.x);
		};

/***/ },
/* 143 */
/***/ function(module, exports, __webpack_require__) {

	var utils = __webpack_require__(2);

	module.exports = function resize_col_text(params, svg_group) {
	  svg_group.selectAll('.col_label_group').select('text').style('font-size', params.labels.default_fs_col + 'px').text(function (d) {
	    return utils.normal_name(d);
	  });

	  svg_group.selectAll('.col_label_group').each(function () {
	    d3.select(this).select('text')[0][0].getBBox();
	  });
	};

/***/ },
/* 144 */
/***/ function(module, exports, __webpack_require__) {

	var col_viz_aid_triangle = __webpack_require__(110);

	module.exports = function resize_col_triangle(params, ini_svg_group, delay_info = false) {

	  // resize column triangle
	  var ini_triangle_group = ini_svg_group.selectAll('.col_label_group').select('path');

	  var delays = {};
	  var duration = params.viz.duration;

	  if (delay_info === false) {
	    delays.run_transition = false;
	  } else {
	    delays = delay_info;
	  }

	  var triangle_group;
	  if (delays.run_transition) {
	    triangle_group = ini_triangle_group.transition().delay(delays.update).duration(duration);
	  } else {
	    triangle_group = ini_triangle_group;
	  }

	  triangle_group.attr('d', function () {
	    return col_viz_aid_triangle(params);
	  }).attr('fill', '#eee');
		};

/***/ },
/* 145 */
/***/ function(module, exports, __webpack_require__) {

	var utils = __webpack_require__(2);

	module.exports = function resize_col_hlight(params, svg_group, delay_info = false) {

	  var delays = {};
	  // var duration = params.viz.duration;

	  if (delay_info === false) {
	    delays.run_transition = false;
	  } else {
	    delays = delay_info;
	  }

	  if (utils.has(params.network_data.col_nodes[0], 'value')) {

	    svg_group.selectAll('.col_bars').data(params.network_data.col_nodes, function (d) {
	      return d.name;
	    }).attr('width', function (d) {

	      var inst_value = 0;

	      if (d.value > 0) {
	        inst_value = params.labels.bar_scale_col(d.value);
	      }
	      return inst_value;
	    })
	    // rotate labels - reduce width if rotating
	    .attr('height', params.viz.rect_width * 0.66);
	  }
		};

/***/ },
/* 146 */
/***/ function(module, exports, __webpack_require__) {

	var get_svg_dim = __webpack_require__(19);
	var calc_clust_height = __webpack_require__(22);
	var calc_clust_width = __webpack_require__(21);
	var calc_default_fs = __webpack_require__(31);
	var calc_zoom_switching = __webpack_require__(30);

	module.exports = function recalc_params_for_resize(params) {

	  // Resetting some visualization parameters
	  params = get_svg_dim(params);
	  params.viz = calc_clust_width(params.viz);
	  params.viz = calc_clust_height(params.viz);

	  if (params.sim_mat) {
	    if (params.viz.clust.dim.width <= params.viz.clust.dim.height) {
	      params.viz.clust.dim.height = params.viz.clust.dim.width;
	    } else {
	      params.viz.clust.dim.width = params.viz.clust.dim.height;
	    }
	  }

	  params.viz = calc_zoom_switching(params.viz);

	  // redefine x_scale and y_scale rangeBands
	  params.viz.x_scale.rangeBands([0, params.viz.clust.dim.width]);
	  params.viz.y_scale.rangeBands([0, params.viz.clust.dim.height]);

	  // redefine border width
	  params.viz.border_width.x = params.viz.x_scale.rangeBand() / params.viz.border_fraction;
	  params.viz.border_width.y = params.viz.y_scale.rangeBand() / params.viz.border_fraction;

	  params.viz.rect_width = params.viz.x_scale.rangeBand() - params.viz.border_width.x;
	  params.viz.rect_height = params.viz.y_scale.rangeBand() - params.viz.border_width.y;

	  // for downsampling
	  if (params.viz.ds != null) {
	    for (var i; i < params.viz.ds.length; i++) {
	      params.viz.ds[i].rect_height = params.viz.ds[i].y_scale.rangeBand() - params.viz.border_width.y;
	    }
	  }

	  // recalc downsampled y_scale if necessary
	  if (params.viz.ds_num_levels > 0) {
	    _.each(params.viz.ds, function (inst_ds) {

	      // y_scale
	      /////////////////////////
	      inst_ds.y_scale = d3.scale.ordinal().rangeBands([0, params.viz.clust.dim.height]);
	      inst_ds.y_scale.domain(d3.range(inst_ds.num_rows + 1));

	      inst_ds.rect_height = inst_ds.y_scale.rangeBand() - params.viz.border_width.y;
	    });
	  }

	  // redefine zoom extent
	  params.viz.square_zoom = params.viz.norm_labels.width.col / (params.viz.rect_width / 2);

	  // the default font sizes are set here
	  params = calc_default_fs(params);

	  return params;
	};

/***/ },
/* 147 */
/***/ function(module, exports, __webpack_require__) {

	var draw_up_tile = __webpack_require__(43);
	var draw_dn_tile = __webpack_require__(44);
	var fine_position_tile = __webpack_require__(47);

	module.exports = function resize_row_tiles(params, svg_group) {

	  var row_nodes_names = params.network_data.row_nodes_names;

	  if (params.viz.ds_level === -1) {

	    // no downsampling
	    ///////////////////////

	    // resize rows
	    svg_group.selectAll('.row').attr('transform', function (d) {
	      var tmp_index = _.indexOf(row_nodes_names, d.name);
	      var inst_y = params.viz.y_scale(tmp_index);
	      return 'translate(0,' + inst_y + ')';
	    });

	    // resize tiles
	    svg_group.selectAll('.row').selectAll('.tile').attr('transform', function (d) {
	      return fine_position_tile(params, d);
	    }).attr('width', params.viz.rect_width).attr('height', params.viz.rect_height);

	    // resize tile_up
	    svg_group.selectAll('.row').selectAll('.tile_up').attr('d', function () {
	      return draw_up_tile(params);
	    }).attr('transform', function (d) {
	      return fine_position_tile(params, d);
	    });

	    // resize tile_dn
	    svg_group.selectAll('.row').selectAll('.tile_dn').attr('d', function () {
	      return draw_dn_tile(params);
	    }).attr('transform', function (d) {
	      return fine_position_tile(params, d);
	    });
	  } else {

	    // downsampling
	    /////////////////////////

	    var ds_level = params.viz.ds_level;
	    var row_class = '.ds' + String(ds_level) + '_row';
	    var ds_rect_height = params.viz.ds[ds_level].rect_height;

	    svg_group.selectAll(row_class).attr('transform', function (d) {
	      var inst_y = params.viz.ds[ds_level].y_scale(d.row_index);
	      return 'translate(0,' + inst_y + ')';
	    });

	    // reset ds-tiles
	    svg_group.selectAll(row_class).selectAll('.tile').attr('transform', function (d) {
	      return fine_position_tile(params, d);
	    }).attr('width', params.viz.rect_width).attr('height', ds_rect_height);
	  }
		};

/***/ },
/* 148 */
/***/ function(module, exports, __webpack_require__) {

	var calc_val_max = __webpack_require__(23);

	module.exports = function resize_label_bars(cgm, svg_group) {
	  var params = cgm.params;

	  // // set bar scale
	  // var val_max = Math.abs(_.max( params.network_data.row_nodes, function(d) {
	  //   return Math.abs(d.value);
	  // } ).value) ;

	  // params.labels.bar_scale_row = d3.scale
	  //   .linear()
	  //   .domain([0, val_max])
	  //   .range([0, params.viz.norm_labels.width.row ]);

	  params = calc_val_max(params);

	  svg_group.selectAll('.row_bars')
	  // .transition().delay(delays.update).duration(duration)
	  .attr('width', function (d) {
	    var inst_value = 0;
	    inst_value = params.labels.bar_scale_row(Math.abs(d.value));
	    return inst_value;
	  }).attr('x', function (d) {
	    var inst_value = 0;
	    inst_value = -params.labels.bar_scale_row(Math.abs(d.value));
	    return inst_value;
	  }).attr('height', params.viz.y_scale.rangeBand());
		};

/***/ },
/* 149 */
/***/ function(module, exports) {

	module.exports = function position_play_button(params) {

	  var clust_transform = d3.select(params.root + ' .clust_container').attr('transform');

	  var clust_x = Number(clust_transform.split('(')[1].split(',')[0]);
	  var clust_y = Number(clust_transform.split(',')[1].replace(')', ''));
	  var trans_x = clust_x + params.viz.clust.dim.width / 2;
	  var trans_y = clust_y + params.viz.clust.dim.height / 2;

	  d3.select(params.root + ' .play_button').attr('transform', function () {
	    return 'translate(' + trans_x + ',' + trans_y + ')';
	  });
		};

/***/ },
/* 150 */
/***/ function(module, exports) {

	module.exports = function position_svg_dendro_slider(cgm, inst_rc) {

	  var viz = cgm.params.viz;
	  var tmp_left;
	  var tmp_top;
	  if (inst_rc === 'row') {

	    // row dendrogram
	    ///////////////////////

	    // keep slider near clustergram
	    var max_room = viz.svg_dim.width - 3 * viz.uni_margin;

	    // position close to row dendrogram trapezoids
	    tmp_left = viz.clust.margin.left + viz.clust.dim.width + 5 * viz.dendro_room.row;

	    if (tmp_left > max_room) {
	      tmp_left = max_room;
	    }

	    tmp_top = viz.clust.margin.top + 3 * viz.uni_margin;
	  } else {

	    // column dendrogram
	    ///////////////////////
	    tmp_left = 2 * viz.uni_margin;
	    // tmp_top =  viz.svg_dim.height - 2.5 * viz.uni_margin;
	    tmp_top = viz.clust.margin.top + viz.clust.dim.height + viz.dendro_room.col - 2 * viz.uni_margin;
	  }

	  d3.select(cgm.params.root + ' .' + inst_rc + '_slider_group').attr('transform', function () {
	    var inst_translation;
	    if (inst_rc === 'row') {
	      inst_translation = 'translate(' + tmp_left + ',' + tmp_top + ')';
	    } else {
	      inst_translation = 'translate(' + tmp_left + ',' + tmp_top + '), rotate(-90)';
	    }
	    return inst_translation;
	  }).style('opacity', 1);
		};

/***/ },
/* 151 */
/***/ function(module, exports) {

	module.exports = function grid_lines_viz(params, duration = 0) {

	  var delay = 0;
	  if (duration > 0) {
	    delay = 2000;
	  }

	  var horz_lines = d3.selectAll(params.root + ' .horz_lines');
	  var vert_lines = d3.selectAll(params.root + ' .vert_lines');

	  horz_lines.style('opacity', 0).attr('transform', function (d) {
	    var inst_index = d.row_index;
	    var inst_trans = params.viz.y_scale(inst_index);
	    return 'translate(  0,' + inst_trans + ') rotate(0)';
	  }).transition().duration(duration).delay(delay).style('opacity', 1);

	  horz_lines.append('line').attr('x1', 0).attr('x2', params.viz.clust.dim.width).style('stroke-width', function () {
	    var inst_width = params.viz.border_width.y;
	    return inst_width + 'px';
	  });

	  vert_lines.style('opacity', 0).attr('transform', function (d) {
	    var inst_index = d.col_index;
	    var inst_trans = params.viz.x_scale(inst_index);
	    return 'translate(' + inst_trans + ') rotate(-90)';
	  }).transition().duration(duration).delay(delay).style('opacity', 1);

	  vert_lines.append('line').attr('x1', 0).attr('x2', -params.viz.clust.dim.height).style('stroke-width', function () {
	    var inst_width = params.viz.border_width.x;
	    return inst_width + 'px';
	  });
		};

/***/ },
/* 152 */
/***/ function(module, exports, __webpack_require__) {

	var cat_tooltip_text = __webpack_require__(153);
	var d3_tip_custom = __webpack_require__(48);
	var reset_cat_opacity = __webpack_require__(154);
	var ini_cat_opacity = __webpack_require__(155);
	var click_filter_cats = __webpack_require__(156);
	var get_cat_names = __webpack_require__(157);

	module.exports = function make_col_cat(cgm) {

	  var params = cgm.params;

	  // make or reuse outer container
	  if (d3.select(params.root + ' .col_cat_outer_container').empty()) {
	    d3.select(params.root + ' .col_container').append('g').attr('class', 'col_cat_outer_container').attr('transform', function () {
	      var inst_offset = params.viz.norm_labels.width.col + 2;
	      return 'translate(0,' + inst_offset + ')';
	    }).append('g').attr('class', 'col_cat_container');
	  } else {
	    d3.select(params.root + ' .col_container').select('col_cat_outer_container').attr('transform', function () {
	      var inst_offset = params.viz.norm_labels.width.col + 2;
	      return 'translate(0,' + inst_offset + ')';
	    });
	  }

	  // remove old col_cat_tips
	  d3.selectAll(params.viz.root_tips + '_col_cat_tip').remove();

	  // d3-tooltip
	  var cat_tip = d3_tip_custom().attr('class', function () {
	    var root_tip_selector = params.viz.root_tips.replace('.', '');
	    var class_string = root_tip_selector + ' d3-tip ' + root_tip_selector + '_col_cat_tip';
	    return class_string;
	  }).direction('s').offset([5, 0]).style('display', 'none').html(function (d) {
	    return cat_tooltip_text(params, d, this, 'col');
	  });

	  // append groups - each will hold classification rects
	  d3.select(params.root + ' .col_cat_container').selectAll('g').data(params.network_data.col_nodes, function (d) {
	    return d.name;
	  }).enter().append('g').attr('class', 'col_cat_group').attr('transform', function (d) {
	    var inst_index = _.indexOf(params.network_data.col_nodes_names, d.name);
	    // return 'translate(' + params.viz.x_scale(d.col_index) + ',0)';
	    return 'translate(' + params.viz.x_scale(inst_index) + ',0)';
	  });

	  d3.select(params.root + ' .col_cat_container').selectAll('.col_cat_group').call(cat_tip);

	  // add category rects
	  d3.selectAll(params.root + ' .col_cat_group').each(function () {

	    var inst_selection = this;
	    var cat_rect;

	    _.each(params.viz.all_cats.col, function (inst_cat) {

	      var inst_num = parseInt(inst_cat.split('-')[1], 10);
	      var cat_rect_class = 'col_cat_rect_' + String(inst_num);

	      if (d3.select(inst_selection).select('.' + cat_rect_class).empty()) {
	        cat_rect = d3.select(inst_selection).append('rect').attr('class', cat_rect_class).attr('cat', inst_cat).attr('transform', function () {
	          var cat_room = params.viz.cat_room.symbol_width + params.viz.cat_room.separation;
	          var inst_shift = inst_num * cat_room;
	          return 'translate(0,' + inst_shift + ')';
	        }).on('click', function (d) {

	          if (d3.select(this).classed('cat_strings')) {

	            if (d3.event.shiftKey === true) {
	              click_filter_cats_db(cgm, d, this, 'col');
	            } else {

	              var found_names = get_cat_names(params, d, this, 'col');

	              $(params.root + ' .dendro_info').modal('toggle');
	              var group_string = found_names.join(', ');
	              d3.select(params.root + ' .dendro_info input').attr('value', group_string);
	            }
	          }
	        });
	      } else {
	        cat_rect = d3.select(inst_selection).select('.' + cat_rect_class);
	      }

	      cat_rect.attr('width', params.viz.x_scale.rangeBand()).attr('height', params.viz.cat_room.symbol_width).style('fill', function (d) {
	        var cat_name = d[inst_cat];
	        var inst_color = params.viz.cat_colors.col[inst_cat][cat_name];
	        return inst_color;
	      }).on('mouseover', cat_tip.show).on('mouseout', function () {
	        cat_tip.hide(this);
	        reset_cat_opacity(params);
	        d3.select(this).classed('hovering', false);

	        d3.selectAll('.d3-tip').style('display', 'none');
	      });

	      ini_cat_opacity(params.viz, 'col', cat_rect, inst_cat);
	    });
	  });

	  var click_filter_cats_db = _.debounce(click_filter_cats, 1500);
		};

/***/ },
/* 153 */
/***/ function(module, exports, __webpack_require__) {

	var get_cat_title = __webpack_require__(113);

	module.exports = function cat_tooltip_text(params, inst_data, inst_selection, inst_rc) {

	  d3.selectAll(params.viz.root_tips + '_col_cat_tip').style('display', 'block');

	  d3.selectAll(params.viz.root_tips + '_row_cat_tip').style('display', 'block');

	  // category index
	  var inst_cat = d3.select(inst_selection).attr('cat');
	  var cat_title = get_cat_title(params.viz, inst_cat, inst_rc);
	  var cat_name = inst_data[inst_cat];

	  if (typeof cat_name === 'string') {
	    if (cat_name.indexOf(': ') >= 0) {
	      cat_name = cat_name.split(': ')[1];
	    }
	  }

	  var cat_string = cat_title + ': ' + cat_name;

	  d3.select(inst_selection).classed('hovering', true);

	  setTimeout(highlight_categories, 500);

	  return cat_string;

	  function highlight_categories() {

	    var run_highlighting = false;

	    if (d3.select(inst_selection).classed('hovering')) {

	      var node_types = [inst_rc];

	      if (params.viz.sim_mat) {
	        node_types = ['row', 'col'];
	      }

	      _.each(node_types, function (tmp_rc) {

	        // only highlight string categories that are not 'false' categories
	        if (typeof cat_name === 'string') {
	          if (cat_name.indexOf('Not ') < 0 && cat_name != 'false') {
	            run_highlighting = true;
	          }
	        }

	        if (run_highlighting) {

	          d3.selectAll(params.root + ' .' + tmp_rc + '_cat_group').selectAll('rect').style('opacity', function (d) {

	            var inst_opacity = d3.select(this).style('opacity');

	            if (d3.select(this).classed('cat_strings') && d3.select(this).classed('filtered_cat') === false) {

	              var tmp_name;
	              var tmp_cat = d3.select(this).attr('cat');

	              if (d[tmp_cat].indexOf(': ') >= 0) {
	                tmp_name = d[tmp_cat].split(': ')[1];
	              } else {
	                tmp_name = d[tmp_cat];
	              }

	              if (tmp_cat === inst_cat && tmp_name === cat_name) {
	                inst_opacity = params.viz.cat_colors.active_opacity;
	              } else {
	                inst_opacity = params.viz.cat_colors.opacity / 4;
	              }
	            }

	            return inst_opacity;
	          });
	        }
	      });
	    }
	  }
		};

/***/ },
/* 154 */
/***/ function(module, exports) {

	module.exports = function reset_cat_opacity(params) {

	  _.each(['row', 'col'], function (inst_rc) {

	    d3.selectAll(params.root + ' .' + inst_rc + '_cat_group').selectAll('rect').style('opacity', function () {

	      var inst_opacity = d3.select(this).style('opacity');

	      if (d3.select(this).classed('cat_strings') && d3.select(this).classed('filtered_cat') === false) {
	        inst_opacity = params.viz.cat_colors.opacity;
	      }

	      return inst_opacity;
	    });
	  });
		};

/***/ },
/* 155 */
/***/ function(module, exports) {

	module.exports = function ini_cat_opacity(viz, inst_rc, cat_rect, inst_cat, updating = false) {

	  // debugger;

	  var super_string = ': ';
	  var inst_type = viz.cat_info[inst_rc][inst_cat].type;

	  // set opacity based on string or value cats
	  if (inst_type === 'cat_strings') {

	    // optionally have categories transition in
	    if (updating) {
	      cat_rect.classed('cat_strings', true).style('opacity', 0).transition().duration(1000).style('opacity', viz.cat_colors.opacity);
	    } else {
	      // opacity is fixed
	      cat_rect.classed('cat_strings', true).style('opacity', viz.cat_colors.opacity);
	    }
	  } else {

	    // opacity varies based on value
	    cat_rect.classed('cat_values', true).style('opacity', function (d) {

	      var unprocessed_val = d[inst_cat];

	      var cat_value = get_cat_value(unprocessed_val);

	      return viz.cat_info[inst_rc][inst_cat].cat_scale(Math.abs(cat_value));
	    }).style('fill', function (d) {
	      var inst_color;

	      var cat_value = get_cat_value(d[inst_cat]);

	      // get positive and negative colors
	      if (cat_value > 0) {
	        inst_color = viz.cat_value_colors[0];
	      } else {
	        inst_color = viz.cat_value_colors[1];
	      }

	      return inst_color;
	    });
	  }

	  function get_cat_value(unprocessed_value) {
	    if (typeof unprocessed_value === 'string') {

	      if (unprocessed_value.indexOf(super_string) > -1) {
	        unprocessed_value = unprocessed_value.split(super_string)[1];
	      }
	    }

	    var cat_value = parseFloat(unprocessed_value);

	    return cat_value;
	  }
		};

/***/ },
/* 156 */
/***/ function(module, exports, __webpack_require__) {

	var get_cat_names = __webpack_require__(157);

	module.exports = function click_filter_cats(cgm, inst_data, inst_selection, inst_rc) {

	  var params = cgm.params;

	  var inst_cat = d3.select(inst_selection).attr('cat');
	  var cat_name = inst_data[inst_cat];

	  var found_names = get_cat_names(params, inst_data, inst_selection, inst_rc);

	  var switch_rc = { 'row': 'col', 'col': 'row' };
	  var other_rc = switch_rc[inst_rc];

	  var filter_names = {};
	  filter_names[inst_rc] = found_names;

	  if (cgm.params.cat_filter[inst_rc] === false) {

	    if (cgm.params.dendro_filter.row === false && cgm.params.dendro_filter.col === false && cgm.params.cat_filter[other_rc] === false) {

	      var tmp_names = cgm.params.network_data.col_nodes_names;

	      // keep a backup of the inst_view
	      var inst_row_nodes = cgm.params.network_data.row_nodes;
	      var inst_col_nodes = cgm.params.network_data.col_nodes;

	      // run filtering using found names
	      cgm.filter_viz_using_names(filter_names);

	      // overwrite with backup of original nodes
	      cgm.params.inst_nodes.row_nodes = inst_row_nodes;
	      cgm.params.inst_nodes.col_nodes = inst_col_nodes;

	      // must set this after filtering has been run
	      cgm.params.cat_filter[inst_rc] = tmp_names;

	      highlight_filtered_cat(inst_rc, inst_cat, cat_name);
	    }
	  } else {

	    // get backup of names
	    filter_names = cgm.params.cat_filter[inst_rc];

	    // reset filter
	    cgm.filter_viz_using_names(filter_names);
	    // must set this after filtering has been run
	    cgm.params.cat_filter[inst_rc] = false;

	    // there are no filtered cats
	    d3.selectAll(params.root + ' .' + inst_rc + '_cat_group').selectAll('rect').classed('filtered_cat', false);
	  }

	  function highlight_filtered_cat(inst_rc, inst_cat, cat_name) {

	    d3.selectAll(params.root + ' .' + inst_rc + '_cat_group').selectAll('rect').style('opacity', function (d) {

	      var inst_opacity = d3.select(this).style('opacity');

	      if (d3.select(this).classed('cat_strings')) {

	        var tmp_name;
	        var tmp_cat = d3.select(this).attr('cat');

	        // no need to filter out title
	        tmp_name = d[tmp_cat];

	        if (tmp_cat === inst_cat && tmp_name === cat_name) {
	          inst_opacity = 1;

	          d3.select(this).classed('filtered_cat', true);
	        }
	        // else {
	        //   inst_opacity = params.viz.cat_colors.opacity/4;
	        // }
	      }

	      return inst_opacity;
	    });
	  }
		};

/***/ },
/* 157 */
/***/ function(module, exports, __webpack_require__) {

	var utils = __webpack_require__(2);

	module.exports = function get_cat_names(params, inst_data, inst_selection, inst_rc) {

	  // category index
	  var inst_cat = d3.select(inst_selection).attr('cat');
	  var cat_name = inst_data[inst_cat];
	  var tmp_nodes = params.network_data[inst_rc + '_nodes'];

	  var found_nodes = _.filter(tmp_nodes, function (d) {
	    return d[inst_cat] == cat_name;
	  });

	  var found_names = utils.pluck(found_nodes, 'name');

	  return found_names;
	};

/***/ },
/* 158 */
/***/ function(module, exports, __webpack_require__) {

	var cat_tooltip_text = __webpack_require__(153);
	var d3_tip_custom = __webpack_require__(48);
	var reset_cat_opacity = __webpack_require__(154);
	var ini_cat_opacity = __webpack_require__(155);
	var click_filter_cats = __webpack_require__(156);
	var get_cat_names = __webpack_require__(157);

	module.exports = function make_row_cat(cgm, updating = false) {

	  // console.log('make_row_cat')

	  var params = cgm.params;

	  // make or reuse outer container
	  if (d3.select(params.root + ' .row_cat_outer_container').empty()) {
	    d3.select(params.root + ' .row_container').append('g').attr('class', 'row_cat_outer_container').attr('transform', 'translate(' + params.viz.norm_labels.width.row + ',0)').append('g').attr('class', 'row_cat_container');
	  } else {
	    d3.select(params.root + ' .row_container').select('row_cat_outer_container').attr('transform', 'translate(' + params.viz.norm_labels.width.row + ',0)');
	  }

	  // white background
	  if (d3.select(params.root + ' .row_cat_container').select('.white_bars').empty()) {
	    d3.select(params.root + ' .row_cat_container').append('rect').attr('class', 'white_bars').attr('fill', params.viz.background_color).attr('width', params.viz.cat_room.row + 'px').attr('height', function () {
	      var inst_height = params.viz.clust.dim.height;
	      return inst_height;
	    });
	  } else {
	    d3.select(params.root + ' .row_cat_container').select('.white_bars').attr('fill', params.viz.background_color).attr('width', params.viz.cat_room.row + 'px').attr('height', function () {
	      var inst_height = params.viz.clust.dim.height;
	      return inst_height;
	    });
	  }

	  // remove old col_cat_tips
	  d3.selectAll(params.viz.root_tips + '_row_cat_tip').remove();

	  // d3-tooltip
	  var cat_tip = d3_tip_custom().attr('class', function () {
	    var root_tip_selector = params.viz.root_tips.replace('.', '');
	    var class_string = root_tip_selector + ' d3-tip ' + root_tip_selector + '_row_cat_tip';
	    return class_string;
	  }).direction('e').offset([5, 0]).style('display', 'none').html(function (d) {
	    return cat_tooltip_text(params, d, this, 'row');
	  });

	  // groups that hold classification triangle and colorbar rect
	  d3.select(params.root + ' .row_cat_container').selectAll('g').data(params.network_data.row_nodes, function (d) {
	    // console.log('-------------')
	    // console.log(d['cat-0'])
	    // console.log('-------------')
	    return d.name;
	  }).enter().append('g').attr('class', 'row_cat_group').attr('transform', function (d) {
	    var inst_index = _.indexOf(params.network_data.row_nodes_names, d.name);
	    return 'translate(0, ' + params.viz.y_scale(inst_index) + ')';
	  });

	  d3.select(params.root + ' .row_cat_container').selectAll('.row_cat_group').call(cat_tip);

	  // add row visual-aid triangles (if no downsampling)
	  // if (params.viz.ds_level === -1){
	  // d3.selectAll(params.root+' .row_cat_group')
	  //   .append('path')
	  //   .attr('d', function() {
	  //     var origin_x = params.viz.cat_room.symbol_width - 1;
	  //     var origin_y = 0;
	  //     var mid_x = 1;
	  //     var mid_y = params.viz.y_scale.rangeBand() / 2;
	  //     var final_x = params.viz.cat_room.symbol_width - 1;
	  //     var final_y = params.viz.y_scale.rangeBand();
	  //     var output_string = 'M ' + origin_x + ',' + origin_y + ' L ' +
	  //       mid_x + ',' + mid_y + ', L ' + final_x + ',' + final_y + ' Z';
	  //     return output_string;
	  //   })
	  //   .attr('fill', '#eee')
	  //   .style('opacity', params.viz.triangle_opacity);
	  // }

	  var cat_rect;
	  var inst_selection;

	  d3.selectAll(params.root + ' .row_cat_group rect').remove();

	  if (params.viz.show_categories.row) {

	    d3.selectAll(params.root + ' .row_cat_group').each(function () {

	      inst_selection = this;

	      _.each(params.viz.all_cats.row, function (inst_cat) {

	        var inst_num = parseInt(inst_cat.split('-')[1], 10);
	        var cat_rect_class = 'row_cat_rect_' + String(inst_num);

	        if (d3.select(inst_selection).select('.' + cat_rect_class).empty()) {
	          cat_rect = d3.select(inst_selection).append('rect').attr('class', cat_rect_class).attr('cat', inst_cat);
	        } else {
	          cat_rect = d3.select(inst_selection).select('.' + cat_rect_class);
	        }

	        cat_rect.attr('width', params.viz.cat_room.symbol_width).attr('height', params.viz.y_scale.rangeBand()).style('fill', function (d) {
	          var cat_name = d[inst_cat];

	          // if (cat_name.indexOf(': ') >= 0){
	          //   cat_name = cat_name.split(': ')[1];
	          // }

	          // console.log(cat_name)

	          var inst_color = params.viz.cat_colors.row[inst_cat][cat_name];

	          // console.log('inst_color: ' + String(inst_color));
	          return inst_color;
	        }).attr('x', function () {
	          var inst_offset = params.viz.cat_room.symbol_width + params.viz.uni_margin / 2;
	          return inst_offset + 'px';
	        }).attr('transform', function () {
	          var cat_room = params.viz.cat_room.symbol_width + params.viz.cat_room.separation;
	          var inst_shift = inst_num * cat_room;
	          return 'translate(' + inst_shift + ',0)';
	        }).on('click', function (d) {

	          if (d3.select(this).classed('cat_strings')) {

	            if (d3.event.shiftKey === true) {
	              click_filter_cats_db(cgm, d, this, 'row');
	            } else {

	              var found_names = get_cat_names(params, d, this, 'row');

	              $(params.root + ' .dendro_info').modal('toggle');
	              var group_string = found_names.join(', ');
	              d3.select(params.root + ' .dendro_info input').attr('value', group_string);
	            }
	          }
	        }).on('mouseover', cat_tip.show).on('mouseout', function () {
	          cat_tip.hide(this);
	          reset_cat_opacity(params);
	          d3.select(this).classed('hovering', false);

	          d3.selectAll('.d3-tip').style('display', 'none');
	        });

	        ini_cat_opacity(params.viz, 'row', cat_rect, inst_cat, updating);
	      });
	    });
	  }

	  var click_filter_cats_db = _.debounce(click_filter_cats, 1500);
		};

/***/ },
/* 159 */
/***/ function(module, exports, __webpack_require__) {

	var make_dendro_triangles = __webpack_require__(55);

	module.exports = function make_row_dendro(cgm) {

	  var params = cgm.params;

	  var spillover_width = params.viz.dendro_room.row + params.viz.uni_margin;

	  // position row_dendro_outer_container
	  var x_offset = params.viz.clust.margin.left + params.viz.clust.dim.width;
	  var y_offset = params.viz.clust.margin.top;

	  // make or reuse outer container
	  if (d3.select(params.root + ' .row_dendro_outer_container').empty()) {

	    d3.select(params.root + ' .viz_svg').append('g').attr('class', 'row_dendro_outer_container').attr('transform', 'translate(' + x_offset + ',' + y_offset + ')');

	    d3.select(params.root + ' .row_dendro_outer_container').append('rect').classed('row_dendro_spillover', true).attr('fill', params.viz.background_color).attr('width', spillover_width + 'px').attr('height', params.viz.svg_dim.height);

	    d3.select(params.root + ' .row_dendro_outer_container').append('g').attr('class', 'row_dendro_container').attr('transform', 'translate(' + params.viz.uni_margin / 2 + ',0)');
	  } else {
	    d3.select(params.root + ' .viz_svg').select('row_dendro_outer_container').attr('transform', 'translate(' + x_offset + ',' + y_offset + ')');

	    d3.select(params.root + ' .row_dendro_outer_container').select('.row_dendro_spillover').attr('width', spillover_width + 'px').attr('height', params.viz.svg_dim.height);
	  }

	  make_dendro_triangles(cgm, 'row', false);

	  if (params.viz.inst_order.col != 'clust') {
	    d3.selectAll(params.root + ' .row_dendro_group').remove();
	  }
		};

/***/ },
/* 160 */
/***/ function(module, exports, __webpack_require__) {

	var make_dendro_triangles = __webpack_require__(55);

	module.exports = function make_col_dendro(cgm) {

	  var params = cgm.params;

	  // position col_dendro_outer_container
	  var x_offset = params.viz.clust.margin.left;
	  var y_offset = params.viz.clust.margin.top + params.viz.clust.dim.height;
	  var spillover_height = params.viz.dendro_room.col + params.viz.uni_margin;

	  // make or reuse outer container
	  if (d3.select(params.root + ' .col_dendro_outer_container').empty()) {

	    d3.select(params.root + ' .viz_svg').append('g').attr('class', 'col_dendro_outer_container').attr('transform', 'translate(' + x_offset + ',' + y_offset + ')');

	    d3.select(params.root + ' .col_dendro_outer_container').append('rect').classed('col_dendro_spillover', true).attr('fill', params.viz.background_color).attr('width', params.viz.svg_dim.width).attr('height', spillover_height + 'px');

	    d3.select(params.root + ' .col_dendro_outer_container').append('g').attr('class', 'col_dendro_container').attr('transform', 'translate(0,' + params.viz.uni_margin / 2 + ')');

	    d3.select(params.root + ' .col_dendro_outer_container').append('rect').classed('col_dendro_spillover_top', true).attr('fill', params.viz.background_color).attr('width', params.viz.svg_dim.width).attr('height', params.viz.svg_dim.height).attr('transform', 'translate(0,' + params.viz.dendro_room.col + ')');
	  } else {

	    d3.select(params.root + ' .viz_svg').select('col_dendro_outer_container').attr('transform', 'translate(' + x_offset + ',' + y_offset + ')');

	    d3.select(params.root + ' .col_dendro_outer_container').select('.col_dendro_spillover').attr('width', params.viz.svg_dim.width).attr('height', spillover_height + 'px');
	  }

	  make_dendro_triangles(cgm, 'col', false);

	  if (params.viz.inst_order.row != 'clust') {
	    d3.selectAll(params.root + ' .col_dendro_group').remove();
	  }
		};

/***/ },
/* 161 */
/***/ function(module, exports, __webpack_require__) {

	var build_svg_dendro_slider = __webpack_require__(162);

	module.exports = function make_svg_dendro_sliders(cgm) {

	  build_svg_dendro_slider(cgm, 'row');
	  build_svg_dendro_slider(cgm, 'col');
		};

/***/ },
/* 162 */
/***/ function(module, exports, __webpack_require__) {

	var change_groups = __webpack_require__(163);
	var position_svg_dendro_slider = __webpack_require__(150);

	module.exports = function build_svg_dendro_slider(cgm, inst_rc) {

	  var slider_length = 100;

	  var drag = d3.behavior.drag().on("drag", dragging).on('dragend', function () {
	    cgm.params.is_slider_drag = false;
	  });

	  var slider_group = d3.select(cgm.params.root + ' .viz_svg').append('g').classed(inst_rc + '_slider_group', true);

	  position_svg_dendro_slider(cgm, inst_rc);

	  var rect_height = slider_length + 20;
	  var rect_width = 30;
	  slider_group.append('rect').classed(inst_rc + '_slider_background', true).attr('height', rect_height + 'px').attr('width', rect_width + 'px').attr('fill', cgm.params.viz.background_color).attr('transform', function () {
	    var translate_string = 'translate(-10, -5)';
	    return translate_string;
	  }).style('opacity', 0);

	  slider_group.append("line").style('stroke-width', slider_length / 7 + 'px').style('stroke', 'black').style('stroke-linecap', 'round').style('opacity', 0.0).attr("y1", 0).attr("y2", function () {
	    return slider_length - 2;
	  }).on('click', click_dendro_slider);

	  var offset_triangle = -slider_length / 40;
	  slider_group.append('path').style('fill', 'black').attr('transform', 'translate(' + offset_triangle + ', 0)').attr('d', function () {

	    // up triangle
	    var start_x = 0;
	    var start_y = 0;

	    var mid_x = 0;
	    var mid_y = slider_length;

	    var final_x = slider_length / 10;
	    var final_y = 0;

	    var output_string = 'M' + start_x + ',' + start_y + ', L' + mid_x + ', ' + mid_y + ', L' + final_x + ',' + final_y + ' Z';

	    return output_string;
	  }).style('opacity', 0.35).on('click', click_dendro_slider);

	  var default_opacity = 0.35;
	  var high_opacity = 0.6;
	  slider_group.append('circle').classed(inst_rc + '_group_circle', true).attr('r', slider_length * 0.08).attr('transform', function () {
	    return 'translate(0, ' + slider_length / 2 + ')';
	  }).style('fill', 'blue').style('opacity', default_opacity).on('mouseover', function () {
	    d3.select(this).style('opacity', high_opacity);
	  }).on('mouseout', function () {
	    d3.select(this).style('opacity', default_opacity);
	  }).call(drag);

	  function dragging() {

	    cgm.params.is_slider_drag = true;

	    // d[0] = d3.event.x;
	    var slider_pos = d3.event.y;

	    if (slider_pos < 0) {
	      slider_pos = 0;
	    }

	    if (slider_pos > slider_length) {
	      slider_pos = slider_length;
	    }

	    if (this.nextSibling) {
	      this.parentNode.appendChild(this);
	    }

	    slider_pos = d3.round(slider_pos, -1);

	    var slider_value = 10 - slider_pos / 10;

	    d3.select(this).attr("transform", "translate(0, " + slider_pos + ")");

	    change_groups(cgm, inst_rc, slider_value);
	  }

	  function click_dendro_slider() {

	    var clicked_line_position = d3.mouse(this);

	    var rel_pos = d3.round(clicked_line_position[1], -1);

	    d3.select(cgm.params.root + ' .' + inst_rc + '_group_circle').attr('transform', 'translate(0, ' + rel_pos + ')');

	    var slider_value = 10 - rel_pos / 10;

	    change_groups(cgm, inst_rc, slider_value);
	  }
	};

/***/ },
/* 163 */
/***/ function(module, exports, __webpack_require__) {

	// var build_color_groups = require('./build_color_groups');
	var make_dendro_triangles = __webpack_require__(55);

	/* Changes the groupings (x- and y-axis color bars).
	 */
	module.exports = function (cgm, inst_rc, inst_index) {

	  var params = cgm.params;

	  if (inst_rc === 'row') {
	    params.group_level.row = inst_index;
	  } else if (inst_rc === 'col') {
	    params.group_level.col = inst_index;
	  }

	  var is_change_group = true;

	  make_dendro_triangles(cgm, inst_rc, is_change_group);
		};

/***/ },
/* 164 */
/***/ function(module, exports, __webpack_require__) {

	var make_dendro_crop_buttons = __webpack_require__(60);

	module.exports = function make_row_dendro_spillover(cgm) {

	  var viz = cgm.params.viz;

	  // hide spillover from right
	  var tmp_left = viz.clust.margin.left + viz.clust.dim.width + viz.uni_margin + viz.dendro_room.row;

	  var r_spill_container = d3.select(viz.viz_svg).append('g').classed('right_spillover_container', true).attr('transform', function () {
	    return 'translate(' + tmp_left + ', 0)';
	  });

	  var tmp_top = viz.norm_labels.margin.top + viz.norm_labels.width.col;

	  r_spill_container.append('rect').attr('fill', viz.background_color) //!! prog_colors
	  .attr('width', 10 * viz.clust.dim.width).attr('height', viz.svg_dim.height + 'px').attr('class', 'white_bars').attr('class', 'right_spillover').attr('transform', function () {
	    return 'translate( 0,' + tmp_top + ')';
	  });

	  var x_offset = 0;
	  var y_offset = viz.clust.margin.top;
	  r_spill_container.append('g').classed('row_dendro_icons_container', true).attr('transform', 'translate(' + x_offset + ',' + y_offset + ')').append('g').classed('row_dendro_icons_group', true);

	  make_dendro_crop_buttons(cgm, 'row');

	  // hide spillover from top of row dendrogram
	  x_offset = viz.clust.margin.left + viz.clust.dim.width;
	  y_offset = tmp_top;

	  var tmp_width = viz.dendro_room.row + viz.uni_margin;
	  var tmp_height = viz.cat_room.col + viz.uni_margin;
	  d3.select(viz.viz_svg).append('rect').attr('fill', viz.background_color).attr('width', tmp_width).attr('height', tmp_height).attr('transform', function () {
	    return 'translate(' + x_offset + ',' + y_offset + ')';
	  }).classed('white_bars', true).classed('dendro_row_spillover', true);
		};

/***/ },
/* 165 */
/***/ function(module, exports, __webpack_require__) {

	/* eslint-disable */

	var run_segment = __webpack_require__(166);
	var play_intro = __webpack_require__(167);
	var play_zoom = __webpack_require__(169);
	var play_reset_zoom = __webpack_require__(170);
	var play_reorder_row = __webpack_require__(172);
	var play_reorder_buttons = __webpack_require__(173);
	var play_search = __webpack_require__(175);
	var play_filter = __webpack_require__(176);
	var quick_cluster = __webpack_require__(199);
	var play_groups = __webpack_require__(200);
	var play_categories = __webpack_require__(201);
	var play_conclusion = __webpack_require__(202);
	var toggle_play_button = __webpack_require__(203);
	var play_menu_button = __webpack_require__(204);

	module.exports = function play_demo() {

	  var cgm = this;
	  var params = cgm.params;

	  if (d3.select(params.root + ' .running_demo').empty()) {

	    // prevent more than one demo from running at once
	    d3.select(params.root + ' .play_button').classed('running_demo', true);

	    toggle_play_button(params, false);

	    // prevent user interaction while playing
	    $.blockUI({ css: {
	        border: 'none',
	        padding: '15px',
	        backgroundColor: '#000',
	        '-webkit-border-radius': '10px',
	        '-moz-border-radius': '10px',
	        opacity: 0,
	        color: '#fff',
	        cursor: 'default'
	      } });

	    d3.selectAll('.blockUI').style('opacity', 0);

	    // intro text
	    var inst_time = 750;

	    if (cgm.params.viz.is_expand === false) {
	      inst_time = run_segment(params, inst_time, quick_cluster);
	      inst_time = inst_time - 1500;
	    }

	    // clustergram interaction
	    ///////////////////////////////////
	    inst_time = run_segment(params, inst_time, play_intro);
	    inst_time = run_segment(params, inst_time, play_zoom);
	    inst_time = run_segment(cgm, inst_time, play_reset_zoom);
	    inst_time = run_segment(params, inst_time, play_categories);
	    inst_time = run_segment(params, inst_time, play_reorder_row);

	    // sidebar interaction
	    ///////////////////////////////////
	    inst_time = run_segment(params, inst_time, play_menu_button);
	    inst_time = run_segment(params, inst_time, play_groups);
	    inst_time = run_segment(params, inst_time, play_reorder_buttons);
	    inst_time = run_segment(params, inst_time, play_search);
	    inst_time = run_segment(cgm, inst_time, play_filter);

	    // conclusion
	    ///////////////////////////////////
	    inst_time = run_segment(params, inst_time, quick_cluster);
	    inst_time = run_segment(params, inst_time, play_conclusion);
	  }
		};

/***/ },
/* 166 */
/***/ function(module, exports) {


	module.exports = function run_segment(segment_data, inst_time, inst_segment) {
	  /* eslint-disable */

	  var timer = setTimeout(inst_segment().run, inst_time, segment_data);

	  // set up kill demo that will stop setTimeouts
	  //////////////////////////////////////////////////
	  // if (clear_timer){
	  //   clearTimeout(timer);
	  // }

	  var inst_duration = inst_segment().get_duration();
	  inst_time = inst_time + inst_duration;

	  return inst_time;
		};

/***/ },
/* 167 */
/***/ function(module, exports, __webpack_require__) {

	var demo_text = __webpack_require__(168);

	module.exports = function play_intro() {

	  var speed_up = 1;

	  function run(params) {
	    var text_1 = 'Clustergrammer allows users to generate\ninteractive and ' + 'sharable visualizations\nby uploading a matrix';
	    var text_2 = "This demo will quickly overview some\nof Clustergrammer's " + "interactive features";

	    setTimeout(demo_text, 0, params, text_1, 4500 / speed_up);
	    setTimeout(demo_text, 4500 / speed_up, params, text_2, 4500 / speed_up);
	  }

	  function get_duration() {
	    return 10000 / speed_up;
	  }

	  return {
	    run: run,
	    get_duration: get_duration
	  };
		};

/***/ },
/* 168 */
/***/ function(module, exports) {

	module.exports = function demo_text(params, text, read_duration) {

	  var split_text = text.split('\n');

	  if (split_text.length < 3) {
	    split_text.push('');
	  }

	  d3.select(params.root + ' .demo_group').style('opacity', 0).transition().duration(250).style('opacity', 1).transition().duration(250).delay(read_duration).style('opacity', 0);

	  for (var i = 0; i < split_text.length; i++) {

	    var inst_text_num = i + 1;

	    // make text box
	    //////////////////
	    var inst_text_obj = d3.select(params.root + ' .demo_group').select('#text_' + inst_text_num).text(split_text[i]);
	    var bbox = inst_text_obj[0][0].getBBox();

	    var box_opacity = 0.9;

	    var tmp_fs = Number(d3.select('.demo_group').select('text').style('font-size').replace('px', ''));
	    var shift_height = tmp_fs * 1.3;

	    d3.select(params.root + ' .demo_group').select('.rect_' + inst_text_num).style('fill', 'white').attr('width', bbox.width + 20).attr('height', bbox.height).attr('x', -10).attr('y', bbox.y + i * shift_height).style('opacity', box_opacity);
	  }
		};

/***/ },
/* 169 */
/***/ function(module, exports, __webpack_require__) {

	var demo_text = __webpack_require__(168);
	var two_translate_zoom = __webpack_require__(116);

	module.exports = function play_zoom() {

	  function run(cgm) {

	    var params = cgm.params;
	    var text = 'Zoom and pan by\nscrolling and dragging';
	    demo_text(params, text, 4000);

	    setTimeout(two_translate_zoom, 1500, cgm, 0, 0, 4);
	  }

	  function get_duration() {
	    return 4000;
	  }

	  return {
	    run: run,
	    get_duration: get_duration
	  };
		};

/***/ },
/* 170 */
/***/ function(module, exports, __webpack_require__) {

	var demo_text = __webpack_require__(168);
	var two_translate_zoom = __webpack_require__(116);
	var sim_click = __webpack_require__(171);

	module.exports = function play_reset_zoom() {

	  function run(cgm) {

	    var params = cgm.params;

	    var text = 'Reset zoom by double-clicking\n';
	    demo_text(params, text, 4000);

	    setTimeout(sim_click, 2000, params, 'double', 300, 300);
	    setTimeout(two_translate_zoom, 2400, cgm, 0, 0, 1);
	  }

	  function get_duration() {
	    return 4500;
	  }

	  return {
	    run: run,
	    get_duration: get_duration
	  };
		};

/***/ },
/* 171 */
/***/ function(module, exports) {

	module.exports = function sim_click(params, single_double, pos_x, pos_y) {

	  var click_duration = 200;

	  var click_circle = d3.select(params.root + ' .viz_svg').append('circle').attr('cx', pos_x).attr('cy', pos_y).attr('r', 25).style('stroke', 'black').style('stroke-width', '3px').style('fill', '#007f00').style('opacity', 0.5);

	  if (single_double === 'double') {
	    click_circle.transition().duration(click_duration).style('opacity', 0.0).transition().duration(50).style('opacity', 0.5).transition().duration(click_duration).style('opacity', 0.0).remove();
	  } else {
	    click_circle.transition().duration(click_duration).style('opacity', 0.0).transition().duration(250).remove();
	  }
		};

/***/ },
/* 172 */
/***/ function(module, exports, __webpack_require__) {

	var demo_text = __webpack_require__(168);
	var sim_click = __webpack_require__(171);

	module.exports = function play_reorder_row() {
	  /* eslint-disable */

	  function run(params) {

	    var text = 'Reorder the matrix based on a single\nrow or column by double-clicking a\nlabel';
	    demo_text(params, text, 7000);

	    var inst_element = get_row_element(params, 'EGFR');

	    var group_trans = d3.select(inst_element).attr('transform');

	    var container_trans = d3.select(params.root + ' .clust_container').attr('transform').split(',')[1].replace(')', '');

	    var x_trans = params.viz.norm_labels.width.row * 0.9;

	    var row_trans = group_trans.split(',')[1].replace(')', '');
	    var y_trans = String(Number(row_trans) + Number(container_trans) + params.viz.rect_height / 2);

	    var wait_click = 4000;
	    setTimeout(sim_click, wait_click, params, 'double', x_trans, y_trans);
	    var wait_reorder = wait_click + 300;
	    setTimeout(fire_double_click_row, wait_reorder, params, inst_element);
	  }

	  function get_duration() {
	    return 8000;
	  }

	  function get_row_element(params, inst_row) {

	    var inst_element = d3.selectAll(params.root + ' .row_label_group').filter(function () {
	      var inst_data = this.__data__;
	      return inst_data.name == inst_row;
	    })[0][0];

	    return inst_element;
	  }

	  function fire_double_click_row(params, inst_element) {

	    $(inst_element).d3DblClick();
	  }

	  // allows doubleclicking on d3 element
	  jQuery.fn.d3DblClick = function () {
	    this.each(function (i, e) {
	      var evt = document.createEvent("MouseEvents");
	      evt.initMouseEvent("dblclick", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
	      e.dispatchEvent(evt);
	    });
	  };

	  return {
	    run: run,
	    get_duration: get_duration
	  };
		};

/***/ },
/* 173 */
/***/ function(module, exports, __webpack_require__) {

	var demo_text = __webpack_require__(168);
	var highlight_sidebar_element = __webpack_require__(174);

	module.exports = function play_reorder_buttons() {
	  /* eslint-disable */

	  function run(params) {

	    var text = 'Reorder all rows and columns\nby clicking the reorder\n buttons';
	    demo_text(params, text, 9000);

	    setTimeout(highlight_sidebar_element, 3000, params, 'toggle_col_order');
	    setTimeout(click_reorder_button, 3500, params, 'col', 'rank');

	    setTimeout(highlight_sidebar_element, 7000, params, 'toggle_row_order');
	    setTimeout(click_reorder_button, 7500, params, 'row', 'rank');
	  }

	  function get_duration() {
	    return 11000;
	  }

	  function click_reorder_button(params, inst_rc, inst_order) {
	    var inst_button = d3.selectAll('.toggle_' + inst_rc + '_order .btn').filter(function () {
	      return this.__data__ == inst_order;
	    })[0];

	    $(inst_button).click();
	  }

	  return {
	    run: run,
	    get_duration: get_duration
	  };
		};

/***/ },
/* 174 */
/***/ function(module, exports) {

	module.exports = function highlight_sidebar_element(params, highlight_class, duration = 4000) {

	  if (highlight_class.indexOf('slider') < 0) {
	    d3.select(params.root + ' .' + highlight_class).style('background', '#007f00').style('box-shadow', '0px 0px 10px 5px #007f00').transition().duration(1).delay(duration).style('background', '#FFFFFF').style('box-shadow', 'none');
	  } else {
	    d3.select(params.root + ' .' + highlight_class).style('box-shadow', '0px 0px 10px 5px #007f00').transition().duration(1).delay(duration).style('box-shadow', 'none');
	  }
		};

/***/ },
/* 175 */
/***/ function(module, exports, __webpack_require__) {

	var demo_text = __webpack_require__(168);
	var highlight_sidebar_element = __webpack_require__(174);
	var two_translate_zoom = __webpack_require__(116);

	module.exports = function play_search() {

	  function run(cgm) {

	    var params = cgm.params;
	    var text = 'Search for rows using\nthe search box';
	    demo_text(params, text, 5000);

	    var ini_delay = 2500;
	    setTimeout(highlight_sidebar_element, ini_delay, params, 'gene_search_container');

	    // manually mimic typing and autocomplete
	    setTimeout(type_out_search, ini_delay + 1000, params, 'E');
	    setTimeout(type_out_search, ini_delay + 1500, params, 'EG');
	    setTimeout(type_out_search, ini_delay + 2000, params, 'EGF');
	    setTimeout(type_out_search, ini_delay + 2500, params, 'EGFR');

	    setTimeout(run_search, 5500, params);

	    setTimeout(two_translate_zoom, 7500, cgm, 0, 0, 1);
	  }

	  function get_duration() {
	    return 10000;
	  }

	  function type_out_search(params, inst_string) {
	    $(params.root + ' .gene_search_box').val(inst_string);
	    $(params.root + ' .gene_search_box').autocomplete("search", inst_string);
	  }

	  function run_search(params) {
	    $(params.root + ' .submit_gene_button').click();
	    $(params.root + ' .gene_search_box').autocomplete("search", '');
	  }

	  return {
	    run: run,
	    get_duration: get_duration
	  };
		};

/***/ },
/* 176 */
/***/ function(module, exports, __webpack_require__) {

	var demo_text = __webpack_require__(168);
	var highlight_sidebar_element = __webpack_require__(174);
	var update_viz_with_view = __webpack_require__(177);

	module.exports = function play_filter() {

	  function run(cgm) {
	    var params = cgm.params;

	    var text = 'Filter rows based on sum or\nvariance using the sliders';
	    demo_text(params, text, 4000);

	    var filter_type = 'N_row_sum';

	    setTimeout(highlight_sidebar_element, 5000, params, 'slider_' + filter_type, 13000);

	    text = 'Filter: Top 20 rows by sum';
	    setTimeout(demo_text, 5000, params, text, 4000);
	    setTimeout(run_update, 5300, cgm, filter_type, 20, 1);

	    text = 'Filter: Top 10 rows by sum';
	    setTimeout(demo_text, 10000, params, text, 4000);
	    setTimeout(run_update, 10300, cgm, filter_type, 10, 2);

	    text = 'Filter: All rows';
	    setTimeout(demo_text, 15000, params, text, 4000);
	    setTimeout(run_update, 15300, cgm, filter_type, 'all', 0);
	  }

	  function get_duration() {
	    return 19500;
	  }

	  function run_update(cgm, filter_type, filter_value, filter_index) {

	    var params = cgm.params;

	    var requested_view = {};
	    requested_view[filter_type] = filter_value;
	    update_viz_with_view(cgm, requested_view);

	    // quick fix for slider
	    $(params.root + ' .slider_' + filter_type).slider("value", filter_index);

	    var unit_name;
	    if (filter_type === 'N_row_sum') {
	      unit_name = 'sum';
	    } else {
	      unit_name = 'variance';
	    }

	    d3.select(params.root + ' .title_' + filter_type).text('Top rows ' + unit_name + ': ' + filter_value);
	  }

	  return {
	    run: run,
	    get_duration: get_duration
	  };
		};

/***/ },
/* 177 */
/***/ function(module, exports, __webpack_require__) {

	var make_network_using_view = __webpack_require__(10);
	var disable_sidebar = __webpack_require__(178);
	var update_viz_with_network = __webpack_require__(179);

	module.exports = function update_viz_with_view(cgm, requested_view) {

	  disable_sidebar(cgm.params);

	  // make new_network_data by filtering the original network data
	  var new_network_data = make_network_using_view(cgm.config, cgm.params, requested_view);

	  // reset crop button
	  d3.select(cgm.params.root + ' .crop_button').style('color', '#337ab7').classed('fa-crop', true).classed('fa-undo', false).classed('active_cropping', false);

	  // reset dendrogram filtering when updating with a new view
	  // e.g. with the row filter sliders
	  _.each(['row', 'col'], function (inst_rc) {

	    // set class to reflect that no filtering was ran
	    d3.select(cgm.params.root + ' .' + inst_rc + '_dendro_icons_group').classed('ran_filter', false);

	    // display all crop buttons when cropping has not been done
	    d3.select(cgm.params.root + ' .' + inst_rc + '_dendro_icons_container').style('display', 'block');
	  });

	  update_viz_with_network(cgm, new_network_data);
		};

/***/ },
/* 178 */
/***/ function(module, exports) {

	module.exports = function disable_sidebar(params) {

	  d3.selectAll(params.root + ' .btn').attr('disabled', true);
	  d3.select(params.viz.viz_svg).style('opacity', 0.70);
		};

/***/ },
/* 179 */
/***/ function(module, exports, __webpack_require__) {

	var make_params = __webpack_require__(9);
	var define_enter_exit_delays = __webpack_require__(180);
	var enter_exit_update = __webpack_require__(181);
	var initialize_resizing = __webpack_require__(123);
	var make_col_cat = __webpack_require__(152);
	var make_row_cat = __webpack_require__(158);
	var make_row_dendro = __webpack_require__(159);
	var make_col_dendro = __webpack_require__(160);
	var ini_sidebar = __webpack_require__(192);
	var enable_sidebar = __webpack_require__(194);
	var ini_doubleclick = __webpack_require__(133);
	var update_reorder_buttons = __webpack_require__(195);
	var make_row_cat_super_labels = __webpack_require__(122);
	var modify_row_node_cats = __webpack_require__(196);
	var run_zoom = __webpack_require__(125);
	var ds_enter_exit_update = __webpack_require__(198);
	var make_cat_params = __webpack_require__(32);

	module.exports = function update_viz_with_network(cgm, new_network_data) {

	  // console.log('UPDATE VIZ WITH NETWORK')

	  // set runnning_update class, prevents multiple update from running at once
	  d3.select(cgm.params.viz.viz_svg).classed('running_update', true);

	  // remove downsampled rows always
	  d3.selectAll(cgm.params.root + ' .ds' + String(cgm.params.viz.ds_level) + '_row').remove();

	  // run optional callback function
	  // console.log('before and after matrix_update_callback')
	  // console.log(new_network_data.row_nodes[0]['cat-0'])
	  if (cgm.params.matrix_update_callback != null) {
	    cgm.params.matrix_update_callback();
	  }
	  // console.log(new_network_data.row_nodes[0]['cat-0'])

	  var inst_group_level = cgm.params.group_level;
	  var inst_crop_fitler = cgm.params.crop_filter_nodes;

	  // make tmp config to make new params
	  var tmp_config = jQuery.extend(true, {}, cgm.config);

	  var new_row_cats = null;

	  // bring in 'new' category data
	  if (cgm.params.new_row_cats != null) {
	    modify_row_node_cats(cgm.params.new_row_cats, new_network_data.row_nodes);
	    new_row_cats = cgm.params.new_row_cats;
	    cgm.params.new_row_cats = new_row_cats;
	    // do not preserve the updated (row) cats
	    var predefined_cat_colors = true;
	    cgm.params.viz = make_cat_params(cgm.params, cgm.params.viz, predefined_cat_colors);
	  }

	  tmp_config.network_data = new_network_data;
	  tmp_config.inst_order = cgm.params.viz.inst_order;
	  tmp_config.input_domain = cgm.params.matrix.opacity_scale.domain()[1];

	  update_reorder_buttons(tmp_config, cgm.params);

	  // tmp_config.ini_expand = false;
	  tmp_config.ini_view = null;
	  tmp_config.current_col_cat = cgm.params.current_col_cat;

	  // disabled, causing problems when cropping
	  // always preserve category colors when updating
	  tmp_config.cat_colors = cgm.params.viz.cat_colors;

	  var new_params = make_params(tmp_config);

	  // this function is sensitive to further updates, so run here
	  var delays = define_enter_exit_delays(cgm.params, new_params);

	  // pass the newly calcluated params back to the cgm object
	  cgm.params = new_params;

	  // set up zoom
	  cgm.params.zoom_behavior = d3.behavior.zoom().scaleExtent([1, cgm.params.viz.square_zoom * cgm.params.viz.zoom_ratio.x]).on('zoom', function () {
	    run_zoom(cgm);
	  });

	  // have persistent group levels while updating
	  cgm.params.group_level = inst_group_level;

	  // have persistent crop_filter_nodes while updating
	  cgm.params.crop_filter_nodes = inst_crop_fitler;

	  // only run enter-exit-updates if there is no downsampling
	  if (cgm.params.viz.ds_num_levels === 0) {
	    // new_network_data is necessary
	    enter_exit_update(cgm, new_network_data, delays);
	  } else {
	    ds_enter_exit_update(cgm);
	  }

	  // reduce opacity during update
	  d3.select(cgm.params.viz.viz_svg).style('opacity', 0.70);

	  make_row_cat(cgm);
	  make_row_cat_super_labels(cgm);

	  if (cgm.params.viz.show_categories.col) {
	    make_col_cat(cgm);
	  }

	  if (cgm.params.viz.show_dendrogram) {
	    make_row_dendro(cgm);
	    make_col_dendro(cgm);
	  }

	  initialize_resizing(cgm);

	  d3.select(cgm.params.viz.viz_svg).call(cgm.params.zoom_behavior);

	  ini_doubleclick(cgm);

	  ini_sidebar(cgm);

	  cgm.params.viz.run_trans = true;

	  // d3.selectAll(cgm.params.viz.root_tips)
	  //   .style('opacity',0);

	  setTimeout(enable_sidebar, 2500, cgm.params);

	  // remove all dendro shadows
	  setTimeout(remove_shadows, 50);
	  setTimeout(remove_shadows, 100);
	  setTimeout(remove_shadows, 500);
	  setTimeout(remove_shadows, 1000);
	  setTimeout(remove_shadows, 1500);

	  function remove_shadows() {
	    d3.selectAll('.dendro_shadow').remove();
	  }

	  function finish_update() {
	    d3.select(cgm.params.viz.viz_svg).transition().duration(250).style('opacity', 1.0);

	    setTimeout(finish_update_class, 1000);
	  }

	  setTimeout(finish_update, delays.enter);

	  function finish_update_class() {
	    d3.select(cgm.params.viz.viz_svg).classed('running_update', false);
	  }
		};

/***/ },
/* 180 */
/***/ function(module, exports) {

	module.exports = function (old_params, params) {

	  // exit, update, enter

	  // check if exit or enter or both are required
	  var old_row_nodes = old_params.network_data.row_nodes;
	  var old_col_nodes = old_params.network_data.col_nodes;
	  var old_row = _.map(old_row_nodes, function (d) {
	    return d.name;
	  });
	  var old_col = _.map(old_col_nodes, function (d) {
	    return d.name;
	  });
	  var all_old_nodes = old_row.concat(old_col);

	  var row_nodes = params.network_data.row_nodes;
	  var col_nodes = params.network_data.col_nodes;
	  var row = _.map(row_nodes, function (d) {
	    return d.name;
	  });
	  var col = _.map(col_nodes, function (d) {
	    return d.name;
	  });
	  var all_nodes = row.concat(col);

	  var exit_nodes = _.difference(all_old_nodes, all_nodes).length;
	  var enter_nodes = _.difference(all_nodes, all_old_nodes).length;

	  var delays = {};

	  if (exit_nodes > 0) {
	    delays.update = 1000;
	  } else {
	    delays.update = 0;
	  }

	  if (enter_nodes > 0) {
	    delays.enter = 1000;
	  } else {
	    delays.enter = 0;
	  }

	  delays.enter = delays.enter + delays.update;

	  delays.run_transition = true;

	  var old_num_links = old_params.network_data.links.length;
	  var new_num_links = params.network_data.links.length;
	  var cutoff_num_links = 0.5 * params.matrix.def_large_matrix;

	  if (old_num_links > cutoff_num_links || new_num_links > cutoff_num_links) {
	    delays.run_transition = false;
	    delays.update = 0;
	    delays.enter = 0;
	  }

	  return delays;
	};

/***/ },
/* 181 */
/***/ function(module, exports, __webpack_require__) {

	var reset_size_after_update = __webpack_require__(182);
	var make_row_label_container = __webpack_require__(49);
	var make_col_label_container = __webpack_require__(103);
	var eeu_existing_row = __webpack_require__(183);
	var exit_components = __webpack_require__(187);
	var draw_gridlines = __webpack_require__(39);
	var enter_row_groups = __webpack_require__(188);
	var resize_containers = __webpack_require__(191);
	var label_constrain_and_trim = __webpack_require__(117);
	var d3_tip_custom = __webpack_require__(48);

	module.exports = function enter_exit_update(cgm, network_data, delays) {

	  var params = cgm.params;

	  // remove old tooltips
	  d3.selectAll(params.viz.root_tips).remove();

	  // d3-tooltip - for tiles
	  var tip = d3_tip_custom().attr('class', function () {
	    var root_tip_selector = params.viz.root_tips.replace('.', '');
	    var class_string = root_tip_selector + ' d3-tip ' + root_tip_selector + '_tile_tip';
	    return class_string;
	  }).direction('nw').offset([0, 0]).style('display', 'none').html(function (d) {
	    var inst_value = String(d.value.toFixed(3));
	    var tooltip_string;

	    if (params.keep_orig) {
	      var orig_value = String(d.value_orig.toFixed(3));
	      tooltip_string = '<p>' + d.row_name + ' and ' + d.col_name + '</p>' + '<p> normalized value: ' + inst_value + '</p>' + '<div> original value: ' + orig_value + '</div>';
	    } else {
	      tooltip_string = '<p>' + d.row_name + ' and ' + d.col_name + '</p>' + '<div> value: ' + inst_value + '</div>';
	    }

	    return tooltip_string;
	  });

	  d3.select(params.root + ' .clust_group').call(tip);

	  // necessary for repositioning clust, col and col-cat containers
	  resize_containers(params);

	  var duration = 1000;

	  // make global so that names can be accessed
	  var row_nodes = network_data.row_nodes;
	  var col_nodes = network_data.col_nodes;
	  var links = network_data.links;

	  //
	  var tile_data = links;

	  // add name to links for object constancy
	  for (var i = 0; i < tile_data.length; i++) {
	    var d = tile_data[i];
	    tile_data[i].name = row_nodes[d.source].name + '_' + col_nodes[d.target].name;
	  }

	  // move rows
	  var move_rows = d3.select(params.root + ' .clust_group').selectAll('.row').data(params.matrix.matrix, function (d) {
	    return d.name;
	  });

	  if (delays.run_transition) {
	    move_rows.transition().delay(delays.update).duration(duration).attr('transform', function (d) {
	      var tmp_index = d.row_index;
	      return 'translate(0,' + params.viz.y_scale(tmp_index) + ')';
	    });
	  } else {
	    move_rows.attr('transform', function (d) {
	      var tmp_index = d.row_index;
	      return 'translate(0,' + params.viz.y_scale(tmp_index) + ')';
	    });
	  }

	  // update existing rows - enter, exit, update tiles in existing row
	  d3.select(params.root + ' .clust_group').selectAll('.row').each(function (d) {
	    // TODO add tip back to arguments
	    var inst_selection = this;
	    eeu_existing_row(params, d, delays, duration, inst_selection, tip);
	  });

	  d3.selectAll(params.root + ' .horz_lines').remove();
	  d3.selectAll(params.root + ' .vert_lines').remove();

	  // exit
	  ////////////
	  exit_components(params, delays, duration);

	  // resize clust components using appropriate delays
	  reset_size_after_update(cgm, duration, delays);

	  // enter new elements
	  //////////////////////////
	  enter_row_groups(params, delays, duration, tip);

	  // update existing rows
	  make_row_label_container(cgm, duration);
	  make_col_label_container(cgm, duration);

	  draw_gridlines(params, delays, duration);

	  setTimeout(label_constrain_and_trim, 2000, params);
		};

/***/ },
/* 182 */
/***/ function(module, exports, __webpack_require__) {

	var utils = __webpack_require__(2);
	var calc_clust_height = __webpack_require__(22);
	var get_svg_dim = __webpack_require__(19);
	var calc_clust_width = __webpack_require__(21);
	var reset_zoom = __webpack_require__(134);
	var resize_dendro = __webpack_require__(135);
	var resize_super_labels = __webpack_require__(136);
	var resize_spillover = __webpack_require__(137);
	var resize_row_labels = __webpack_require__(139);
	var resize_row_viz = __webpack_require__(141);
	var resize_col_labels = __webpack_require__(142);
	var resize_col_text = __webpack_require__(143);
	var resize_col_triangle = __webpack_require__(144);
	var resize_col_hlight = __webpack_require__(145);
	var resize_label_bars = __webpack_require__(148);
	var calc_default_fs = __webpack_require__(31);
	var calc_zoom_switching = __webpack_require__(30);
	// var show_visible_area = require('../zoom/show_visible_area');
	var ini_zoom_info = __webpack_require__(36);

	module.exports = function reset_size_after_update(cgm, duration = 0, delays = null) {

	  if (delays === null) {
	    delays = {};
	    delays.enter = 0;
	    delays.update = 0;
	    delays.run_transition = false;
	  }

	  var params = cgm.params;

	  var row_nodes = cgm.params.network_data.row_nodes;

	  params.zoom_info = ini_zoom_info();

	  // // not sure if this is necessary
	  // ////////////////////////////
	  // show_visible_area(params);
	  // // quick fix for column filtering
	  // setTimeout(show_visible_area, 2200, cgm);

	  var row_nodes_names = params.network_data.row_nodes_names;

	  reset_zoom(params);

	  // Resetting some visualization parameters
	  params = get_svg_dim(params);
	  params.viz = calc_clust_width(params.viz);
	  params.viz = calc_clust_height(params.viz);

	  if (params.sim_mat) {
	    if (params.viz.clust.dim.width <= params.viz.clust.dim.height) {
	      params.viz.clust.dim.height = params.viz.clust.dim.width;
	    } else {
	      params.viz.clust.dim.width = params.viz.clust.dim.height;
	    }
	  }

	  params.viz = calc_zoom_switching(params.viz);

	  // redefine x_scale and y_scale rangeBands
	  params.viz.x_scale.rangeBands([0, params.viz.clust.dim.width]);
	  params.viz.y_scale.rangeBands([0, params.viz.clust.dim.height]);

	  // redefine zoom extent
	  params.viz.square_zoom = params.viz.norm_labels.width.col / (params.viz.x_scale.rangeBand() / 2);
	  params.zoom_behavior.scaleExtent([1, params.viz.square_zoom * params.viz.zoom_ratio.x]);

	  // redefine border width
	  params.viz.border_width.x = params.viz.x_scale.rangeBand() / params.viz.border_fraction;
	  params.viz.border_width.y = params.viz.y_scale.rangeBand() / params.viz.border_fraction;

	  params = calc_default_fs(params);

	  // resize the svg
	  ///////////////////////
	  var svg_group = d3.select(params.viz.viz_wrapper).select('svg');

	  svg_group.select(params.root + ' .grey_background').transition().delay(delays.update).duration(duration).attr('width', params.viz.clust.dim.width).attr('height', params.viz.clust.dim.height);

	  resize_row_labels(params, svg_group, delays);

	  // do not delay the font size change since this will break the bounding box calc
	  svg_group.selectAll('.row_label_group').select('text').style('font-size', params.labels.default_fs_row + 'px').text(function (d) {
	    return utils.normal_name(d);
	  });

	  // change the size of the highlighting rects
	  svg_group.selectAll('.row_label_group').each(function () {
	    var bbox = d3.select(this).select('text')[0][0].getBBox();
	    d3.select(this).select('rect').attr('x', bbox.x).attr('y', 0).attr('width', bbox.width).attr('height', params.viz.y_scale.rangeBand()).style('fill', 'yellow').style('opacity', function (d) {
	      var inst_opacity = 0;
	      // highlight target genes
	      if (d.target === 1) {
	        inst_opacity = 1;
	      }
	      return inst_opacity;
	    });
	  });

	  resize_row_viz(params, svg_group, delays);

	  if (delays.run_transition) {

	    // positioning row text after row text size may have been reduced
	    svg_group.selectAll('.row_label_group').select('text').transition().delay(delays.update).duration(duration).attr('y', params.viz.rect_height * 0.5 + params.labels.default_fs_row * 0.35);

	    svg_group.selectAll('.row_cat_group').data(row_nodes, function (d) {
	      return d.name;
	    }).transition().delay(delays.update).duration(duration).attr('transform', function (d) {
	      var inst_index = _.indexOf(row_nodes_names, d.name);
	      return 'translate(0, ' + params.viz.y_scale(inst_index) + ')';
	    });

	    svg_group.selectAll('.row_cat_group').select('path').transition().delay(delays.update).duration(duration).attr('d', function () {
	      var origin_x = params.viz.cat_room.symbol_width - 1;
	      var origin_y = 0;
	      var mid_x = 1;
	      var mid_y = params.viz.y_scale.rangeBand() / 2;
	      var final_x = params.viz.cat_room.symbol_width - 1;
	      var final_y = params.viz.y_scale.rangeBand();
	      var output_string = 'M ' + origin_x + ',' + origin_y + ' L ' + mid_x + ',' + mid_y + ', L ' + final_x + ',' + final_y + ' Z';
	      return output_string;
	    });

	    svg_group.selectAll('.row_dendro_group').data(row_nodes, function (d) {
	      return d.name;
	    }).transition().delay(delays.update).duration(duration).attr('transform', function (d) {
	      var inst_index = _.indexOf(row_nodes_names, d.name);
	      return 'translate(0, ' + params.viz.y_scale(inst_index) + ')';
	    });
	  } else {

	    // positioning row text after row text size may have been reduced
	    svg_group.selectAll('.row_label_group').select('text').attr('y', params.viz.rect_height * 0.5 + params.labels.default_fs_row * 0.35);

	    svg_group.selectAll('.row_cat_group').data(row_nodes, function (d) {
	      return d.name;
	    }).attr('transform', function (d) {
	      var inst_index = _.indexOf(row_nodes_names, d.name);
	      return 'translate(0, ' + params.viz.y_scale(inst_index) + ')';
	    });

	    svg_group.selectAll('.row_cat_group').select('path').attr('d', function () {
	      var origin_x = params.viz.cat_room.symbol_width - 1;
	      var origin_y = 0;
	      var mid_x = 1;
	      var mid_y = params.viz.y_scale.rangeBand() / 2;
	      var final_x = params.viz.cat_room.symbol_width - 1;
	      var final_y = params.viz.y_scale.rangeBand();
	      var output_string = 'M ' + origin_x + ',' + origin_y + ' L ' + mid_x + ',' + mid_y + ', L ' + final_x + ',' + final_y + ' Z';
	      return output_string;
	    });

	    svg_group.selectAll('.row_dendro_group').data(row_nodes, function (d) {
	      return d.name;
	    }).attr('transform', function (d) {
	      var inst_index = _.indexOf(row_nodes_names, d.name);
	      return 'translate(0, ' + params.viz.y_scale(inst_index) + ')';
	    });
	  }

	  if (utils.has(params.network_data.row_nodes[0], 'value')) {

	    resize_label_bars(cgm, svg_group);
	  }

	  // resize col labels
	  ///////////////////////
	  // reduce width of rotated rects

	  resize_col_labels(params, svg_group, delays);
	  resize_col_text(params, svg_group);
	  resize_col_triangle(params, svg_group, delays);

	  resize_col_hlight(params, svg_group, delays);

	  resize_dendro(params, svg_group, delays);
	  resize_super_labels(params, svg_group, delays);
	  resize_spillover(params.viz, svg_group, delays);

	  // reset zoom and translate
	  params.zoom_behavior.scale(1).translate([params.viz.clust.margin.left, params.viz.clust.margin.top]);
		};

/***/ },
/* 183 */
/***/ function(module, exports, __webpack_require__) {

	var exit_existing_row = __webpack_require__(184);
	var enter_existing_row = __webpack_require__(185);
	var update_split_tiles = __webpack_require__(186);
	var mouseover_tile = __webpack_require__(45);
	var mouseout_tile = __webpack_require__(46);
	var fine_position_tile = __webpack_require__(47);

	// TODO add tip back to arguments
	module.exports = function eeu_existing_row(params, ini_inp_row_data, delays, duration, row_selection, tip) {

	  var inp_row_data = ini_inp_row_data.row_data;

	  // remove zero values from
	  var row_values = _.filter(inp_row_data, function (num) {
	    return num.value != 0;
	  });

	  // bind data to tiles
	  var cur_row_tiles = d3.select(row_selection).selectAll('.tile').data(row_values, function (d) {
	    return d.col_name;
	  });

	  exit_existing_row(params, delays, cur_row_tiles, inp_row_data, row_selection);

	  ///////////////////////////
	  // Update
	  ///////////////////////////

	  // update tiles in x direction
	  var update_row_tiles = cur_row_tiles.on('mouseover', function (...args) {
	    mouseover_tile(params, this, tip, args);
	  }).on('mouseout', function mouseout() {
	    mouseout_tile(params, this, tip);
	  });

	  var col_nodes_names = params.network_data.col_nodes_names;

	  if (delays.run_transition) {

	    update_row_tiles.transition().delay(delays.update).duration(duration).attr('width', params.viz.rect_width).attr('height', params.viz.rect_height).attr('transform', function (d) {
	      if (_.contains(col_nodes_names, d.col_name)) {
	        return fine_position_tile(params, d);
	      } else {
	        return 'translate(0,0)';
	      }
	    });
	  } else {
	    update_row_tiles.attr('width', params.viz.rect_width).attr('height', params.viz.rect_height).attr('transform', function (d) {
	      if (_.contains(col_nodes_names, d.col_name)) {
	        return fine_position_tile(params, d);
	      } else {
	        return 'translate(0,0)';
	      }
	    });
	  }

	  if (params.matrix.tile_type == 'updn') {
	    update_split_tiles(params, inp_row_data, row_selection, delays, duration, cur_row_tiles, tip);
	  }

	  enter_existing_row(params, delays, duration, cur_row_tiles, tip);
		};

/***/ },
/* 184 */
/***/ function(module, exports) {

	module.exports = function exit_existing_row(params, delays, cur_row_tiles, inp_row_data, row_selection) {

	  if (delays.run_transition) {
	    cur_row_tiles.exit().transition().duration(300).attr('fill-opacity', 0).remove();
	  } else {
	    cur_row_tiles.exit().attr('fill-opacity', 0).remove();
	  }

	  if (params.matrix.tile_type == 'updn') {

	    // value split
	    var row_split_data = _.filter(inp_row_data, function (num) {
	      return num.value_up != 0 || num.value_dn != 0;
	    });

	    // tile_up
	    var cur_tiles_up = d3.select(row_selection).selectAll('.tile_up').data(row_split_data, function (d) {
	      return d.col_name;
	    });

	    if (delays.run_transition) {
	      cur_tiles_up.exit().transition().duration(300).attr('fill', '0').remove();
	    } else {
	      cur_tiles_up.exit().attr('fill', 0).remove();
	    }

	    // tile_dn
	    var cur_tiles_dn = d3.select(row_selection).selectAll('.tile_dn').data(row_split_data, function (d) {
	      return d.col_name;
	    });

	    if (delays.run_transition) {
	      cur_tiles_dn.exit().transition().duration(300).attr('fill', 0).remove();
	    } else {
	      cur_tiles_dn.exit().attr('fill', 0).remove();
	    }
	  }
		};

/***/ },
/* 185 */
/***/ function(module, exports, __webpack_require__) {

	var mouseover_tile = __webpack_require__(45);
	var mouseout_tile = __webpack_require__(46);
	var fine_position_tile = __webpack_require__(47);

	module.exports = function enter_existing_row(params, delays, duration, cur_row_tiles, tip) {

	  // enter new tiles
	  var new_tiles = cur_row_tiles.enter().append('rect').attr('class', 'tile row_tile').attr('width', params.viz.rect_width).attr('height', params.viz.rect_height).on('mouseover', function (...args) {
	    mouseover_tile(params, this, tip, args);
	  }).on('mouseout', function mouseout() {
	    mouseout_tile(params, this, tip);
	  }).attr('fill-opacity', 0).attr('transform', function (d) {
	    return fine_position_tile(params, d);
	  });

	  if (delays.run_transition) {
	    new_tiles.transition().delay(delays.enter).duration(duration).style('fill', function (d) {
	      return d.value > params.matrix.mid_val ? params.matrix.tile_colors[0] : params.matrix.tile_colors[1];
	    }).attr('fill-opacity', function (d) {
				var op_val = 0, output_opacity = 0;
				op_val = params.matrix.mid_val + Math.abs(d.value - params.matrix.mid_val);
	      output_opacity = params.matrix.opacity_scale(op_val);
	      return output_opacity;
	    });
	  } else {
	    new_tiles.style('fill', function (d) {
	      return d.value > params.matrix.mid_val ? params.matrix.tile_colors[0] : params.matrix.tile_colors[1];
	    }).attr('fill-opacity', function (d) {
				var op_val = 0, output_opacity = 0;
				op_val = params.matrix.mid_val + Math.abs(d.value - params.matrix.mid_val);
	      output_opacity = params.matrix.opacity_scale(Math.abs(op_val));
	      return output_opacity;
	    });
	  }

	  // remove new tiles if necessary
	  new_tiles.each(function (d) {
	    if (Math.abs(d.value_up) > 0 && Math.abs(d.value_dn) > 0) {
	      d3.select(this).remove();
	    }
	  });
	};

/***/ },
/* 186 */
/***/ function(module, exports, __webpack_require__) {

	var draw_up_tile = __webpack_require__(43);
	var draw_dn_tile = __webpack_require__(44);
	var mouseover_tile = __webpack_require__(45);
	var mouseout_tile = __webpack_require__(46);
	var fine_position_tile = __webpack_require__(47);

	module.exports = function update_split_tiles(params, inp_row_data, row_selection, delays, duration, cur_row_tiles, tip) {

	  // value split
	  var row_split_data = _.filter(inp_row_data, function (num) {
	    return num.value_up != 0 || num.value_dn != 0;
	  });

	  // tile_up
	  var cur_tiles_up = d3.select(row_selection).selectAll('.tile_up').data(row_split_data, function (d) {
	    return d.col_name;
	  });

	  // update split tiles_up
	  var update_tiles_up = cur_tiles_up.on('mouseover', function (...args) {
	    mouseover_tile(params, this, tip, args);
	  }).on('mouseout', function mouseout() {
	    mouseout_tile(params, this, tip);
	  });

	  if (delays.run_transition) {
	    update_tiles_up.transition().delay(delays.update).duration(duration).attr('d', function () {
	      return draw_up_tile(params);
	    }).attr('transform', function (d) {
	      return fine_position_tile(params, d);
	    });
	  } else {
	    update_tiles_up.attr('d', function () {
	      return draw_up_tile(params);
	    }).attr('transform', function (d) {
	      return fine_position_tile(params, d);
	    });
	  }

	  // tile_dn
	  var cur_tiles_dn = d3.select(row_selection).selectAll('.tile_dn').data(row_split_data, function (d) {
	    return d.col_name;
	  });

	  // update split tiles_dn
	  var update_tiles_dn = cur_tiles_dn.on('mouseover', function (...args) {
	    mouseover_tile(params, this, tip, args);
	  }).on('mouseout', function mouseout() {
	    mouseout_tile(params, this, tip);
	  });

	  if (delays.run_transition) {
	    update_tiles_dn.transition().delay(delays.update).duration(duration).attr('d', function () {
	      return draw_dn_tile(params);
	    }).attr('transform', function (d) {
	      return fine_position_tile(params, d);
	    });
	  } else {
	    update_tiles_dn.attr('d', function () {
	      return draw_dn_tile(params);
	    }).attr('transform', function (d) {
	      return fine_position_tile(params, d);
	    });
	  }

	  // remove tiles when splitting is done
	  cur_row_tiles.selectAll('.tile').each(function (d) {
	    if (Math.abs(d.value_up) > 0 && Math.abs(d.value_dn) > 0) {
	      d3.select(this).remove();
	    }
	  });
	};

/***/ },
/* 187 */
/***/ function(module, exports) {

	module.exports = function exit_components(params, delays, duration) {

	  var row_nodes = params.network_data.row_nodes;
	  var col_nodes = params.network_data.col_nodes;

	  // remove entire rows
	  var exiting_rows = d3.select(params.root + ' .clust_group').selectAll('.row').data(params.matrix.matrix, function (d) {
	    return d.name;
	  }).exit();

	  if (delays.run_transition) {
	    exiting_rows.transition().duration(duration).style('opacity', 0).remove();
	  } else {
	    exiting_rows.style('opacity', 0).remove();
	  }

	  // remove row labels
	  d3.selectAll(params.root + ' .row_label_group').data(row_nodes, function (d) {
	    return d.name;
	  }).exit().transition().duration(duration).style('opacity', 0).remove();

	  // remove column labels
	  d3.selectAll(params.root + ' .col_label_group').data(col_nodes, function (d) {
	    return d.name;
	  }).exit().transition().duration(duration).style('opacity', 0).remove();

	  // remove row triangles and colorbars
	  d3.selectAll(params.root + ' .row_cat_group').data(row_nodes, function (d) {
	    return d.name;
	  }).exit().transition().duration(duration).style('opacity', 0).remove();

	  // remove row triangles and colorbars
	  d3.selectAll(params.root + ' .row_dendro_group').data(row_nodes, function (d) {
	    return d.name;
	  }).exit().transition().duration(duration).style('opacity', 0).remove();

	  d3.selectAll(params.root + ' .col_label_text').data(col_nodes, function (d) {
	    return d.name;
	  }).exit().transition().duration(duration).style('opacity', 0).remove();

	  d3.selectAll(params.root + ' .horz_lines').data(row_nodes, function (d) {
	    return d.name;
	  }).exit().transition().duration(duration).style('opacity', 0).remove();

	  d3.selectAll(params.root + ' .vert_lines').data(col_nodes, function (d) {
	    return d.name;
	  }).exit().transition().duration(duration).style('opacity', 0).remove();

	  // remove dendrogram
	  d3.selectAll(params.root + ' .col_cat_group').data(col_nodes, function (d) {
	    return d.name;
	  }).exit().transition().duration(duration).style('opacity', 0).remove();

	  d3.selectAll(params.root + ' .col_dendro_group').data(col_nodes, function (d) {
	    return d.name;
	  }).exit().transition().duration(duration).style('opacity', 0).remove();
		};

/***/ },
/* 188 */
/***/ function(module, exports, __webpack_require__) {

	var enter_new_rows = __webpack_require__(189);

	module.exports = function enter_row_groups(params, delays, duration, tip) {

	  // enter new rows
	  var new_row_groups = d3.select(params.root + ' .clust_group').selectAll('.row').data(params.matrix.matrix, function (d) {
	    return d.name;
	  }).enter().append('g').classed('row', true).attr('transform', function (d) {
	    return 'translate(0,' + params.viz.y_scale(d.row_index) + ')';
	  });

	  new_row_groups.each(function (d) {
	    enter_new_rows(params, d, delays, duration, tip, this);
	  });
		};

/***/ },
/* 189 */
/***/ function(module, exports, __webpack_require__) {

	var enter_split_tiles = __webpack_require__(190);
	var mouseover_tile = __webpack_require__(45);
	var mouseout_tile = __webpack_require__(46);
	var fine_position_tile = __webpack_require__(47);

	// make each row in the clustergram
	module.exports = function enter_new_rows(params, ini_inp_row_data, delays, duration, tip, row_selection) {

	  var inp_row_data = ini_inp_row_data.row_data;

	  // remove zero values to make visualization faster
	  var row_data = _.filter(inp_row_data, function (num) {
	    return num.value !== 0;
	  });

	  // update tiles
	  ////////////////////////////////////////////
	  var tile = d3.select(row_selection).selectAll('rect').data(row_data, function (d) {
	    return d.col_name;
	  }).enter().append('rect').attr('class', 'tile row_tile').attr('width', params.viz.rect_width).attr('height', params.viz.rect_height)
	  // switch the color based on up/dn value
	  .style('fill', function (d) {
	    return d.value > params.matrix.mid_val ? params.matrix.tile_colors[0] : params.matrix.tile_colors[1];
	  }).on('mouseover', function (...args) {
	    mouseover_tile(params, this, tip, args);
	  }).on('mouseout', function mouseout() {
	    mouseout_tile(params, this, tip);
	  });

	  tile.style('fill-opacity', 0).transition().delay(delays.enter).duration(duration).style('fill-opacity', function (d) {
	    // calculate output opacity using the opacity scale
			var op_val = 0, output_opacity = 0;
			op_val = params.matrix.mid_val + Math.abs(d.value - params.matrix.mid_val);
			output_opacity = params.matrix.opacity_scale(Math.abs(op_val));
	    return output_opacity;
	  });

	  tile.attr('transform', function (d) {
	    return fine_position_tile(params, d);
	  });

	  if (params.matrix.tile_type == 'updn') {
	    enter_split_tiles(params, inp_row_data, row_selection, tip, delays, duration, tile);
	  }
		};

/***/ },
/* 190 */
/***/ function(module, exports, __webpack_require__) {

	var draw_up_tile = __webpack_require__(43);
	var draw_dn_tile = __webpack_require__(44);
	var fine_position_tile = __webpack_require__(47);

	module.exports = function enter_split_tiles(params, inp_row_data, row_selection, tip, delays, duration, tile) {

	  // value split
	  var row_split_data = _.filter(inp_row_data, function (num) {
	    return num.value_up != 0 || num.value_dn != 0;
	  });

	  // tile_up
	  var new_tiles_up = d3.select(row_selection).selectAll('.tile_up').data(row_split_data, function (d) {
	    return d.col_name;
	  }).enter().append('path').attr('class', 'tile_up').attr('d', function () {
	    return draw_up_tile(params);
	  }).attr('transform', function (d) {
	    return fine_position_tile(params, d);
	  }).style('fill', function () {
	    return params.matrix.tile_colors[0];
	  }).on('mouseover', function (p) {
	    // highlight row - set text to active if
	    d3.selectAll(params.root + ' .row_label_group text').classed('active', function (d) {
	      return p.row_name === d.name;
	    });

	    d3.selectAll(params.root + ' .col_label_text text').classed('active', function (d) {
	      return p.col_name === d.name;
	    });
	    if (params.matrix.show_tile_tooltips) {
	      tip.show(p);
	    }
	  }).on('mouseout', function () {
	    d3.selectAll(params.root + ' text').classed('active', false);
	    if (params.matrix.show_tile_tooltips) {
	      tip.hide();
	    }
	  });

	  new_tiles_up.style('fill-opacity', 0).transition().delay(delays.enter).duration(duration).style('fill-opacity', function (d) {
	    var inst_opacity = 0;
	    if (Math.abs(d.value_dn) > 0) {
				var op_val = params.matrix.mid_val + Math.abs(d.value_up - params.matrix.mid_val);
	      inst_opacity = params.matrix.opacity_scale(op_val);
	    }
	    return inst_opacity;
	  });

	  // tile_dn
	  var new_tiles_dn = d3.select(row_selection).selectAll('.tile_dn').data(row_split_data, function (d) {
	    return d.col_name;
	  }).enter().append('path').attr('class', 'tile_dn').attr('d', function () {
	    return draw_dn_tile(params);
	  }).attr('transform', function (d) {
	    return fine_position_tile(params, d);
	  }).style('fill', function () {
	    return params.matrix.tile_colors[1];
	  }).on('mouseover', function (p) {
	    // highlight row - set text to active if
	    d3.selectAll(params.root + ' .row_label_group text').classed('active', function (d) {
	      return p.row_name === d.name;
	    });

	    d3.selectAll(params.root + ' .col_label_text text').classed('active', function (d) {
	      return p.col_name === d.name;
	    });
	    if (params.matrix.show_tile_tooltips) {
	      tip.show(p);
	    }
	  }).on('mouseout', function () {
	    d3.selectAll(params.root + ' text').classed('active', false);
	    if (params.matrix.show_tile_tooltips) {
	      tip.hide();
	    }
	  });

	  new_tiles_dn.style('fill-opacity', 0).transition().delay(delays.enter).duration(duration).style('fill-opacity', function (d) {
	    var inst_opacity = 0;
	    if (Math.abs(d.value_up) > 0) {
				var op_val = params.matrix.mid_val + Math.abs(d.value_dn - params.matrix.mid_val);
	      inst_opacity = params.matrix.opacity_scale(op_val);
	    }
	    return inst_opacity;
	  });

	  // remove tiles when splitting is done
	  tile.each(function (d) {
	    if (Math.abs(d.value_up) > 0 && Math.abs(d.value_dn) > 0) {
	      d3.select(this).remove();
	    }
	  });
		};

/***/ },
/* 191 */
/***/ function(module, exports) {

	module.exports = function resize_containers(params) {

	  // reposition matrix
	  d3.select(params.root + ' .clust_container').attr('transform', 'translate(' + params.viz.clust.margin.left + ',' + params.viz.clust.margin.top + ')');

	  // reposition col container
	  d3.select(params.root + ' .col_label_outer_container').attr('transform', 'translate(0,' + params.viz.norm_labels.width.col + ')');

	  // reposition col_viz container
	  d3.select(params.root + ' .col_cat_outer_container').attr('transform', function () {
	    var inst_offset = params.viz.norm_labels.width.col + 2;
	    return 'translate(0,' + inst_offset + ')';
	  });
		};

/***/ },
/* 192 */
/***/ function(module, exports, __webpack_require__) {

	/* eslint-disable */

	var change_groups = __webpack_require__(163);
	var all_reorder = __webpack_require__(115);
	var ini_cat_reorder = __webpack_require__(114);
	var run_row_search = __webpack_require__(193);

	module.exports = function ini_sidebar(cgm) {

	  var params = cgm.params;

	  var input = d3.select(params.root + ' .gene_search_box')[0][0];
	  var awesomplete = new Awesomplete(input, { minChars: 1, maxItems: 15 });
	  var entities = cgm.params.network_data.row_nodes_names;
	  awesomplete.list = entities;

	  // position awesomplete list elements above other elements in the page
	  d3.selectAll('.awesomplete ul').style('z-index', 99);

	  // submit genes button
	  $(params.root + ' .gene_search_box').keyup(function (e) {
	    if (e.keyCode === 13) {
	      var search_gene = $(params.root + ' .gene_search_box').val();
	      run_row_search(cgm, search_gene, entities);
	    }
	  });

	  $(params.root + ' .submit_gene_button').off().click(function () {
	    var search_gene = $(params.root + ' .gene_search_box').val();
	    run_row_search(cgm, search_gene, entities);
	  });

	  var reorder_types;
	  if (params.sim_mat) {
	    reorder_types = ['both'];
	  } else {
	    reorder_types = ['row', 'col'];
	  }

	  _.each(reorder_types, function (inst_rc) {

	    // reorder buttons
	    $(params.root + ' .toggle_' + inst_rc + '_order .btn').off().click(function (evt) {

	      var order_id = $(evt.target).attr('name').replace('_row', '').replace('_col', '');

	      d3.selectAll(params.root + ' .toggle_' + inst_rc + '_order .btn').classed('active', false);

	      d3.select(this).classed('active', true);

	      if (inst_rc != 'both') {
	        all_reorder(cgm, order_id, inst_rc);
	      } else {
	        all_reorder(cgm, order_id, 'row');
	        all_reorder(cgm, order_id, 'col');
	      }
	    });
	  });

	  ini_cat_reorder(cgm);

	  // Opacity Slider
	  //////////////////////////////////////////////////////////////////////
	  if (d3.select(cgm.params.root + ' .opacity_slider').select('#handle-one').empty()) {

	    var slider_fun = d3.slider().snap(true).value(1).min(0.1).max(1.9).step(0.1).on('slide', function (evt, value) {
	      run_on_opacity_slide(evt, value);
	    });

	    d3.select(cgm.params.root + ' .opacity_slider').call(slider_fun);
	  }

	  function run_on_dendro_slide(evt, value, inst_rc) {
	    $("#amount").val("$" + value);
	    var inst_index = value * 10;
	    // var inst_rc;

	    if (inst_rc != 'both') {
	      change_groups(cgm, inst_rc, inst_index);
	    } else {
	      change_groups(cgm, 'row', inst_index);
	      change_groups(cgm, 'col', inst_index);
	    }
	  }

	  function run_on_opacity_slide(evt, value) {

	    var inst_index = 2 - value;
	    var scaled_max = cgm.params.matrix.abs_max_val * inst_index;

	    cgm.params.matrix.opacity_scale.domain([0, scaled_max]);

	    d3.selectAll(cgm.params.root + ' .tile').style('fill-opacity', function (d) {
	      // calculate output opacity using the opacity scale
				var op_val = 0, output_opacity = 0;
				op_val = cgm.params.matrix.mid_val + Math.abs(d.value - cgm.params.matrix.mid_val);
	      var output_opacity = cgm.params.matrix.opacity_scale(op_val);
	      return output_opacity;
	    });
	  }
		};

/***/ },
/* 193 */
/***/ function(module, exports, __webpack_require__) {

	var two_translate_zoom = __webpack_require__(116);

	module.exports = function run_row_search(cgm, search_term, entities) {

	  var prop = 'name';

	  if (entities.indexOf(search_term) !== -1) {

	    // unhighlight
	    d3.selectAll(cgm.params.root + ' .row_label_group').select('rect').style('opacity', 0);

	    // calc pan_dy
	    var idx = _.indexOf(entities, search_term);
	    var inst_y_pos = cgm.params.viz.y_scale(idx);
	    var pan_dy = cgm.params.viz.clust.dim.height / 2 - inst_y_pos;

	    var inst_zoom = cgm.params.viz.zoom_ratio.x;

	    // working on improving zoom behavior
	    ///////////////////////////////////////////////////
	    ///////////////////////////////////////////////////

	    // // increase zoom
	    // inst_zoom = 3 * inst_zoom;

	    // // move visualization down less
	    // pan_dy = pan_dy - 5;

	    two_translate_zoom(cgm, 0, pan_dy, inst_zoom);

	    // set y zoom to zoom_switch
	    cgm.params.zoom_info.zoom_y = inst_zoom;

	    // highlight
	    d3.selectAll(cgm.params.root + ' .row_label_group').filter(function (d) {
	      return d[prop] === search_term;
	    }).select('rect').style('opacity', 1);
	  }
		};

/***/ },
/* 194 */
/***/ function(module, exports) {

	module.exports = function enable_sidebar(params) {

	  /* only enable dendrogram sliders if there has been no dendro_filtering */

	  // only enable reordering if params.dendro_filter.row === false
	  if (params.dendro_filter.row === false) {

	    // orders are switched!
	    if (params.viz.inst_order.col === 'clust') {
	      d3.select(params.root + ' .row_slider_group').style('opacity', 1).style('pointer-events', 'all');
	    }
	  }

	  d3.selectAll(params.root + ' .toggle_row_order .btn').attr('disabled', null);

	  if (params.dendro_filter.col === false) {

	    // orders are switched!
	    if (params.viz.inst_order.row === 'clust') {
	      d3.select(params.root + ' .col_slider_group').style('opacity', 1).style('pointer-events', 'all');
	    }
	  }

	  d3.selectAll(params.root + ' .toggle_col_order .btn').attr('disabled', null);

	  d3.selectAll(params.root + ' .gene_search_button .btn').attr('disabled', null);

	  params.viz.run_trans = false;
		};

/***/ },
/* 195 */
/***/ function(module, exports) {

	module.exports = function update_reorder_buttons(tmp_config, params) {
	  _.each(['row', 'col'], function (inst_rc) {

	    var other_rc;
	    if (inst_rc === 'row') {
	      other_rc = 'col';
	    } else {
	      other_rc = 'row';
	    }

	    d3.selectAll(params.root + ' .toggle_' + other_rc + '_order .btn').filter(function () {
	      return d3.select(this).attr('name') === tmp_config.inst_order[inst_rc];
	    }).classed('active', true);
	  });
	};

/***/ },
/* 196 */
/***/ function(module, exports, __webpack_require__) {

	var remove_node_cats = __webpack_require__(197);
	var utils = __webpack_require__(2);

	module.exports = function modify_row_node_cats(cat_data, inst_nodes, strip_names = false) {

	  // console.log('MODIFY ROW NODE CATS')
	  // console.log('CAT_DATA')
	  // console.log(cat_data)

	  var cat_type_num = 0;
	  var inst_index = 0;
	  var inst_cat_title;
	  var inst_cats;
	  var inst_members;
	  var inst_name;
	  var inst_category;
	  var inst_cat_name;
	  var inst_full_cat;
	  var inst_cat_num;

	  // loop through row nodes
	  //////////////////////////
	  _.each(inst_nodes, function (inst_node) {

	    inst_name = inst_node.name;

	    // not sure if this is needed
	    // inst_name = inst_name.toUpperCase();

	    if (strip_names === true) {
	      // only consider first part of inst_name
	      ////////////////////////////////////////////
	      // may improve this
	      if (inst_name.indexOf(' ')) {
	        inst_name = inst_name.split(' ')[0];
	      } else if (inst_name.indexOf('_')) {
	        inst_name = inst_name.split('_')[0];
	      }
	    }

	    cat_type_num = 0;

	    remove_node_cats(inst_node);

	    // loop through each category type
	    _.each(cat_data, function (inst_cat_data) {

	      inst_cat_title = inst_cat_data.cat_title;
	      inst_cats = inst_cat_data.cats;

	      // initialize with no category
	      inst_category = 'false';
	      inst_index = -1;

	      inst_cat_num = 0;

	      // loop through each category in the category-type
	      _.each(inst_cats, function (inst_cat) {

	        inst_cat_name = inst_cat.cat_name;
	        inst_members = inst_cat.members;

	        // add category if node is a member
	        if (_.contains(inst_members, inst_name)) {

	          inst_category = inst_cat_name;
	          inst_index = inst_cat_num;
	        }

	        inst_cat_num = inst_cat_num + 1;
	      });

	      if (utils.has(inst_cat_data, 'pval')) {

	        var inst_pval = inst_cat_data.pval.toExponential();
	        inst_full_cat = inst_cat_title + ': ' + inst_category + '<p> Pval ' + String(inst_pval) + '</p>';
	      } else {

	        if (inst_cat_title.indexOf('cat-') === -1) {
	          inst_full_cat = inst_cat_title + ': ' + inst_category;
	        } else {
	          inst_full_cat = inst_category;
	        }
	      }

	      inst_node['cat-' + String(cat_type_num)] = inst_full_cat;
	      inst_node['cat_' + String(cat_type_num) + '_index'] = inst_index;

	      cat_type_num = cat_type_num + 1;
	    });
	  });
		};

/***/ },
/* 197 */
/***/ function(module, exports) {

	module.exports = function remove_node_cats(inst_node) {

	  var all_props = _.keys(inst_node);

	  _.each(all_props, function (inst_prop) {

	    if (inst_prop.indexOf('cat-') > -1) {
	      delete inst_node[inst_prop];
	    }

	    if (inst_prop.indexOf('cat_') > -1) {
	      delete inst_node[inst_prop];
	    }
	  });
		};

/***/ },
/* 198 */
/***/ function(module, exports, __webpack_require__) {

	var reset_size_after_update = __webpack_require__(182);
	var make_col_label_container = __webpack_require__(103);
	var show_visible_area = __webpack_require__(106);
	var resize_containers = __webpack_require__(191);

	module.exports = function ds_enter_exit_update(cgm) {

	  // console.log('======== ds_enter_exit_update ===============');

	  // remove row labels, remove non-downsampled rows, and add downsampled rows
	  d3.selectAll(cgm.params.root + ' .row_cat_group').remove();
	  d3.selectAll(cgm.params.root + ' .row_label_group').remove();
	  d3.selectAll(cgm.params.root + ' .row').remove();

	  // no need to re-calculate the downsampled layers
	  // calc_downsampled_levels(params);
	  var zooming_stopped = true;
	  var zooming_out = true;
	  var make_all_rows = true;

	  // show_visible_area is also run with two_translate_zoom, but at that point
	  // the parameters were not updated and two_translate_zoom if only run
	  // if needed to reset zoom
	  show_visible_area(cgm, zooming_stopped, zooming_out, make_all_rows);

	  make_col_label_container(cgm);

	  var col_nodes = cgm.params.network_data.col_nodes;

	  // remove column labels
	  d3.selectAll(cgm.params.root + ' .col_label_group').data(col_nodes, function (d) {
	    return d.name;
	  }).exit().style('opacity', 0).remove();

	  d3.selectAll(cgm.params.root + ' .col_label_text').data(col_nodes, function (d) {
	    return d.name;
	  }).exit().style('opacity', 0).remove();

	  d3.selectAll(cgm.params.root + ' .col_cat_group').data(col_nodes, function (d) {
	    return d.name;
	  }).exit().style('opacity', 0).remove();

	  d3.selectAll(cgm.params.root + ' .col_dendro_group').data(col_nodes, function (d) {
	    return d.name;
	  }).exit().style('opacity', 0).remove();

	  // necessary for repositioning clust, col and col-cat containers
	  resize_containers(cgm.params);

	  // seeing if this fixes resizing issue
	  var delays = {};
	  delays.enter = 0;
	  delays.update = 0;
	  delays.run_transition = false;
	  var duration = 0;
	  reset_size_after_update(cgm, duration, delays);
		};

/***/ },
/* 199 */
/***/ function(module, exports, __webpack_require__) {

	var sim_click = __webpack_require__(171);

	module.exports = function quick_cluster() {
	  /* eslint-disable */

	  function run(params) {

	    var x_trans = Number(d3.select(params.root + ' .expand_button').attr('x').replace('px', ''));
	    var y_trans = Number(d3.select(params.root + ' .expand_button').attr('y').replace('px', ''));

	    var wait_click = 0;
	    var wait_real_click = 400;
	    setTimeout(sim_click, wait_click, params, 'single', x_trans, y_trans);
	    setTimeout(click_menu_button, wait_real_click, params);

	    setTimeout(reset_cluster_order, 1500, params);
	  }

	  function get_duration() {
	    return 3500;
	  }

	  function click_menu_button(params) {
	    $(params.root + ' .expand_button').d3Click();
	  };

	  function reset_cluster_order(params) {
	    click_reorder_button(params, 'row', 'clust');
	    click_reorder_button(params, 'col', 'clust');
	  }

	  function click_reorder_button(params, inst_rc, inst_order) {
	    var inst_button = d3.selectAll('.toggle_' + inst_rc + '_order .btn').filter(function () {
	      return this.__data__ == inst_order;
	    })[0];

	    $(inst_button).click();
	  }

	  // allows doubleclicking on d3 element
	  jQuery.fn.d3Click = function () {
	    this.each(function (i, e) {
	      var evt = document.createEvent("MouseEvents");
	      evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
	      e.dispatchEvent(evt);
	    });
	  };

	  return {
	    run: run,
	    get_duration: get_duration
	  };
		};

/***/ },
/* 200 */
/***/ function(module, exports, __webpack_require__) {

	var demo_text = __webpack_require__(168);
	var highlight_sidebar_element = __webpack_require__(174);
	var change_groups = __webpack_require__(163);

	module.exports = function play_groups() {
	  /* eslint-disable */

	  function run(params) {

	    var text = 'Identify row and column groups\nof varying sizes using ' + ' the\nsliders and dendrogram';
	    demo_text(params, text, 10000);

	    setTimeout(highlight_sidebar_element, 3000, params, 'slider_col', 7000);

	    setTimeout(change_group_slider, 4000, params, 'row', 3);
	    setTimeout(change_group_slider, 5000, params, 'row', 4);
	    setTimeout(change_group_slider, 6000, params, 'row', 5);
	    setTimeout(change_group_slider, 7000, params, 'row', 6);
	    setTimeout(change_group_slider, 8000, params, 'row', 7);
	    setTimeout(change_group_slider, 9000, params, 'row', 5);
	  }

	  function get_duration() {
	    return 11000;
	  }

	  function change_group_slider(params, inst_rc, inst_value) {
	    $(cgm.params.root + ' .slider_col').slider("value", inst_value / 10);
	    change_groups(cgm, inst_rc, inst_value);
	  }

	  return {
	    run: run,
	    get_duration: get_duration
	  };
		};

/***/ },
/* 201 */
/***/ function(module, exports, __webpack_require__) {

	var demo_text = __webpack_require__(168);
	var sim_click = __webpack_require__(171);

	module.exports = function play_category() {
	  /* eslint-disable */

	  function run(params) {

	    var text = 'Row and column categories\ncan be use to reorder\nby double-clicking';
	    demo_text(params, text, 7000);

	    var inst_element = d3.selectAll(params.root + ' .col_cat_super').filter(function () {
	      return this.__data__ === 'cat-1';
	    })[0];

	    var tmp_pos = d3.select('.col_cat_super').attr('transform');
	    var x_trans = Number(tmp_pos.split('(')[1].split(',')[0].replace(')', '')) + 20;
	    var y_trans = Number(tmp_pos.split(',')[1].replace(')', ''));

	    var wait_click = 4000;
	    setTimeout(sim_click, wait_click, params, 'double', x_trans, y_trans);

	    var wait_reorder = wait_click + 300;
	    setTimeout(fire_double_click_row, wait_reorder, params, inst_element);
	  }

	  function get_duration() {
	    return 8000;
	  }

	  function fire_double_click_row(params, inst_element) {
	    $(inst_element).d3DblClick();
	  }

	  // allows doubleclicking on d3 element
	  jQuery.fn.d3DblClick = function () {
	    this.each(function (i, e) {
	      var evt = document.createEvent("MouseEvents");
	      evt.initMouseEvent("dblclick", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
	      e.dispatchEvent(evt);
	    });
	  };
	  return {
	    run: run,
	    get_duration: get_duration
	  };
		};

/***/ },
/* 202 */
/***/ function(module, exports, __webpack_require__) {

	var demo_text = __webpack_require__(168);
	var toggle_play_button = __webpack_require__(203);

	module.exports = function play_conclusion() {

	  function run(params) {
	    var text_1 = "Clustergrammer is built with gene\nexpression data in mind" + " and interfaces\nwith several Ma'ayan lab web tools";
	    var text_2 = "The example data being visualized is\ngene expression data" + " obtained from the\nCancer Cell Line Encyclopedia";
	    var text_3 = "For more information please view\nthe help documentation";

	    setTimeout(demo_text, 0, params, text_1, 4500);
	    setTimeout(demo_text, 4500, params, text_2, 4500);
	    setTimeout(demo_text, 9000, params, text_3, 4500);

	    setTimeout(reset_demo, 14000, params);
	  }

	  function reset_demo(params) {

	    // prevent more than one demo from running at once
	    d3.select(params.root + ' .play_button').classed('running_demo', false);

	    toggle_play_button(params, true);
	  }

	  function get_duration() {
	    return 12000;
	  }

	  return {
	    run: run,
	    get_duration: get_duration
	  };
		};

/***/ },
/* 203 */
/***/ function(module, exports) {

	module.exports = function toggle_play_button(params, show) {

	  if (show === false) {
	    d3.select(params.root + ' .play_button').transition().duration(500).style('opacity', 0);
	  } else {
	    d3.select(params.root + ' .play_button').transition().duration(500).style('opacity', 1);

	    $.unblockUI();
	  }
		};

/***/ },
/* 204 */
/***/ function(module, exports, __webpack_require__) {

	var demo_text = __webpack_require__(168);
	var sim_click = __webpack_require__(171);

	module.exports = function play_menu_button() {
	  /* eslint-disable */

	  function run(params) {

	    var text = 'View additional controls\nby clicking the menu button';
	    demo_text(params, text, 4000);

	    // var inst_element = get_row_element(params, 'EGFR');

	    // var group_trans = d3.select(inst_element).attr('transform');

	    // var container_trans = d3.select(params.root+' .clust_container')
	    //   .attr('transform')
	    //   .split(',')[1].replace(')','');

	    // var x_trans = params.viz.norm_labels.width.row * 0.9;

	    // var row_trans = group_trans.split(',')[1].replace(')','');
	    // var y_trans = String(Number(row_trans) + Number(container_trans) +
	    //   params.viz.rect_height/2);

	    var x_trans = Number(d3.select(params.root + ' .expand_button').attr('x').replace('px', ''));
	    var y_trans = Number(d3.select(params.root + ' .expand_button').attr('y').replace('px', ''));

	    var wait_click = 3000;
	    var wait_real_click = 3400;
	    setTimeout(sim_click, wait_click, params, 'single', x_trans, y_trans);
	    setTimeout(click_menu_button, wait_real_click, params);
	  }

	  function get_duration() {
	    return 5000;
	  }

	  function click_menu_button(params) {
	    $(params.root + ' .expand_button').d3Click();
	  };

	  function get_row_element(params, inst_row) {

	    var inst_element = d3.selectAll(params.root + ' .row_label_group').filter(function () {
	      var inst_data = this.__data__;
	      return inst_data.name == inst_row;
	    })[0][0];

	    return inst_element;
	  }

	  // allows doubleclicking on d3 element
	  jQuery.fn.d3Click = function () {
	    this.each(function (i, e) {
	      var evt = document.createEvent("MouseEvents");
	      evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
	      e.dispatchEvent(evt);
	    });
	  };

	  // allows doubleclicking on d3 element
	  jQuery.fn.d3DblClick = function () {
	    this.each(function (i, e) {
	      var evt = document.createEvent("MouseEvents");
	      evt.initMouseEvent("dblclick", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
	      e.dispatchEvent(evt);
	    });
	  };
	  return {
	    run: run,
	    get_duration: get_duration
	  };
		};

/***/ },
/* 205 */
/***/ function(module, exports, __webpack_require__) {

	var make_play_button = __webpack_require__(206);
	var make_demo_text_containers = __webpack_require__(207);

	module.exports = function ini_demo() {

	  var cgm = this;
	  var params = cgm.params;

	  make_play_button(cgm);

	  var demo_text_size = 30;
	  make_demo_text_containers(params, demo_text_size);
		};

/***/ },
/* 206 */
/***/ function(module, exports, __webpack_require__) {

	var position_play_button = __webpack_require__(149);

	module.exports = function make_play_button(cgm) {

	  var params = cgm.params;

	  if (d3.select(params.root + ' .play_button').empty()) {

	    var play_button = d3.select(params.root + ' .viz_svg').append('g').classed('play_button', true).classed('running_demo', false);

	    position_play_button(params);

	    play_button.append('circle').style('r', 45).style('fill', 'white').style('stroke', 'black').style('stroke-width', '3px').style('opacity', 0.5);

	    play_button.append('path').attr('d', function () {

	      var tri_w = 40;
	      var tri_h = 22;
	      var tri_offset = 15;

	      return 'M-' + tri_offset + ',-' + tri_h + ' l ' + tri_w + ',' + tri_h + ' l -' + tri_w + ',' + tri_h + ' z ';
	    }).style('fill', 'black').style('opacity', 0.5);

	    // mouseover behavior
	    play_button.on('mouseover', function () {
	      d3.select(this).select('path').style('fill', 'red').style('opacity', 1);

	      d3.select(this).select('circle').style('opacity', 1);
	    }).on('mouseout', function () {
	      d3.select(this).select('path').style('fill', 'black').style('opacity', 0.5);
	      d3.select(this).select('circle').style('opacity', 0.5);
	    }).on('click', function () {
	      // running from anonymous function to keep this defined correctly
	      cgm.play_demo();
	    });
	  }
		};

/***/ },
/* 207 */
/***/ function(module, exports) {

	module.exports = function make_demo_text_containers(params, demo_text_size) {

	  if (d3.select(params.root + ' .demo_group').empty()) {

	    var clust_transform = d3.select(params.root + ' .clust_container').attr('transform');
	    var clust_x = Number(clust_transform.split('(')[1].split(',')[0]);
	    var clust_y = Number(clust_transform.split(',')[1].replace(')', ''));

	    // demo text container
	    var demo_group = d3.select(params.root + ' .viz_svg').append('g').classed('demo_group', true).attr('transform', function () {
	      var pos_x = clust_x + 20;
	      var pos_y = clust_y + 40;
	      return 'translate(' + pos_x + ',' + pos_y + ')';
	    });

	    demo_group.append('rect').classed('rect_1', true);

	    demo_group.append('rect').classed('rect_2', true);

	    demo_group.append('rect').classed('rect_3', true);

	    var shift_height = 1.3 * demo_text_size;

	    demo_group.append('text').attr('id', 'text_1').attr('font-size', demo_text_size + 'px').attr('font-weight', 1000).attr('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif');

	    demo_group.append('text').attr('id', 'text_2').attr('font-size', demo_text_size + 'px').attr('font-weight', 1000).attr('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif').attr('transform', function () {
	      return 'translate(0,' + String(shift_height) + ')';
	    });

	    demo_group.append('text').attr('id', 'text_3').attr('font-size', demo_text_size + 'px').attr('font-weight', 1000).attr('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif').attr('transform', function () {
	      return 'translate(0,' + String(2 * shift_height) + ')';
	    });
	  }
		};

/***/ },
/* 208 */
/***/ function(module, exports, __webpack_require__) {

	var filter_network_using_new_nodes = __webpack_require__(11);
	var update_viz_with_network = __webpack_require__(179);

	module.exports = function filter_viz_using_nodes(new_nodes) {

	  var new_network_data = filter_network_using_new_nodes(this.config, new_nodes);
	  update_viz_with_network(this, new_network_data);
		};

/***/ },
/* 209 */
/***/ function(module, exports, __webpack_require__) {

	var filter_network_using_new_nodes = __webpack_require__(11);
	var update_viz_with_network = __webpack_require__(179);

	module.exports = function filter_viz_using_names(names, external_cgm = false) {

	  // names is an object with row and column names that will be used to filter
	  // the matrix

	  var cgm;
	  if (external_cgm === false) {
	    cgm = this;
	  } else {
	    cgm = external_cgm;
	  }

	  var params = cgm.params;
	  var new_nodes = {};
	  var found_nodes;

	  _.each(['row', 'col'], function (inst_rc) {

	    var orig_nodes = params.inst_nodes[inst_rc + '_nodes'];

	    if (_.has(names, inst_rc)) {

	      if (names[inst_rc].length > 0) {
	        var inst_names = names[inst_rc];
	        found_nodes = $.grep(orig_nodes, function (d) {
	          return $.inArray(d.name, inst_names) > -1;
	        });
	      } else {

	        found_nodes = orig_nodes;
	      }
	    } else {

	      found_nodes = orig_nodes;
	    }

	    new_nodes[inst_rc + '_nodes'] = found_nodes;
	  });

	  // keep backup of the nodes for resetting filtering
	  var inst_row_nodes = cgm.params.network_data.row_nodes;
	  var inst_col_nodes = cgm.params.network_data.col_nodes;

	  var new_network_data = filter_network_using_new_nodes(cgm.config, new_nodes);

	  // takes entire cgm object
	  // last argument tells it to not preserve categoty colors
	  update_viz_with_network(cgm, new_network_data);

	  // only keep backup if previous number of nodes were larger than current number
	  // of nodes
	  if (inst_row_nodes.length > cgm.params.inst_nodes.row_nodes.length) {
	    cgm.params.inst_nodes.row_nodes = inst_row_nodes;
	  }

	  if (inst_col_nodes.length > cgm.params.inst_nodes.col_nodes.length) {
	    cgm.params.inst_nodes.col_nodes = inst_col_nodes;
	  }
		};

/***/ },
/* 210 */
/***/ function(module, exports, __webpack_require__) {

	var make_row_cat = __webpack_require__(158);
	var calc_viz_params = __webpack_require__(15);
	var resize_viz = __webpack_require__(124);
	var modify_row_node_cats = __webpack_require__(196);

	module.exports = function update_cats(cgm, cat_data) {

	  // Only accessible from the cgm API, cat_data is provided by externally
	  ///////////////////////////////////////////////////////////////////////////

	  if (cgm.params.cat_update_callback != null) {
	    cgm.params.cat_update_callback(this);
	  }

	  // do not change column category info
	  var col_cat_colors = cgm.params.viz.cat_colors.col;

	  modify_row_node_cats(cat_data, cgm.params.network_data.row_nodes, true);
	  // modify the current inst copy of nodes
	  modify_row_node_cats(cat_data, cgm.params.inst_nodes.row_nodes, true);

	  // recalculate the visualization parameters using the updated network_data
	  cgm.params = calc_viz_params(cgm.params, false);

	  make_row_cat(cgm, true);
	  resize_viz(cgm);

	  cgm.params.new_row_cats = cat_data;

	  cgm.params.viz.cat_colors.col = col_cat_colors;
		};

/***/ },
/* 211 */
/***/ function(module, exports, __webpack_require__) {

	var make_row_cat = __webpack_require__(158);
	var calc_viz_params = __webpack_require__(15);
	var resize_viz = __webpack_require__(124);
	var modify_row_node_cats = __webpack_require__(196);
	var generate_cat_data = __webpack_require__(212);

	module.exports = function reset_cats(run_resize_viz = true) {

	  // console.log('RESET CATS')

	  var cgm = this;

	  var cat_data = generate_cat_data(cgm);

	  // do not change column category info
	  var col_cat_colors = cgm.params.viz.cat_colors.col;

	  modify_row_node_cats(cat_data, cgm.params.network_data.row_nodes);
	  // modify the current inst copy of nodes
	  modify_row_node_cats(cat_data, cgm.params.inst_nodes.row_nodes);

	  cgm.params.new_row_cats = cat_data;
	  cgm.params.viz.cat_colors.col = col_cat_colors;

	  if (run_resize_viz) {

	    // resize visualizatino
	    ////////////////////////////
	    // recalculate the visualization parameters using the updated network_data
	    var predefine_cat_colors = true;
	    cgm.params = calc_viz_params(cgm.params, predefine_cat_colors);

	    make_row_cat(cgm, true);
	    resize_viz(cgm);
	  }
		};

/***/ },
/* 212 */
/***/ function(module, exports) {

	module.exports = function generate_cat_data(cgm) {

	  // only row category resetting is supported currently

	  // get row_nodes from config, since this is has the original network
	  var row_nodes = cgm.config.network_data.row_nodes;
	  var title_sep = ': ';

	  // contains all the category information stored as an array of
	  // cat_type
	  var cat_data = [];
	  var cat_type;
	  var cat_info;
	  var found_cat_title;
	  var found_cat_name;
	  var cat_name;

	  // console.log('generate_cat_data')
	  // console.log(cgm.params.viz.cat_names.row)

	  // get current list of cateories
	  var check_node = row_nodes[0];
	  var node_keys = _.keys(check_node);
	  var current_cats = {};
	  var tmp_cat;
	  var tmp_title;
	  var cat_index;
	  _.each(node_keys, function (inst_prop) {

	    if (inst_prop.indexOf('cat-') >= 0) {

	      // generate titles from cat info
	      tmp_cat = check_node[inst_prop];

	      cat_index = parseInt(inst_prop.split('cat-')[1], 10);

	      // use given title
	      if (tmp_cat.indexOf(title_sep) >= 0) {
	        tmp_title = tmp_cat.split(title_sep)[0];
	      } else {
	        tmp_title = inst_prop;
	      }

	      // current_cats.push(tmp_title);

	      current_cats[cat_index] = tmp_title;
	    }
	  });

	  // console.log('current_cats')
	  // console.log(current_cats)

	  // initialize cat_data with categories in the correct order
	  var all_index = _.keys(current_cats).sort();

	  var inst_data;
	  _.each(all_index, function (inst_index) {

	    inst_data = {};
	    inst_data.cat_title = current_cats[inst_index];
	    inst_data.cats = [];

	    cat_data.push(inst_data);
	  });

	  // // initialize cat_data (keep original order)
	  // var found_title;
	  // _.each(cgm.params.viz.cat_names.row, function(inst_title){

	  //   found_title = false;

	  //   console.log('inst_title -> ' + String(inst_title))

	  //   if (current_cats.indexOf(inst_title) >= 0){
	  //     found_title = true;
	  //   }

	  //   // only track cats that are found in the incoming nodes
	  //   if (found_title){
	  //     var inst_data = {};
	  //     inst_data.cat_title = inst_title;
	  //     inst_data.cats = [];
	  //     cat_data.push(inst_data);
	  //   }

	  // });

	  // console.log('cat_data after cross checking with current cats')
	  // console.log(cat_data)
	  // console.log('-------------------------\n')

	  _.each(row_nodes, function (inst_node) {

	    var all_props = _.keys(inst_node);

	    _.each(all_props, function (inst_prop) {

	      if (inst_prop.indexOf('cat-') > -1) {

	        cat_name = inst_node[inst_prop];

	        cat_index = parseInt(inst_prop.split('cat-')[1], 10);

	        // default title and name
	        var cat_title = inst_prop;
	        cat_name = inst_node[inst_prop];
	        var cat_string = inst_node[inst_prop];
	        var cat_row_name = inst_node.name;

	        // console.log('cat_string: '+String(cat_string))
	        // found actual title
	        if (cat_string.indexOf(title_sep) > -1) {
	          cat_title = cat_string.split(title_sep)[0];
	          cat_name = cat_string.split(title_sep)[1];
	        } else {
	          // cat_title = 'Category-'+String(parseInt(inst_prop.split('-')[1]) + 1)
	          cat_title = inst_prop;
	          cat_name = cat_string;
	        }

	        // console.log('cat_index -> ' + String(cat_index))
	        // console.log('cat_name '+cat_name)
	        // console.log('cat_title ' + cat_title)
	        // console.log('--------')

	        // cat_data is empty
	        if (cat_data.length === 0) {

	          add_new_cat_type(cat_title, cat_name, cat_row_name);

	          // cat_data is not empty
	        } else {

	          // look for cat_title in cat_data
	          found_cat_title = false;
	          _.each(cat_data, function (inst_cat_type) {

	            // console.log('inst_cat_data title ' + inst_cat_type.cat_title)

	            // check each cat_type object for a matching title
	            if (cat_title === inst_cat_type.cat_title) {
	              found_cat_title = true;

	              // check if cat_name is in cats
	              found_cat_name = false;
	              _.each(inst_cat_type.cats, function (inst_cat_obj) {

	                // found category name, add cat_row_name to members
	                if (cat_name === inst_cat_obj.cat_name) {
	                  found_cat_name = true;

	                  // add cat_row_name to members
	                  inst_cat_obj.members.push(cat_row_name);
	                }
	              });

	              // did not find cat name in cat_type - add cat_info for new
	              // category
	              if (found_cat_name === false) {
	                cat_info = {};
	                cat_info.cat_name = cat_name;
	                cat_info.members = [];
	                cat_info.members.push(cat_row_name);
	                inst_cat_type.cats.push(cat_info);
	              }
	            }
	          });

	          // did not find category type, initialize category type object
	          if (found_cat_title === false) {

	            // console.log('did not find cat_title: ' + String(cat_title))
	            // add_new_cat_type(cat_title, cat_name, cat_row_name);

	          }
	        }
	      }
	    });
	  });

	  function add_new_cat_type(cat_title, cat_name, cat_row_name) {

	    // initialize cat_type object to push to cat_data
	    cat_type = {};
	    cat_type.cat_title = cat_title;
	    cat_type.cats = [];

	    // initialize cat_info (e.g. 'true' category has members [...])
	    cat_info = {};
	    cat_info.cat_name = cat_name;
	    cat_info.members = [];
	    cat_info.members.push(cat_row_name);

	    cat_type.cats.push(cat_info);

	    cat_data.push(cat_type);
	  }

	  // console.log('RETURNING CAT DATA')
	  // console.log(cat_data)

	  return cat_data;
	};

/***/ },
/* 213 */
/***/ function(module, exports, __webpack_require__) {

	var update_viz_with_view = __webpack_require__(177);
	var reset_other_filter_sliders = __webpack_require__(214);

	module.exports = function external_update_view(filter_type, inst_state) {

	  // add something to control slider position
	  /////////////////////////////////////////////

	  var cgm = this;

	  var requested_view = {};
	  requested_view[filter_type] = inst_state;
	  update_viz_with_view(this, requested_view);

	  reset_other_filter_sliders(cgm, filter_type, inst_state);
	};

/***/ },
/* 214 */
/***/ function(module, exports, __webpack_require__) {

	var make_filter_title = __webpack_require__(215);

	module.exports = function reset_other_filter_sliders(cgm, filter_type, inst_state) {

	  var params = cgm.params;
	  var inst_rc;
	  var reset_rc;

	  d3.select(params.root + ' .slider_' + filter_type).attr('current_state', inst_state);

	  _.each(_.keys(params.viz.possible_filters), function (reset_filter) {

	    if (filter_type.indexOf('row') > -1) {
	      inst_rc = 'row';
	    } else if (filter_type.indexOf('col') > -1) {
	      inst_rc = 'col';
	    } else {
	      inst_rc = 'neither';
	    }

	    if (reset_filter.indexOf('row') > -1) {
	      reset_rc = 'row';
	    } else if (reset_filter.indexOf('col') > -1) {
	      reset_rc = 'col';
	    } else {
	      reset_rc = 'neither';
	    }

	    if (filter_type != reset_filter && inst_rc != 'neither') {

	      if (inst_rc == reset_rc) {

	        var tmp_title = make_filter_title(params, reset_filter);

	        cgm.slider_functions[reset_filter].value(0);

	        d3.select(params.root + ' .title_' + reset_filter).text(tmp_title.text + tmp_title.state);

	        d3.select(params.root + ' .slider_' + reset_filter).attr('current_state', tmp_title.state);
	      }
	    }
	  });

	  var filter_title = make_filter_title(params, filter_type);

	  d3.select(params.root + ' .title_' + filter_type).text(filter_title.text + inst_state + filter_title.suffix);
		};

/***/ },
/* 215 */
/***/ function(module, exports, __webpack_require__) {

	var get_filter_default_state = __webpack_require__(5);

	module.exports = function make_filter_title(params, filter_type) {

	  var filter_title = {};
	  var title = {};
	  var type = {};

	  filter_title.state = get_filter_default_state(params.viz.filter_data, filter_type);

	  type.top = filter_type.split('_')[0];
	  type.node = filter_type.split('_')[1];
	  type.measure = filter_type.split('_')[2];

	  if (type.node === 'row') {
	    title.node = 'rows';
	  } else {
	    title.node = 'columns';
	  }

	  if (type.top === 'N') {
	    // filter_title.suffix = ' '+title.node;
	    filter_title.suffix = '';
	  }

	  if (type.top === 'pct') {
	    filter_title.suffix = '%';
	  }

	  if (type.measure == 'sum') {
	    title.measure = 'sum';
	  } else if (type.measure == 'var') {
	    title.measure = 'variance';
	  }

	  if (type.measure === 'sum') {
	    filter_title.text = 'Top ' + title.node + ' ' + title.measure + ': ';
	  }

	  if (type.measure === 'var') {
	    filter_title.text = 'Top ' + title.node + ' ' + title.measure + ': ';
	  }

	  // Enrichr specific rules
	  if (_.keys(params.viz.possible_filters).indexOf('enr_score_type') > -1) {
	    if (type.node === 'col') {
	      filter_title.text = 'Top Enriched Terms: ';
	      filter_title.suffix = '';
	    }
	  }

	  return filter_title;
	};

/***/ },
/* 216 */
/***/ function(module, exports, __webpack_require__) {

	var file_saver = __webpack_require__(217);
	var make_matrix_string = __webpack_require__(218);

	module.exports = function save_matrix() {

	  var saveAs = file_saver();

	  var params = this.params;

	  var matrix_string = make_matrix_string(params);

	  var blob = new Blob([matrix_string], { type: 'text/plain;charset=utf-8' });
	  saveAs(blob, 'clustergrammer.txt');
		};

/***/ },
/* 217 */
/***/ function(module, exports) {

	module.exports = function file_saver() {
	  /* eslint-disable */
	  /* FileSaver.js
	   * A saveAs() FileSaver implementation.
	   * 2013-01-23
	   *
	   * By Eli Grey, http://eligrey.com
	   * License: X11/MIT
	   *   See LICENSE.md
	   */

	  /*global self */
	  /*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
	    plusplus: true */

	  /*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */

	  var saveAs = saveAs || navigator.msSaveBlob && navigator.msSaveBlob.bind(navigator) || function (view) {
	    "use strict";

	    var doc = view.document
	    // only get URL when necessary in case BlobBuilder.js hasn't overridden it yet
	    ,
	        get_URL = function () {
	      return view.URL || view.webkitURL || view;
	    },
	        URL = view.URL || view.webkitURL || view,
	        save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a"),
	        can_use_save_link = "download" in save_link,
	        click = function (node) {
	      var event = doc.createEvent("MouseEvents");
	      event.initMouseEvent("click", true, false, view, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
	      node.dispatchEvent(event);
	    },
	        webkit_req_fs = view.webkitRequestFileSystem,
	        req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem,
	        throw_outside = function (ex) {
	      (view.setImmediate || view.setTimeout)(function () {
	        throw ex;
	      }, 0);
	    },
	        force_saveable_type = "application/octet-stream",
	        fs_min_size = 0,
	        deletion_queue = [],
	        process_deletion_queue = function () {
	      var i = deletion_queue.length;
	      while (i--) {
	        var file = deletion_queue[i];
	        if (typeof file === "string") {
	          // file is an object URL
	          URL.revokeObjectURL(file);
	        } else {
	          // file is a File
	          file.remove();
	        }
	      }
	      deletion_queue.length = 0; // clear queue
	    },
	        dispatch = function (filesaver, event_types, event) {
	      event_types = [].concat(event_types);
	      var i = event_types.length;
	      while (i--) {
	        var listener = filesaver["on" + event_types[i]];
	        if (typeof listener === "function") {
	          try {
	            listener.call(filesaver, event || filesaver);
	          } catch (ex) {
	            throw_outside(ex);
	          }
	        }
	      }
	    },
	        FileSaver = function (blob, name) {
	      // First try a.download, then web filesystem, then object URLs
	      var filesaver = this,
	          type = blob.type,
	          blob_changed = false,
	          object_url,
	          target_view,
	          get_object_url = function () {
	        var object_url = get_URL().createObjectURL(blob);
	        deletion_queue.push(object_url);
	        return object_url;
	      },
	          dispatch_all = function () {
	        dispatch(filesaver, "writestart progress write writeend".split(" "));
	      }
	      // on any filesys errors revert to saving with object URLs
	      ,
	          fs_error = function () {
	        // don't create more object URLs than needed
	        if (blob_changed || !object_url) {
	          object_url = get_object_url(blob);
	        }
	        if (target_view) {
	          target_view.location.href = object_url;
	        }
	        filesaver.readyState = filesaver.DONE;
	        dispatch_all();
	      },
	          abortable = function (func) {
	        return function () {
	          if (filesaver.readyState !== filesaver.DONE) {
	            return func.apply(this, arguments);
	          }
	        };
	      },
	          create_if_not_found = { create: true, exclusive: false },
	          slice;
	      filesaver.readyState = filesaver.INIT;
	      if (!name) {
	        name = "download";
	      }
	      if (can_use_save_link) {
	        object_url = get_object_url(blob);
	        save_link.href = object_url;
	        save_link.download = name;
	        click(save_link);
	        filesaver.readyState = filesaver.DONE;
	        dispatch_all();
	        return;
	      }
	      // Object and web filesystem URLs have a problem saving in Google Chrome when
	      // viewed in a tab, so I force save with application/octet-stream
	      // http://code.google.com/p/chromium/issues/detail?id=91158
	      if (view.chrome && type && type !== force_saveable_type) {
	        slice = blob.slice || blob.webkitSlice;
	        blob = slice.call(blob, 0, blob.size, force_saveable_type);
	        blob_changed = true;
	      }
	      // Since I can't be sure that the guessed media type will trigger a download
	      // in WebKit, I append .download to the filename.
	      // https://bugs.webkit.org/show_bug.cgi?id=65440
	      if (webkit_req_fs && name !== "download") {
	        name += ".download";
	      }
	      if (type === force_saveable_type || webkit_req_fs) {
	        target_view = view;
	      } else {
	        target_view = view.open();
	      }
	      if (!req_fs) {
	        fs_error();
	        return;
	      }
	      fs_min_size += blob.size;
	      req_fs(view.TEMPORARY, fs_min_size, abortable(function (fs) {
	        fs.root.getDirectory("saved", create_if_not_found, abortable(function (dir) {
	          var save = function () {
	            dir.getFile(name, create_if_not_found, abortable(function (file) {
	              file.createWriter(abortable(function (writer) {
	                writer.onwriteend = function (event) {
	                  target_view.location.href = file.toURL();
	                  deletion_queue.push(file);
	                  filesaver.readyState = filesaver.DONE;
	                  dispatch(filesaver, "writeend", event);
	                };
	                writer.onerror = function () {
	                  var error = writer.error;
	                  if (error.code !== error.ABORT_ERR) {
	                    fs_error();
	                  }
	                };
	                "writestart progress write abort".split(" ").forEach(function (event) {
	                  writer["on" + event] = filesaver["on" + event];
	                });
	                writer.write(blob);
	                filesaver.abort = function () {
	                  writer.abort();
	                  filesaver.readyState = filesaver.DONE;
	                };
	                filesaver.readyState = filesaver.WRITING;
	              }), fs_error);
	            }), fs_error);
	          };
	          dir.getFile(name, { create: false }, abortable(function (file) {
	            // delete file if it already exists
	            file.remove();
	            save();
	          }), abortable(function (ex) {
	            if (ex.code === ex.NOT_FOUND_ERR) {
	              save();
	            } else {
	              fs_error();
	            }
	          }));
	        }), fs_error);
	      }), fs_error);
	    },
	        FS_proto = FileSaver.prototype,
	        saveAs = function (blob, name) {
	      return new FileSaver(blob, name);
	    };
	    FS_proto.abort = function () {
	      var filesaver = this;
	      filesaver.readyState = filesaver.DONE;
	      dispatch(filesaver, "abort");
	    };
	    FS_proto.readyState = FS_proto.INIT = 0;
	    FS_proto.WRITING = 1;
	    FS_proto.DONE = 2;

	    FS_proto.error = FS_proto.onwritestart = FS_proto.onprogress = FS_proto.onwrite = FS_proto.onabort = FS_proto.onerror = FS_proto.onwriteend = null;

	    view.addEventListener("unload", process_deletion_queue, false);
	    return saveAs;
	  }(self);

	  return saveAs;
		};

/***/ },
/* 218 */
/***/ function(module, exports, __webpack_require__) {

	var make_full_name = __webpack_require__(219);

	module.exports = function make_matrix_string(params) {

	  var inst_matrix = params.matrix;

	  // get order indexes
	  var order_indexes = {};
	  var inst_name;
	  _.each(['row', 'col'], function (tmp_rc) {

	    var inst_rc;
	    // row/col names are reversed in saved orders
	    if (tmp_rc === 'row') {
	      inst_rc = 'col';
	    } else {
	      inst_rc = 'row';
	    }

	    // use tmp_rc
	    inst_name = params.inst_order[tmp_rc];

	    // use tmp_rc
	    order_indexes[inst_rc] = inst_matrix.orders[inst_name + '_' + tmp_rc];
	  });

	  var matrix_string = '\t';
	  var row_nodes = params.network_data.row_nodes;
	  var col_nodes = params.network_data.col_nodes;

	  // alternate column entry
	  for (var c_i = 0; c_i < order_indexes.col.length; c_i++) {

	    var inst_index = order_indexes.col[c_i];

	    var inst_col = col_nodes[inst_index];
	    var col_name = make_full_name(params, inst_col, 'col');

	    if (c_i < order_indexes.col.length - 1) {
	      matrix_string = matrix_string + col_name + '\t';
	    } else {
	      matrix_string = matrix_string + col_name;
	    }
	  }

	  var row_data;
	  matrix_string = matrix_string + '\n';

	  _.each(order_indexes.row, function (inst_index) {

	    // row names
	    row_data = inst_matrix.matrix[inst_index].row_data;

	    // var row_name = inst_matrix.matrix[inst_index].name;
	    var inst_row = row_nodes[inst_index];

	    // var row_name = inst_row.name;
	    var row_name = make_full_name(params, inst_row, 'row');

	    matrix_string = matrix_string + row_name + '\t';

	    // alternate data entry
	    for (var r_i = 0; r_i < order_indexes.col.length; r_i++) {

	      // get the order
	      var col_index = order_indexes.col[r_i];

	      if (r_i < order_indexes.col.length - 1) {
	        matrix_string = matrix_string + String(row_data[col_index].value) + '\t';
	      } else {
	        matrix_string = matrix_string + String(row_data[col_index].value);
	      }
	    }

	    matrix_string = matrix_string + '\n';
	  });

	  return matrix_string;
		};

/***/ },
/* 219 */
/***/ function(module, exports) {

	module.exports = function make_full_name(params, inst_node, inst_rc) {

	  var cat_name;
	  var inst_name = inst_node.name;
	  var num_cats = params.viz.all_cats[inst_rc].length;

	  // make tuple if necessary
	  if (num_cats > 0) {

	    inst_name = "('" + inst_name + "'";

	    for (var cat_index = 0; cat_index < num_cats; cat_index++) {
	      cat_name = 'cat-' + String(cat_index);

	      inst_name = inst_name + ", '" + String(inst_node[cat_name]) + "'";
	    }

	    inst_name = inst_name + ')';
	  } else {

	    // always make names strings
	    inst_name = String(inst_name);
	  }

	  return inst_name;
	};

/***/ },
/* 220 */
/***/ function(module, exports, __webpack_require__) {

	var deactivate_cropping = __webpack_require__(221);

	module.exports = function brush_crop_matrix() {

	  // get rows/cols from brush-extent
	  // works for differnt brushing directions (e.g. start end sites)

	  var cgm = this;
	  var params = cgm.params;

	  var clust_width = params.viz.clust.dim.width;
	  var clust_height = params.viz.clust.dim.height;

	  var x = d3.scale.linear().domain([0, clust_width]).range([0, clust_width]);
	  var y = d3.scale.linear().domain([0, clust_height]).range([0, clust_height]);

	  // make brush group
	  d3.select(params.root + ' .clust_container').append('g').classed('brush_group', true);

	  cgm.params.is_cropping = true;

	  var brush = d3.svg.brush().x(x).y(y).on("brushend", brushend);

	  d3.select(params.root + ' .brush_group').call(brush);

	  function brushend() {

	    // do not display dendro crop buttons when cropping with brushing
	    d3.select(cgm.params.root + ' .col_dendro_icons_container').style('display', 'none');
	    d3.select(cgm.params.root + ' .row_dendro_icons_container').style('display', 'none');

	    var brushing_extent = brush.extent();
	    var brush_start = brushing_extent[0];
	    var brush_end = brushing_extent[1];

	    var x_start = brush_start[0];
	    var x_end = brush_end[0];

	    var y_start = brush_start[1];
	    var y_end = brush_end[1];

	    if (x_start != x_end && y_start != y_end) {

	      setTimeout(deactivate_cropping, 500, cgm);

	      // find cropped nodes
	      var found_nodes = find_cropped_nodes(x_start, x_end, y_start, y_end, brush_start, brush_end);

	      cgm.filter_viz_using_names(found_nodes);

	      d3.select(params.root + ' .crop_button').style('color', '#337ab7').classed('fa-crop', false).classed('fa-undo', true);
	    }
	  }

	  function find_cropped_nodes(x_start, x_end, y_start, y_end, brush_start, brush_end) {

	    // reverse if necessary (depending on how brushing was done)
	    if (x_start > x_end) {
	      x_start = brush_end[0];
	      x_end = brush_start[0];
	    }

	    if (y_start > y_end) {
	      y_start = brush_end[1];
	      y_end = brush_start[1];
	    }

	    // add room to brushing
	    y_start = y_start - params.viz.rect_height;
	    x_start = x_start - params.viz.rect_width;

	    var found_nodes = {};
	    found_nodes.row = [];
	    found_nodes.col = [];

	    // d3.selectAll(params.root+' .row_label_group')
	    //   .each(function(inst_row){

	    //     // there is already bound data on the rows
	    //     var inst_trans = d3.select(this)
	    //       .attr('transform');

	    //     var y_trans = Number(inst_trans.split(',')[1].split(')')[0]);

	    //     if (y_trans > y_start && y_trans < y_end){

	    //       found_nodes.row.push(inst_row.name);

	    //     }

	    //   });

	    _.each(params.matrix.matrix, function (row_data) {
	      var y_trans = params.viz.y_scale(row_data.row_index);

	      if (y_trans > y_start && y_trans < y_end) {
	        found_nodes.row.push(row_data.name);
	      }
	    });

	    d3.selectAll(params.root + ' .col_label_text').each(function (inst_col) {

	      // there is already bound data on the cols
	      var inst_trans = d3.select(this).attr('transform');

	      var x_trans = Number(inst_trans.split(',')[0].split('(')[1]);

	      if (x_trans > x_start && x_trans < x_end) {

	        found_nodes.col.push(inst_col.name);
	      }
	    });

	    return found_nodes;
	  }

	  d3.selectAll(params.root + ' .extent').style('opacity', 0.2).style('fill', 'black');
		};

/***/ },
/* 221 */
/***/ function(module, exports) {

	module.exports = function deactivate_cropping(cgm) {

	  d3.select(cgm.params.root + ' .brush_group').transition().style('opacity', 0).remove();

	  cgm.params.is_cropping = false;
		};

/***/ },
/* 222 */
/***/ function(module, exports, __webpack_require__) {

	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*
	    D3.js Slider
	    Inspired by jQuery UI Slider
	    Copyright (c) 2013, Bjorn Sandvik - http://blog.thematicmapping.org
	    BSD license: http://opensource.org/licenses/BSD-3-Clause
	*/
	(function (root, factory) {
	  if (true) {
	    // AMD. Register as an anonymous module.
	    !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(223)], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
	  } else if (typeof exports === 'object') {
	    if (process.browser) {
	      // Browserify. Import css too using cssify.
	      require('./d3.slider.css');
	    }
	    // Node. Does not work with strict CommonJS, but
	    // only CommonJS-like environments that support module.exports,
	    // like Node.
	    module.exports = factory(require('d3'));
	  } else {
	    // Browser globals (root is window)
	    root.d3.slider = factory(root.d3);
	  }
	})(this, function (d3) {
	  return function module() {
	    "use strict";

	    // Public variables width default settings

	    var min = 0,
	        max = 100,
	        step = 0.01,
	        animate = false,
	        orientation = "horizontal",
	        axis = false,
	        margin = 50,
	        value,
	        active = 1,
	        snap = false,
	        scale;

	    // Private variables
	    var axisScale,
	        dispatch = d3.dispatch("slide", "slideend"),
	        formatPercent = d3.format(".2%"),
	        tickFormat = d3.format(".0"),
	        handle1,
	        handle2 = null,
	        divRange,
	        sliderLength;

	    function slider(selection) {
	      selection.each(function () {

	        // Create scale if not defined by user
	        if (!scale) {
	          scale = d3.scale.linear().domain([min, max]);
	        }

	        // Start value
	        value = value || scale.domain()[0];

	        // DIV container
	        var div = d3.select(this).classed("d3-slider d3-slider-" + orientation, true);

	        var drag = d3.behavior.drag();
	        drag.on('dragend', function () {
	          dispatch.slideend(d3.event, value);
	        });

	        // Slider handle
	        //if range slider, create two
	        // var divRange;

	        if (toType(value) == "array" && value.length == 2) {
	          handle1 = div.append("a").classed("d3-slider-handle", true).attr("xlink:href", "#").attr('id', "handle-one").on("click", stopPropagation).call(drag);
	          handle2 = div.append("a").classed("d3-slider-handle", true).attr('id', "handle-two").attr("xlink:href", "#").on("click", stopPropagation).call(drag);
	        } else {
	          handle1 = div.append("a").classed("d3-slider-handle", true).attr("xlink:href", "#").attr('id', "handle-one").on("click", stopPropagation).call(drag);
	        }

	        // Horizontal slider
	        if (orientation === "horizontal") {

	          div.on("click", onClickHorizontal);

	          if (toType(value) == "array" && value.length == 2) {
	            divRange = d3.select(this).append('div').classed("d3-slider-range", true);

	            handle1.style("left", formatPercent(scale(value[0])));
	            divRange.style("left", formatPercent(scale(value[0])));
	            drag.on("drag", onDragHorizontal);

	            var width = 100 - parseFloat(formatPercent(scale(value[1])));
	            handle2.style("left", formatPercent(scale(value[1])));
	            divRange.style("right", width + "%");
	            drag.on("drag", onDragHorizontal);
	          } else {
	            handle1.style("left", formatPercent(scale(value)));
	            drag.on("drag", onDragHorizontal);
	          }

	          sliderLength = parseInt(div.style("width"), 10);
	        } else {
	          // Vertical

	          div.on("click", onClickVertical);
	          drag.on("drag", onDragVertical);
	          if (toType(value) == "array" && value.length == 2) {
	            divRange = d3.select(this).append('div').classed("d3-slider-range-vertical", true);

	            handle1.style("bottom", formatPercent(scale(value[0])));
	            divRange.style("bottom", formatPercent(scale(value[0])));
	            drag.on("drag", onDragVertical);

	            var top = 100 - parseFloat(formatPercent(scale(value[1])));
	            handle2.style("bottom", formatPercent(scale(value[1])));
	            divRange.style("top", top + "%");
	            drag.on("drag", onDragVertical);
	          } else {
	            handle1.style("bottom", formatPercent(scale(value)));
	            drag.on("drag", onDragVertical);
	          }

	          sliderLength = parseInt(div.style("height"), 10);
	        }

	        if (axis) {
	          createAxis(div);
	        }

	        function createAxis(dom) {

	          // Create axis if not defined by user
	          if (typeof axis === "boolean") {

	            axis = d3.svg.axis().ticks(Math.round(sliderLength / 100)).tickFormat(tickFormat).orient(orientation === "horizontal" ? "bottom" : "right");
	          }

	          // Copy slider scale to move from percentages to pixels
	          axisScale = scale.ticks ? scale.copy().range([0, sliderLength]) : scale.copy().rangePoints([0, sliderLength], 0.5);
	          axis.scale(axisScale);

	          // Create SVG axis container
	          var svg = dom.append("svg").classed("d3-slider-axis d3-slider-axis-" + axis.orient(), true).on("click", stopPropagation);

	          var g = svg.append("g");

	          // Horizontal axis
	          if (orientation === "horizontal") {

	            svg.style("margin-left", -margin + "px");

	            svg.attr({
	              width: sliderLength + margin * 2,
	              height: margin
	            });

	            if (axis.orient() === "top") {
	              svg.style("top", -margin + "px");
	              g.attr("transform", "translate(" + margin + "," + margin + ")");
	            } else {
	              // bottom
	              g.attr("transform", "translate(" + margin + ",0)");
	            }
	          } else {
	            // Vertical

	            svg.style("top", -margin + "px");

	            svg.attr({
	              width: margin,
	              height: sliderLength + margin * 2
	            });

	            if (axis.orient() === "left") {
	              svg.style("left", -margin + "px");
	              g.attr("transform", "translate(" + margin + "," + margin + ")");
	            } else {
	              // right
	              g.attr("transform", "translate(" + 0 + "," + margin + ")");
	            }
	          }

	          g.call(axis);
	        }

	        function onClickHorizontal() {
	          if (toType(value) != "array") {
	            var pos = Math.max(0, Math.min(sliderLength, d3.event.offsetX || d3.event.layerX));
	            moveHandle(scale.invert ? stepValue(scale.invert(pos / sliderLength)) : nearestTick(pos / sliderLength));
	          }
	        }

	        function onClickVertical() {
	          if (toType(value) != "array") {
	            var pos = sliderLength - Math.max(0, Math.min(sliderLength, d3.event.offsetY || d3.event.layerY));
	            moveHandle(scale.invert ? stepValue(scale.invert(pos / sliderLength)) : nearestTick(pos / sliderLength));
	          }
	        }

	        function onDragHorizontal() {
	          if (d3.event.sourceEvent.target.id === "handle-one") {
	            active = 1;
	          } else if (d3.event.sourceEvent.target.id == "handle-two") {
	            active = 2;
	          }
	          var pos = Math.max(0, Math.min(sliderLength, d3.event.x));
	          moveHandle(scale.invert ? stepValue(scale.invert(pos / sliderLength)) : nearestTick(pos / sliderLength));
	        }

	        function onDragVertical() {
	          if (d3.event.sourceEvent.target.id === "handle-one") {
	            active = 1;
	          } else if (d3.event.sourceEvent.target.id == "handle-two") {
	            active = 2;
	          }
	          var pos = sliderLength - Math.max(0, Math.min(sliderLength, d3.event.y));
	          moveHandle(scale.invert ? stepValue(scale.invert(pos / sliderLength)) : nearestTick(pos / sliderLength));
	        }

	        function stopPropagation() {
	          d3.event.stopPropagation();
	        }
	      });
	    }

	    // Move slider handle on click/drag
	    function moveHandle(newValue) {
	      var currentValue = toType(value) == "array" && value.length == 2 ? value[active - 1] : value,
	          oldPos = formatPercent(scale(stepValue(currentValue))),
	          newPos = formatPercent(scale(stepValue(newValue))),
	          position = orientation === "horizontal" ? "left" : "bottom";
	      if (oldPos !== newPos) {

	        if (toType(value) == "array" && value.length == 2) {
	          value[active - 1] = newValue;
	          if (d3.event) {
	            dispatch.slide(d3.event, value);
	          };
	        } else {
	          if (d3.event) {
	            dispatch.slide(d3.event.sourceEvent || d3.event, value = newValue);
	          };
	        }

	        if (value[0] >= value[1]) return;
	        if (active === 1) {
	          if (toType(value) == "array" && value.length == 2) {
	            position === "left" ? divRange.style("left", newPos) : divRange.style("bottom", newPos);
	          }

	          if (animate) {
	            handle1.transition().styleTween(position, function () {
	              return d3.interpolate(oldPos, newPos);
	            }).duration(typeof animate === "number" ? animate : 250);
	          } else {
	            handle1.style(position, newPos);
	          }
	        } else {

	          var width = 100 - parseFloat(newPos);
	          var top = 100 - parseFloat(newPos);

	          position === "left" ? divRange.style("right", width + "%") : divRange.style("top", top + "%");

	          if (animate) {
	            handle2.transition().styleTween(position, function () {
	              return d3.interpolate(oldPos, newPos);
	            }).duration(typeof animate === "number" ? animate : 250);
	          } else {
	            handle2.style(position, newPos);
	          }
	        }
	      }
	    }

	    // Calculate nearest step value
	    function stepValue(val) {

	      if (val === scale.domain()[0] || val === scale.domain()[1]) {
	        return val;
	      }

	      var alignValue = val;
	      if (snap) {
	        alignValue = nearestTick(scale(val));
	      } else {
	        var valModStep = (val - scale.domain()[0]) % step;
	        alignValue = val - valModStep;

	        if (Math.abs(valModStep) * 2 >= step) {
	          alignValue += valModStep > 0 ? step : -step;
	        }
	      };

	      return alignValue;
	    }

	    // Find the nearest tick
	    function nearestTick(pos) {
	      var ticks = scale.ticks ? scale.ticks() : scale.domain();
	      var dist = ticks.map(function (d) {
	        return pos - scale(d);
	      });
	      var i = -1,
	          index = 0,
	          r = scale.ticks ? scale.range()[1] : scale.rangeExtent()[1];
	      do {
	        i++;
	        if (Math.abs(dist[i]) < r) {
	          r = Math.abs(dist[i]);
	          index = i;
	        };
	      } while (dist[i] > 0 && i < dist.length - 1);

	      return ticks[index];
	    };

	    // Return the type of an object
	    function toType(v) {
	      return {}.toString.call(v).match(/\s([a-zA-Z]+)/)[1].toLowerCase();
	    };

	    // Getter/setter functions
	    slider.min = function (_) {
	      if (!arguments.length) return min;
	      min = _;
	      return slider;
	    };

	    slider.max = function (_) {
	      if (!arguments.length) return max;
	      max = _;
	      return slider;
	    };

	    slider.step = function (_) {
	      if (!arguments.length) return step;
	      step = _;
	      return slider;
	    };

	    slider.animate = function (_) {
	      if (!arguments.length) return animate;
	      animate = _;
	      return slider;
	    };

	    slider.orientation = function (_) {
	      if (!arguments.length) return orientation;
	      orientation = _;
	      return slider;
	    };

	    slider.axis = function (_) {
	      if (!arguments.length) return axis;
	      axis = _;
	      return slider;
	    };

	    slider.margin = function (_) {
	      if (!arguments.length) return margin;
	      margin = _;
	      return slider;
	    };

	    slider.value = function (_) {
	      if (!arguments.length) return value;
	      if (value) {
	        moveHandle(stepValue(_));
	      };
	      value = _;
	      return slider;
	    };

	    slider.snap = function (_) {
	      if (!arguments.length) return snap;
	      snap = _;
	      return slider;
	    };

	    slider.scale = function (_) {
	      if (!arguments.length) return scale;
	      scale = _;
	      return slider;
	    };

	    d3.rebind(slider, dispatch, "on");

	    return slider;
	  };
	});

/***/ },
/* 223 */
/***/ function(module, exports) {

	module.exports = d3;

/***/ },
/* 224 */
/***/ function(module, exports) {

	/**
	 * Simple, lightweight, usable local autocomplete library for modern browsers
	 * Because there weren’t enough autocomplete scripts in the world? Because I’m completely insane and have NIH syndrome? Probably both. :P
	 * @author Lea Verou http://leaverou.github.io/awesomplete
	 * MIT license
	 */

	(function () {

		var _ = function (input, o) {
			var me = this;

			// Setup

			this.input = $(input);
			this.input.setAttribute("autocomplete", "off");
			this.input.setAttribute("aria-autocomplete", "list");

			o = o || {};

			configure(this, {
				minChars: 2,
				maxItems: 10,
				autoFirst: false,
				data: _.DATA,
				filter: _.FILTER_CONTAINS,
				sort: _.SORT_BYLENGTH,
				item: _.ITEM,
				replace: _.REPLACE
			}, o);

			this.index = -1;

			// Create necessary elements

			this.container = $.create("div", {
				className: "awesomplete",
				around: input
			});

			this.ul = $.create("ul", {
				hidden: "hidden",
				inside: this.container
			});

			this.status = $.create("span", {
				className: "visually-hidden",
				role: "status",
				"aria-live": "assertive",
				"aria-relevant": "additions",
				inside: this.container
			});

			// Bind events

			$.bind(this.input, {
				"input": this.evaluate.bind(this),
				"blur": this.close.bind(this, { reason: "blur" }),
				"keydown": function (evt) {
					var c = evt.keyCode;

					// If the dropdown `ul` is in view, then act on keydown for the following keys:
					// Enter / Esc / Up / Down
					if (me.opened) {
						if (c === 13 && me.selected) {
							// Enter
							evt.preventDefault();
							me.select();
						} else if (c === 27) {
							// Esc
							me.close({ reason: "esc" });
						} else if (c === 38 || c === 40) {
							// Down/Up arrow
							evt.preventDefault();
							me[c === 38 ? "previous" : "next"]();
						}
					}
				}
			});

			$.bind(this.input.form, { "submit": this.close.bind(this, { reason: "submit" }) });

			$.bind(this.ul, { "mousedown": function (evt) {
					var li = evt.target;

					if (li !== this) {

						while (li && !/li/i.test(li.nodeName)) {
							li = li.parentNode;
						}

						if (li && evt.button === 0) {
							// Only select on left click
							evt.preventDefault();
							me.select(li, evt.target);
						}
					}
				} });

			if (this.input.hasAttribute("list")) {
				this.list = "#" + this.input.getAttribute("list");
				this.input.removeAttribute("list");
			} else {
				this.list = this.input.getAttribute("data-list") || o.list || [];
			}

			_.all.push(this);
		};

		_.prototype = {
			set list(list) {
				if (Array.isArray(list)) {
					this._list = list;
				} else if (typeof list === "string" && list.indexOf(",") > -1) {
					this._list = list.split(/\s*,\s*/);
				} else {
					// Element or CSS selector
					list = $(list);

					if (list && list.children) {
						var items = [];
						slice.apply(list.children).forEach(function (el) {
							if (!el.disabled) {
								var text = el.textContent.trim();
								var value = el.value || text;
								var label = el.label || text;
								if (value !== "") {
									items.push({ label: label, value: value });
								}
							}
						});
						this._list = items;
					}
				}

				if (document.activeElement === this.input) {
					this.evaluate();
				}
			},

			get selected() {
				return this.index > -1;
			},

			get opened() {
				return !this.ul.hasAttribute("hidden");
			},

			close: function (o) {
				if (!this.opened) {
					return;
				}

				this.ul.setAttribute("hidden", "");
				this.index = -1;

				$.fire(this.input, "awesomplete-close", o || {});
			},

			open: function () {
				this.ul.removeAttribute("hidden");

				if (this.autoFirst && this.index === -1) {
					this.goto(0);
				}

				$.fire(this.input, "awesomplete-open");
			},

			next: function () {
				var count = this.ul.children.length;

				this.goto(this.index < count - 1 ? this.index + 1 : -1);
			},

			previous: function () {
				var count = this.ul.children.length;

				this.goto(this.selected ? this.index - 1 : count - 1);
			},

			// Should not be used, highlights specific item without any checks!
			goto: function (i) {
				var lis = this.ul.children;

				if (this.selected) {
					lis[this.index].setAttribute("aria-selected", "false");
				}

				this.index = i;

				if (i > -1 && lis.length > 0) {
					lis[i].setAttribute("aria-selected", "true");
					this.status.textContent = lis[i].textContent;

					$.fire(this.input, "awesomplete-highlight", {
						text: this.suggestions[this.index]
					});
				}
			},

			select: function (selected, origin) {
				if (selected) {
					this.index = $.siblingIndex(selected);
				} else {
					selected = this.ul.children[this.index];
				}

				if (selected) {
					var suggestion = this.suggestions[this.index];

					var allowed = $.fire(this.input, "awesomplete-select", {
						text: suggestion,
						origin: origin || selected
					});

					if (allowed) {
						this.replace(suggestion);
						this.close({ reason: "select" });
						$.fire(this.input, "awesomplete-selectcomplete", {
							text: suggestion
						});
					}
				}
			},

			evaluate: function () {
				var me = this;
				var value = this.input.value;

				if (value.length >= this.minChars && this._list.length > 0) {
					this.index = -1;
					// Populate list with options that match
					this.ul.innerHTML = "";

					this.suggestions = this._list.map(function (item) {
						return new Suggestion(me.data(item, value));
					}).filter(function (item) {
						return me.filter(item, value);
					}).sort(this.sort).slice(0, this.maxItems);

					this.suggestions.forEach(function (text) {
						me.ul.appendChild(me.item(text, value));
					});

					if (this.ul.children.length === 0) {
						this.close({ reason: "nomatches" });
					} else {
						this.open();
					}
				} else {
					this.close({ reason: "nomatches" });
				}
			}
		};

		// Static methods/properties

		_.all = [];

		_.FILTER_CONTAINS = function (text, input) {
			return RegExp($.regExpEscape(input.trim()), "i").test(text);
		};

		_.FILTER_STARTSWITH = function (text, input) {
			return RegExp("^" + $.regExpEscape(input.trim()), "i").test(text);
		};

		_.SORT_BYLENGTH = function (a, b) {
			if (a.length !== b.length) {
				return a.length - b.length;
			}

			return a < b ? -1 : 1;
		};

		_.ITEM = function (text, input) {
			var html = input === '' ? text : text.replace(RegExp($.regExpEscape(input.trim()), "gi"), "<mark>$&</mark>");
			return $.create("li", {
				innerHTML: html,
				"aria-selected": "false"
			});
		};

		_.REPLACE = function (text) {
			this.input.value = text.value;
		};

		_.DATA = function (item /*, input*/) {
			return item;
		};

		// Private functions

		function Suggestion(data) {
			var o = Array.isArray(data) ? { label: data[0], value: data[1] } : typeof data === "object" && "label" in data && "value" in data ? data : { label: data, value: data };

			this.label = o.label || o.value;
			this.value = o.value;
		}
		Object.defineProperty(Suggestion.prototype = Object.create(String.prototype), "length", {
			get: function () {
				return this.label.length;
			}
		});
		Suggestion.prototype.toString = Suggestion.prototype.valueOf = function () {
			return "" + this.label;
		};

		function configure(instance, properties, o) {
			for (var i in properties) {
				var initial = properties[i],
				    attrValue = instance.input.getAttribute("data-" + i.toLowerCase());

				if (typeof initial === "number") {
					instance[i] = parseInt(attrValue);
				} else if (initial === false) {
					// Boolean options must be false by default anyway
					instance[i] = attrValue !== null;
				} else if (initial instanceof Function) {
					instance[i] = null;
				} else {
					instance[i] = attrValue;
				}

				if (!instance[i] && instance[i] !== 0) {
					instance[i] = i in o ? o[i] : initial;
				}
			}
		}

		// Helpers

		var slice = Array.prototype.slice;

		function $(expr, con) {
			return typeof expr === "string" ? (con || document).querySelector(expr) : expr || null;
		}

		function $$(expr, con) {
			return slice.call((con || document).querySelectorAll(expr));
		}

		$.create = function (tag, o) {
			var element = document.createElement(tag);

			for (var i in o) {
				var val = o[i];

				if (i === "inside") {
					$(val).appendChild(element);
				} else if (i === "around") {
					var ref = $(val);
					ref.parentNode.insertBefore(element, ref);
					element.appendChild(ref);
				} else if (i in element) {
					element[i] = val;
				} else {
					element.setAttribute(i, val);
				}
			}

			return element;
		};

		$.bind = function (element, o) {
			if (element) {
				for (var event in o) {
					var callback = o[event];

					event.split(/\s+/).forEach(function (event) {
						element.addEventListener(event, callback);
					});
				}
			}
		};

		$.fire = function (target, type, properties) {
			var evt = document.createEvent("HTMLEvents");

			evt.initEvent(type, true, true);

			for (var j in properties) {
				evt[j] = properties[j];
			}

			return target.dispatchEvent(evt);
		};

		$.regExpEscape = function (s) {
			return s.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&");
		};

		$.siblingIndex = function (el) {
			/* eslint-disable no-cond-assign */
			for (var i = 0; el = el.previousElementSibling; i++);
			return i;
		};

		// Initialization

		function init() {
			$$("input.awesomplete").forEach(function (input) {
				new _(input);
			});
		}

		// Are we in a browser? Check for Document constructor
		if (typeof Document !== "undefined") {
			// DOM already loaded?
			if (document.readyState !== "loading") {
				init();
			} else {
				// Wait for it
				document.addEventListener("DOMContentLoaded", init);
			}
		}

		_.$ = $;
		_.$$ = $$;

		// Make sure to export Awesomplete on self when in a browser
		if (typeof self !== "undefined") {
			self.Awesomplete = _;
		}

		// Expose Awesomplete as a CJS module
		if (typeof module === "object" && module.exports) {
			module.exports = _;
		}

		return _;
		})();

/***/ },
/* 225 */
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag

	// load the styles
	var content = __webpack_require__(226);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(228)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../../node_modules/css-loader/index.js!./d3.slider.css", function() {
				var newContent = require("!!./../../node_modules/css-loader/index.js!./d3.slider.css");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },
/* 226 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(227)();
	// imports


	// module
	exports.push([module.id, ".d3-slider {\n    position: relative;\n    font-family: Verdana,Arial,sans-serif;\n    font-size: 1.1em;\n    border: 1px solid #aaaaaa;\n    z-index: 2;\n}\n\n.d3-slider-horizontal {\n    height: .8em;\n}  \n\n.d3-slider-range {\n  background:#2980b9;\n  left:0px;\n  right:0px;\n  height: 0.8em;\n  position: absolute;\n}\n\n.d3-slider-range-vertical {\n  background:#2980b9;\n  left:0px;\n  right:0px;\n  position: absolute;\n  top:0;\n}\n\n.d3-slider-vertical {\n    width: .8em;\n    height: 100px;\n}      \n\n.d3-slider-handle {\n    position: absolute;\n    width: 1.2em;\n    height: 1.2em;\n    border: 1px solid #d3d3d3;\n    border-radius: 4px;\n    background: #eee;\n    background: linear-gradient(to bottom, #eee 0%, #ddd 100%);\n    z-index: 3;\n}\n\n.d3-slider-handle:hover {\n    border: 1px solid #999999;\n}\n\n.d3-slider-horizontal .d3-slider-handle {\n    top: -.3em;\n    margin-left: -.6em;\n}\n\n.d3-slider-axis {\n    position: relative;\n    z-index: 1;    \n}\n\n.d3-slider-axis-bottom {\n    top: .8em;\n}\n\n.d3-slider-axis-right {\n    left: .8em;\n}\n\n.d3-slider-axis path {\n    stroke-width: 0;\n    fill: none;\n}\n\n.d3-slider-axis line {\n    fill: none;\n    stroke: #aaa;\n    shape-rendering: crispEdges;\n}\n\n.d3-slider-axis text {\n    font-size: 11px;\n}\n\n.d3-slider-vertical .d3-slider-handle {\n    left: -.25em;\n    margin-left: 0;\n    margin-bottom: -.6em;      \n}", ""]);

	// exports


/***/ },
/* 227 */
/***/ function(module, exports) {

	/*
		MIT License http://www.opensource.org/licenses/mit-license.php
		Author Tobias Koppers @sokra
	*/
	// css base code, injected by the css-loader
	module.exports = function () {
		var list = [];

		// return the list of modules as css string
		list.toString = function toString() {
			var result = [];
			for (var i = 0; i < this.length; i++) {
				var item = this[i];
				if (item[2]) {
					result.push("@media " + item[2] + "{" + item[1] + "}");
				} else {
					result.push(item[1]);
				}
			}
			return result.join("");
		};

		// import a list of modules into the list
		list.i = function (modules, mediaQuery) {
			if (typeof modules === "string") modules = [[null, modules, ""]];
			var alreadyImportedModules = {};
			for (var i = 0; i < this.length; i++) {
				var id = this[i][0];
				if (typeof id === "number") alreadyImportedModules[id] = true;
			}
			for (i = 0; i < modules.length; i++) {
				var item = modules[i];
				// skip already imported module
				// this implementation is not 100% perfect for weird media query combinations
				//  when a module is imported multiple times with different media queries.
				//  I hope this will never occur (Hey this way we have smaller bundles)
				if (typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) {
					if (mediaQuery && !item[2]) {
						item[2] = mediaQuery;
					} else if (mediaQuery) {
						item[2] = "(" + item[2] + ") and (" + mediaQuery + ")";
					}
					list.push(item);
				}
			}
		};
		return list;
	};

/***/ },
/* 228 */
/***/ function(module, exports, __webpack_require__) {

	/*
		MIT License http://www.opensource.org/licenses/mit-license.php
		Author Tobias Koppers @sokra
	*/
	var stylesInDom = {},
		memoize = function(fn) {
			var memo;
			return function () {
				if (typeof memo === "undefined") memo = fn.apply(this, arguments);
				return memo;
			};
		},
		isOldIE = memoize(function() {
			return /msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase());
		}),
		getHeadElement = memoize(function () {
			return document.head || document.getElementsByTagName("head")[0];
		}),
		singletonElement = null,
		singletonCounter = 0,
		styleElementsInsertedAtTop = [];

	module.exports = function(list, options) {
		if(false) {
			if(typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");
		}

		options = options || {};
		// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
		// tags it will allow on a page
		if (typeof options.singleton === "undefined") options.singleton = isOldIE();

		// By default, add <style> tags to the bottom of <head>.
		if (typeof options.insertAt === "undefined") options.insertAt = "bottom";

		var styles = listToStyles(list);
		addStylesToDom(styles, options);

		return function update(newList) {
			var mayRemove = [];
			for(var i = 0; i < styles.length; i++) {
				var item = styles[i];
				var domStyle = stylesInDom[item.id];
				domStyle.refs--;
				mayRemove.push(domStyle);
			}
			if(newList) {
				var newStyles = listToStyles(newList);
				addStylesToDom(newStyles, options);
			}
			for(var i = 0; i < mayRemove.length; i++) {
				var domStyle = mayRemove[i];
				if(domStyle.refs === 0) {
					for(var j = 0; j < domStyle.parts.length; j++)
						domStyle.parts[j]();
					delete stylesInDom[domStyle.id];
				}
			}
		};
	}

	function addStylesToDom(styles, options) {
		for(var i = 0; i < styles.length; i++) {
			var item = styles[i];
			var domStyle = stylesInDom[item.id];
			if(domStyle) {
				domStyle.refs++;
				for(var j = 0; j < domStyle.parts.length; j++) {
					domStyle.parts[j](item.parts[j]);
				}
				for(; j < item.parts.length; j++) {
					domStyle.parts.push(addStyle(item.parts[j], options));
				}
			} else {
				var parts = [];
				for(var j = 0; j < item.parts.length; j++) {
					parts.push(addStyle(item.parts[j], options));
				}
				stylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};
			}
		}
	}

	function listToStyles(list) {
		var styles = [];
		var newStyles = {};
		for(var i = 0; i < list.length; i++) {
			var item = list[i];
			var id = item[0];
			var css = item[1];
			var media = item[2];
			var sourceMap = item[3];
			var part = {css: css, media: media, sourceMap: sourceMap};
			if(!newStyles[id])
				styles.push(newStyles[id] = {id: id, parts: [part]});
			else
				newStyles[id].parts.push(part);
		}
		return styles;
	}

	function insertStyleElement(options, styleElement) {
		var head = getHeadElement();
		var lastStyleElementInsertedAtTop = styleElementsInsertedAtTop[styleElementsInsertedAtTop.length - 1];
		if (options.insertAt === "top") {
			if(!lastStyleElementInsertedAtTop) {
				head.insertBefore(styleElement, head.firstChild);
			} else if(lastStyleElementInsertedAtTop.nextSibling) {
				head.insertBefore(styleElement, lastStyleElementInsertedAtTop.nextSibling);
			} else {
				head.appendChild(styleElement);
			}
			styleElementsInsertedAtTop.push(styleElement);
		} else if (options.insertAt === "bottom") {
			head.appendChild(styleElement);
		} else {
			throw new Error("Invalid value for parameter 'insertAt'. Must be 'top' or 'bottom'.");
		}
	}

	function removeStyleElement(styleElement) {
		styleElement.parentNode.removeChild(styleElement);
		var idx = styleElementsInsertedAtTop.indexOf(styleElement);
		if(idx >= 0) {
			styleElementsInsertedAtTop.splice(idx, 1);
		}
	}

	function createStyleElement(options) {
		var styleElement = document.createElement("style");
		styleElement.type = "text/css";
		insertStyleElement(options, styleElement);
		return styleElement;
	}

	function createLinkElement(options) {
		var linkElement = document.createElement("link");
		linkElement.rel = "stylesheet";
		insertStyleElement(options, linkElement);
		return linkElement;
	}

	function addStyle(obj, options) {
		var styleElement, update, remove;

		if (options.singleton) {
			var styleIndex = singletonCounter++;
			styleElement = singletonElement || (singletonElement = createStyleElement(options));
			update = applyToSingletonTag.bind(null, styleElement, styleIndex, false);
			remove = applyToSingletonTag.bind(null, styleElement, styleIndex, true);
		} else if(obj.sourceMap &&
			typeof URL === "function" &&
			typeof URL.createObjectURL === "function" &&
			typeof URL.revokeObjectURL === "function" &&
			typeof Blob === "function" &&
			typeof btoa === "function") {
			styleElement = createLinkElement(options);
			update = updateLink.bind(null, styleElement);
			remove = function() {
				removeStyleElement(styleElement);
				if(styleElement.href)
					URL.revokeObjectURL(styleElement.href);
			};
		} else {
			styleElement = createStyleElement(options);
			update = applyToTag.bind(null, styleElement);
			remove = function() {
				removeStyleElement(styleElement);
			};
		}

		update(obj);

		return function updateStyle(newObj) {
			if(newObj) {
				if(newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap)
					return;
				update(obj = newObj);
			} else {
				remove();
			}
		};
	}

	var replaceText = (function () {
		var textStore = [];

		return function (index, replacement) {
			textStore[index] = replacement;
			return textStore.filter(Boolean).join('\n');
		};
	})();

	function applyToSingletonTag(styleElement, index, remove, obj) {
		var css = remove ? "" : obj.css;

		if (styleElement.styleSheet) {
			styleElement.styleSheet.cssText = replaceText(index, css);
		} else {
			var cssNode = document.createTextNode(css);
			var childNodes = styleElement.childNodes;
			if (childNodes[index]) styleElement.removeChild(childNodes[index]);
			if (childNodes.length) {
				styleElement.insertBefore(cssNode, childNodes[index]);
			} else {
				styleElement.appendChild(cssNode);
			}
		}
	}

	function applyToTag(styleElement, obj) {
		var css = obj.css;
		var media = obj.media;

		if(media) {
			styleElement.setAttribute("media", media)
		}

		if(styleElement.styleSheet) {
			styleElement.styleSheet.cssText = css;
		} else {
			while(styleElement.firstChild) {
				styleElement.removeChild(styleElement.firstChild);
			}
			styleElement.appendChild(document.createTextNode(css));
		}
	}

	function updateLink(linkElement, obj) {
		var css = obj.css;
		var sourceMap = obj.sourceMap;

		if(sourceMap) {
			// http://stackoverflow.com/a/26603875
			css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + " */";
		}

		var blob = new Blob([css], { type: "text/css" });

		var oldSrc = linkElement.href;

		linkElement.href = URL.createObjectURL(blob);

		if(oldSrc)
			URL.revokeObjectURL(oldSrc);
	}


/***/ },
/* 229 */
/***/ function(module, exports, __webpack_require__) {

	// style-loader: Adds some css to the DOM by adding a <style> tag

	// load the styles
	var content = __webpack_require__(230);
	if(typeof content === 'string') content = [[module.id, content, '']];
	// add the styles to the DOM
	var update = __webpack_require__(228)(content, {});
	if(content.locals) module.exports = content.locals;
	// Hot Module Replacement
	if(false) {
		// When the styles change, update the <style> tags
		if(!content.locals) {
			module.hot.accept("!!./../css-loader/index.js!./awesomplete.css", function() {
				var newContent = require("!!./../css-loader/index.js!./awesomplete.css");
				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
				update(newContent);
			});
		}
		// When the module is disposed, remove the <style> tags
		module.hot.dispose(function() { update(); });
	}

/***/ },
/* 230 */
/***/ function(module, exports, __webpack_require__) {

	exports = module.exports = __webpack_require__(227)();
	// imports


	// module
	exports.push([module.id, "[hidden] { display: none; }\n\n.visually-hidden {\n\tposition: absolute;\n\tclip: rect(0, 0, 0, 0);\n}\n\ndiv.awesomplete {\n\tdisplay: inline-block;\n\tposition: relative;\n}\n\ndiv.awesomplete > input {\n\tdisplay: block;\n}\n\ndiv.awesomplete > ul {\n\tposition: absolute;\n\tleft: 0;\n\tz-index: 1;\n\tmin-width: 100%;\n\tbox-sizing: border-box;\n\tlist-style: none;\n\tpadding: 0;\n\tborder-radius: .3em;\n\tmargin: .2em 0 0;\n\tbackground: hsla(0,0%,100%,.9);\n\tbackground: linear-gradient(to bottom right, white, hsla(0,0%,100%,.8));\n\tborder: 1px solid rgba(0,0,0,.3);\n\tbox-shadow: .05em .2em .6em rgba(0,0,0,.2);\n\ttext-shadow: none;\n}\n\ndiv.awesomplete > ul[hidden],\ndiv.awesomplete > ul:empty {\n\tdisplay: none;\n}\n\n@supports (transform: scale(0)) {\n\tdiv.awesomplete > ul {\n\t\ttransition: .3s cubic-bezier(.4,.2,.5,1.4);\n\t\ttransform-origin: 1.43em -.43em;\n\t}\n\t\n\tdiv.awesomplete > ul[hidden],\n\tdiv.awesomplete > ul:empty {\n\t\topacity: 0;\n\t\ttransform: scale(0);\n\t\tdisplay: block;\n\t\ttransition-timing-function: ease;\n\t}\n}\n\n\t/* Pointer */\n\tdiv.awesomplete > ul:before {\n\t\tcontent: \"\";\n\t\tposition: absolute;\n\t\ttop: -.43em;\n\t\tleft: 1em;\n\t\twidth: 0; height: 0;\n\t\tpadding: .4em;\n\t\tbackground: white;\n\t\tborder: inherit;\n\t\tborder-right: 0;\n\t\tborder-bottom: 0;\n\t\t-webkit-transform: rotate(45deg);\n\t\ttransform: rotate(45deg);\n\t}\n\n\tdiv.awesomplete > ul > li {\n\t\tposition: relative;\n\t\tpadding: .2em .5em;\n\t\tcursor: pointer;\n\t}\n\t\n\tdiv.awesomplete > ul > li:hover {\n\t\tbackground: hsl(200, 40%, 80%);\n\t\tcolor: black;\n\t}\n\t\n\tdiv.awesomplete > ul > li[aria-selected=\"true\"] {\n\t\tbackground: hsl(205, 40%, 40%);\n\t\tcolor: white;\n\t}\n\t\n\t\tdiv.awesomplete mark {\n\t\t\tbackground: hsl(65, 100%, 50%);\n\t\t}\n\t\t\n\t\tdiv.awesomplete li:hover mark {\n\t\t\tbackground: hsl(68, 100%, 41%);\n\t\t}\n\t\t\n\t\tdiv.awesomplete li[aria-selected=\"true\"] mark {\n\t\t\tbackground: hsl(86, 100%, 21%);\n\t\t\tcolor: inherit;\n\t\t}", ""]);

	// exports


/***/ },
/* 231 */
/***/ function(module, exports, __webpack_require__) {

	var ini_sidebar = __webpack_require__(192);
	var set_up_filters = __webpack_require__(232);
	var set_up_search = __webpack_require__(237);
	var set_up_reorder = __webpack_require__(238);
	var set_sidebar_ini_view = __webpack_require__(239);
	var make_icons = __webpack_require__(240);
	var make_modals = __webpack_require__(242);
	var set_up_opacity_slider = __webpack_require__(244);
	var make_colorbar = __webpack_require__(245);

	/* Represents sidebar with controls.
	 */
	module.exports = function sidebar(cgm) {

	  var params = cgm.params;

	  var sidebar = d3.select(params.root + ' .sidebar_wrapper');

	  // console.log('is_expand ',params.viz.is_expand)

	  if (params.viz.is_expand) {
	    sidebar.style('display', 'none');
	  }

	  sidebar.append('div').classed('title_section', true);

	  if (params.sidebar.title != null) {
	    sidebar.select('.title_section').append('h4')
	    // .style('margin-left', params.sidebar.title_margin_left+'px')
	    .style('margin-left', '20px').style('margin-top', '5px').style('margin-bottom', '0px').text(params.sidebar.title);
	  }

	  sidebar.append('div').style('padding-right', '2px').classed('about_section', true);

	  if (params.sidebar.about != null) {

	    sidebar.select('.about_section').append('h5').classed('sidebar_text', true).style('margin-left', '7px').style('margin-top', '5px').style('margin-bottom', '2px').style('text-align', 'justify').html(params.sidebar.about);
	  }

	  sidebar.append('div').classed('icons_section', true).style('text-align', 'center');

	  if (cgm.params.make_modals) {
	    make_modals(params);
	  }

	  if (params.sidebar.icons) {
	    make_icons(cgm, sidebar);
	  }

	  set_up_reorder(params, sidebar);

	  set_up_search(sidebar, params);

	  set_up_opacity_slider(sidebar);

	  var possible_filter_names = _.keys(params.viz.possible_filters);

	  if (possible_filter_names.indexOf('enr_score_type') > -1) {
	    possible_filter_names.sort(function (a, b) {
	      return a.toLowerCase().localeCompare(b.toLowerCase());
	    });
	  }

	  cgm.slider_functions = {};

	  _.each(possible_filter_names, function (inst_filter) {
	    set_up_filters(cgm, inst_filter);
	  });

	  ini_sidebar(cgm);

	  // when initializing the visualization using a view
	  if (params.ini_view !== null) {

	    set_sidebar_ini_view(params);

	    params.ini_view = null;
	  }

	  make_colorbar(cgm);
		};

/***/ },
/* 232 */
/***/ function(module, exports, __webpack_require__) {

	var make_slider_filter = __webpack_require__(233);
	var make_button_filter = __webpack_require__(236);

	module.exports = function set_up_filters(cgm, filter_type) {

	  var params = cgm.params;

	  var div_filters = d3.select(params.root + ' .sidebar_wrapper').append('div').classed('div_filters', true).style('padding-left', '10px').style('padding-right', '10px');

	  if (params.viz.possible_filters[filter_type] == 'numerical') {
	    make_slider_filter(cgm, filter_type, div_filters);
	  } else if (params.viz.possible_filters[filter_type] == 'categorical') {
	    make_button_filter(cgm, filter_type, div_filters);
	  }
		};

/***/ },
/* 233 */
/***/ function(module, exports, __webpack_require__) {

	var make_filter_title = __webpack_require__(215);
	var run_filter_slider = __webpack_require__(234);
	var get_filter_default_state = __webpack_require__(5);
	var get_subset_views = __webpack_require__(12);

	d3.slider = __webpack_require__(222);

	module.exports = function make_slider_filter(cgm, filter_type, div_filters) {

	  var params = cgm.params;
	  var inst_view = {};

	  var possible_filters = _.keys(params.viz.possible_filters);

	  _.each(possible_filters, function (tmp_filter) {
	    if (tmp_filter != filter_type) {
	      var default_state = get_filter_default_state(params.viz.filter_data, tmp_filter);
	      inst_view[tmp_filter] = default_state;
	    }
	  });

	  var filter_title = make_filter_title(params, filter_type);

	  div_filters.append('div').classed('title_' + filter_type, true).classed('sidebar_text', true).classed('slider_description', true).style('margin-top', '5px').style('margin-bottom', '3px').text(filter_title.text + filter_title.state + filter_title.suffix);

	  div_filters.append('div').classed('slider_' + filter_type, true).classed('slider', true).attr('current_state', filter_title.state);

	  var views = params.network_data.views;

	  var available_views = get_subset_views(params, views, inst_view);

	  // sort available views by filter_type value
	  available_views = available_views.sort(function (a, b) {
	    return b[filter_type] - a[filter_type];
	  });

	  var inst_max = available_views.length - 1;

	  var ini_value = 0;
	  // change the starting position of the slider if necessary
	  if (params.requested_view !== null && filter_type in params.requested_view) {

	    var inst_filter_value = params.requested_view[filter_type];

	    if (inst_filter_value != 'all') {

	      var found_value = available_views.map(function (e) {
	        return e[filter_type];
	      }).indexOf(inst_filter_value);

	      if (found_value > 0) {
	        ini_value = found_value;
	      }
	    }
	  }

	  // Filter Slider
	  //////////////////////////////////////////////////////////////////////
	  var slide_filter_fun = d3.slider().value(ini_value).min(0).max(inst_max).step(1).on('slide', function (evt, value) {
	    run_filter_slider_db(cgm, filter_type, available_views, value);
	  }).on('slideend', function (evt, value) {
	    run_filter_slider_db(cgm, filter_type, available_views, value);
	  });

	  // save slider function in order to reset value later
	  cgm.slider_functions[filter_type] = slide_filter_fun;

	  d3.select(cgm.params.root + ' .slider_' + filter_type).call(slide_filter_fun);

	  //////////////////////////////////////////////////////////////////////

	  var run_filter_slider_db = _.debounce(run_filter_slider, 800);
		};

/***/ },
/* 234 */
/***/ function(module, exports, __webpack_require__) {

	var update_viz_with_view = __webpack_require__(177);
	var reset_other_filter_sliders = __webpack_require__(214);
	var get_current_orders = __webpack_require__(235);
	var make_requested_view = __webpack_require__(14);

	module.exports = function run_filter_slider(cgm, filter_type, available_views, inst_index) {

	  // only update if not running update
	  if (d3.select(cgm.params.viz.viz_svg).classed('running_update') === false) {

	    var params = cgm.params;

	    // get value
	    var inst_state = available_views[inst_index][filter_type];

	    reset_other_filter_sliders(cgm, filter_type, inst_state);

	    params = get_current_orders(params);

	    var requested_view = {};
	    requested_view[filter_type] = inst_state;

	    requested_view = make_requested_view(params, requested_view);

	    if (_.has(available_views[0], 'enr_score_type')) {
	      var enr_state = d3.select(params.root + ' .toggle_enr_score_type').attr('current_state');

	      requested_view.enr_score_type = enr_state;
	    }

	    update_viz_with_view(cgm, requested_view);
	  }
		};

/***/ },
/* 235 */
/***/ function(module, exports) {

	module.exports = function get_current_orders(params) {

	  // get current orders
	  var other_rc;
	  _.each(['row', 'col'], function (inst_rc) {

	    if (inst_rc === 'row') {
	      other_rc = 'col';
	    } else {
	      other_rc = 'row';
	    }

	    if (d3.select(params.root + ' .toggle_' + other_rc + '_order .active').empty() === false) {

	      params.viz.inst_order[inst_rc] = d3.select(params.root + ' .toggle_' + other_rc + '_order').select('.active').attr('name');
	    } else {

	      // default to cluster ordering
	      params.viz.inst_order[inst_rc] = 'clust';
	    }
	  });

	  return params;
	};

/***/ },
/* 236 */
/***/ function(module, exports, __webpack_require__) {

	// var update_network = require('../network/update_network');
	var make_requested_view = __webpack_require__(14);

	module.exports = function make_button_filter(config, params, filter_type, div_filters) {

	  /*
	  Enrichr specific code
	  */

	  var buttons = div_filters.append('div').classed('categorical_filter', true).classed('toggle_' + filter_type, true).classed('btn-group-vertical', true).style('width', '100%').style('margin-top', '10px').attr('current_state', 'combined_score');

	  var filter_options = params.viz.filter_data[filter_type];

	  var button_dict = {
	    'combined_score': 'Combined Score',
	    'pval': 'P-Value',
	    'zscore': 'Z-score'
	  };

	  buttons.selectAll('button').data(filter_options).enter().append('button').attr('type', 'button').classed('btn', true).classed('btn-primary', true).classed('.filter_button', true).classed('active', function (d) {
	    var is_active = false;
	    if (d == 'combined_score') {
	      is_active = true;
	    }
	    return is_active;
	  }).attr('name', function (d) {
	    return d;
	  }).html(function (d) {
	    return button_dict[d];
	  });

	  $(params.root + ' .categorical_filter .btn').off().click(function () {

	    d3.selectAll(params.root + ' .categorical_filter .btn').classed('active', false);

	    d3.select(this).classed('active', true);

	    var inst_state = d3.select(this).attr('name');

	    var requested_view = { 'enr_score_type': inst_state };

	    make_requested_view(params, requested_view);

	    d3.select(params.root + ' .toggle_enr_score_type').attr('current_state', inst_state);
	  });
		};

/***/ },
/* 237 */
/***/ function(module, exports) {

	module.exports = function set_up_search(sidebar, params) {

	  var search_container = sidebar.append('div')
	  // .classed('row',true)
	  .classed('gene_search_container', true).style('padding-left', '10px').style('padding-right', '10px').style('margin-top', '10px');

	  search_container.append('input').classed('form-control', true).classed('gene_search_box', true).classed('sidebar_text', true).attr('type', 'text').attr('placeholder', params.sidebar.row_search.placeholder).style('height', params.sidebar.row_search.box.height + 'px').style('margin-top', '10px');

	  search_container.append('div').classed('gene_search_button', true).style('margin-top', '5px').attr('data-toggle', 'buttons').append('button').classed('sidebar_text', true).html('Search').attr('type', 'button').classed('btn', true).classed('btn-primary', true).classed('submit_gene_button', true).style('width', '100%').style('font-size', '14px');
		};

/***/ },
/* 238 */
/***/ function(module, exports) {

	// var get_cat_title = require('../categories/get_cat_title');

	module.exports = function set_up_reorder(params, sidebar) {

	  var button_dict;
	  var tmp_orders;
	  var rc_dict = { 'row': 'Row', 'col': 'Column', 'both': '' };
	  var is_active;
	  var inst_reorder;
	  // var all_cats;
	  // var inst_order_label;

	  var reorder_section = sidebar.append('div').style('padding-left', '10px').style('padding-right', '10px').classed('reorder_section', true);

	  var reorder_types;
	  if (params.sim_mat) {
	    reorder_types = ['both'];
	  } else {
	    reorder_types = ['row', 'col'];
	  }

	  _.each(reorder_types, function (inst_rc) {

	    button_dict = {
	      'clust': 'Cluster',
	      'rank': 'Rank by Sum',
	      'rankvar': 'Rank by Variance',
	      'ini': 'Initial Order',
	      'alpha': 'Alphabetically'
	    };

	    var other_rc;
	    if (inst_rc === 'row') {
	      other_rc = 'col';
	    } else {
	      other_rc = 'row';
	    }

	    tmp_orders = Object.keys(params.matrix.orders);

	    var possible_orders = [];

	    _.each(tmp_orders, function (inst_name) {

	      if (inst_name.indexOf(other_rc) > -1) {
	        inst_name = inst_name.replace('_row', '').replace('_col', '');

	        if (inst_name.indexOf('cat_') < 0) {
	          possible_orders.push(inst_name);
	        }
	      }
	    });

	    // specific to Enrichr
	    if (_.keys(params.viz.filter_data).indexOf('enr_score_type') > -1) {
	      possible_orders = ['clust', 'rank'];
	    }

	    possible_orders = _.uniq(possible_orders);

	    possible_orders = possible_orders.sort();

	    var reorder_text;
	    if (inst_rc != 'both') {
	      reorder_text = ' Order';
	    } else {
	      reorder_text = 'Reorder Matrix';
	    }

	    reorder_section.append('div').classed('sidebar_button_text', true).style('clear', 'both').style('margin-top', '10px').html(rc_dict[inst_rc] + reorder_text);

	    inst_reorder = reorder_section.append('div').classed('btn-group-vertical', true).style('width', '100%').classed('toggle_' + inst_rc + '_order', true).attr('role', 'group');

	    inst_reorder.selectAll('.button').data(possible_orders).enter().append('button').attr('type', 'button').classed('btn', true).classed('btn-primary', true).classed('sidebar_button_text', true).classed('active', function (d) {
	      is_active = false;
	      if (d == params.viz.inst_order[other_rc]) {
	        is_active = true;
	      }
	      return is_active;
	    }).attr('name', function (d) {
	      return d;
	    }).html(function (d) {
	      return button_dict[d];
	    });
	  });
		};

/***/ },
/* 239 */
/***/ function(module, exports, __webpack_require__) {

	var make_filter_title = __webpack_require__(215);

	module.exports = function set_sidebar_ini_view(params) {

	  _.each(_.keys(params.ini_view), function (inst_filter) {

	    // initialize filter slider using ini_view
	    var inst_value = params.ini_view[inst_filter];

	    var filter_type = params.viz.possible_filters[inst_filter];

	    if (filter_type === 'numerical') {

	      if (inst_value != 'all') {
	        inst_value = parseInt(inst_value, 10);
	      }

	      if (params.viz.filter_data[inst_filter].indexOf(inst_value) <= -1) {
	        inst_value = 'all';
	      }

	      var filter_title = make_filter_title(params, inst_filter);

	      d3.select(params.root + ' .title_' + inst_filter).text(filter_title.text + inst_value + filter_title.suffix);

	      d3.select(params.root + ' .slider_' + inst_filter).attr('current_state', inst_value);
	    } else {

	      // set up button initialization

	    }
	  });
		};

/***/ },
/* 240 */
/***/ function(module, exports, __webpack_require__) {

	var file_saver = __webpack_require__(217);
	var two_translate_zoom = __webpack_require__(116);
	var deactivate_cropping = __webpack_require__(221);
	var save_svg_png = __webpack_require__(241);

	module.exports = function make_icons(cgm, sidebar) {

	  var params = cgm.params;
	  // var saveSvgAsPng = save_svg_png();
	  var saveAs = file_saver();

	  var row = sidebar.select('.icons_section').style('margin-top', '7px').style('margin-left', '5%');

	  var width_pct = '22%';
	  var padding_left = '0px';
	  var padding_right = '0px';

	  row.append('div').classed('clust_icon', true).style('float', 'left').style('width', width_pct).style('padding-left', padding_left).style('padding-right', padding_right).append('i').classed('fa', true).classed('fa-share-alt', true).classed('icon_buttons', true).style('font-size', '25px').on('click', function () {
	    $(params.root + ' .share_info').modal('toggle');
	    $('.share_url').val(window.location.href);
	  }).classed('sidebar_tooltip', true).append('span').classed('sidebar_tooltip_text', true).html('Share').style('left', '0%');

	  row.append('div').classed('clust_icon', true).style('float', 'left').style('width', width_pct).style('padding-left', padding_left).style('padding-right', padding_right).append('i').classed('fa', true).classed('fa-camera', true).classed('icon_buttons', true).style('font-size', '25px').on('click', function () {

	    $(params.root + ' .picture_info').modal('toggle');
	  }).classed('sidebar_tooltip', true).append('span').classed('sidebar_tooltip_text', true).html('Take snapshot').style('left', '-100%');

	  row.append('div').classed('clust_icon', true).style('float', 'left').style('width', width_pct).style('padding-left', padding_left).style('padding-right', padding_right).append('i').classed('fa', true).classed('fa fa-cloud-download', true).classed('icon_buttons', true).style('font-size', '25px').on('click', function () {

	    cgm.save_matrix();
	  }).classed('sidebar_tooltip', true).append('span').classed('sidebar_tooltip_text', true).html('Download matrix').style('left', '-200%');

	  row.append('div').classed('clust_icon', true).style('float', 'left').style('width', width_pct).style('padding-left', padding_left).style('padding-right', '-5px').append('i').classed('fa', true).classed('fa-crop', true).classed('crop_button', true).classed('icon_buttons', true).style('font-size', '25px').on('click', function () {

	    // do nothing if dendro filtering has been done
	    if (cgm.params.dendro_filter.row === false && cgm.params.dendro_filter.col === false) {

	      var is_crop = d3.select(this).classed('fa-crop');

	      var is_undo = d3.select(this).classed('fa-undo');

	      // press crop button (can be active/incative)
	      if (is_crop) {

	        // keep list of names to return to state
	        cgm.params.crop_filter_nodes = {};
	        cgm.params.crop_filter_nodes.row_nodes = cgm.params.network_data.row_nodes;
	        cgm.params.crop_filter_nodes.col_nodes = cgm.params.network_data.col_nodes;

	        cgm.brush_crop_matrix();

	        if (d3.select(this).classed('active_cropping') === false) {

	          // set active_cropping (button turns red)
	          d3.select(this).classed('active_cropping', true).style('color', 'red');
	        } else {
	          // deactivate cropping (button turns blue)
	          d3.select(this).classed('active_cropping', false).style('color', '#337ab7');

	          deactivate_cropping(cgm);
	        }
	      }

	      // press undo button
	      if (is_undo) {

	        d3.select(params.root + ' .crop_button').style('color', '#337ab7').classed('fa-crop', true).classed('fa-undo', false);

	        // cgm.filter_viz_using_names(cgm.params.crop_filter_nodes);
	        cgm.filter_viz_using_nodes(cgm.params.crop_filter_nodes);

	        // show dendro crop buttons after brush-cropping has been undone
	        d3.select(cgm.params.root + ' .col_dendro_icons_container').style('display', 'block');
	        d3.select(cgm.params.root + ' .row_dendro_icons_container').style('display', 'block');
	      }

	      two_translate_zoom(cgm, 0, 0, 1);
	    }
	  }).classed('sidebar_tooltip', true).append('span').classed('sidebar_tooltip_text', true).html('Crop matrix').style('left', '-400%');

	  // save svg: example from: http://bl.ocks.org/pgiraud/8955139#profile.json
	  ////////////////////////////////////////////////////////////////////////////
	  function save_clust_svg() {

	    d3.select(params.root + ' .expand_button').style('opacity', 0);

	    var html = d3.select(params.root + " .viz_svg").attr("title", "test2").attr("version", 1.1).attr("xmlns", "http://www.w3.org/2000/svg").node().parentNode.innerHTML;

	    var blob = new Blob([html], { type: "image/svg+xml" });

	    saveAs(blob, "clustergrammer.svg");

	    d3.select(params.root + ' .expand_button').style('opacity', 0.4);
	  }

	  d3.select(params.root + ' .download_buttons').append('p').append('a').html('Download SVG').on('click', function () {
	    save_clust_svg();
	  });

	  var svg_id = 'svg_' + params.root.replace('#', '');

	  // save as PNG
	  /////////////////////////////////////////
	  d3.select(params.root + ' .download_buttons').append('p').append('a').html('Download PNG').on('click', function () {
	    d3.select(params.root + ' .expand_button').style('opacity', 0);
	    // saveSvgAsPng(document.getElementById(svg_id), "clustergrammer.png");
	    save_svg_png.saveSvgAsPng(document.getElementById(svg_id), "clustergrammer.png");
	    d3.select(params.root + ' .expand_button').style('opacity', 0.4);
	  });
		};

/***/ },
/* 241 */
/***/ function(module, exports, __webpack_require__) {

	var __WEBPACK_AMD_DEFINE_RESULT__;(function () {
	  var out$ = typeof exports != 'undefined' && exports || "function" != 'undefined' && {} || this;

	  var doctype = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [<!ENTITY nbsp "&#160;">]>';

	  function isElement(obj) {
	    return obj instanceof HTMLElement || obj instanceof SVGElement;
	  }

	  function requireDomNode(el) {
	    if (!isElement(el)) {
	      throw new Error('an HTMLElement or SVGElement is required; got ' + el);
	    }
	  }

	  function isExternal(url) {
	    return url && url.lastIndexOf('http', 0) == 0 && url.lastIndexOf(window.location.host) == -1;
	  }

	  function inlineImages(el, callback) {
	    requireDomNode(el);

	    var images = el.querySelectorAll('image'),
	        left = images.length,
	        checkDone = function () {
	      if (left === 0) {
	        callback();
	      }
	    };

	    checkDone();
	    for (var i = 0; i < images.length; i++) {
	      (function (image) {
	        var href = image.getAttributeNS("http://www.w3.org/1999/xlink", "href");
	        if (href) {
	          if (isExternal(href.value)) {
	            console.warn("Cannot render embedded images linking to external hosts: " + href.value);
	            return;
	          }
	        }
	        var canvas = document.createElement('canvas');
	        var ctx = canvas.getContext('2d');
	        var img = new Image();
	        img.crossOrigin = "anonymous";
	        href = href || image.getAttribute('href');
	        if (href) {
	          img.src = href;
	          img.onload = function () {
	            canvas.width = img.width;
	            canvas.height = img.height;
	            ctx.drawImage(img, 0, 0);
	            image.setAttributeNS("http://www.w3.org/1999/xlink", "href", canvas.toDataURL('image/png'));
	            left--;
	            checkDone();
	          };
	          img.onerror = function () {
	            console.log("Could not load " + href);
	            left--;
	            checkDone();
	          };
	        } else {
	          left--;
	          checkDone();
	        }
	      })(images[i]);
	    }
	  }

	  function styles(el, options, cssLoadedCallback) {
	    var selectorRemap = options.selectorRemap;
	    var modifyStyle = options.modifyStyle;
	    var css = "";
	    // each font that has extranl link is saved into queue, and processed
	    // asynchronously
	    var fontsQueue = [];
	    var sheets = document.styleSheets;
	    for (var i = 0; i < sheets.length; i++) {
	      try {
	        var rules = sheets[i].cssRules;
	      } catch (e) {
	        console.warn("Stylesheet could not be loaded: " + sheets[i].href);
	        continue;
	      }

	      if (rules != null) {
	        for (var j = 0, match; j < rules.length; j++, match = null) {
	          var rule = rules[j];
	          if (typeof rule.style != "undefined") {
	            var selectorText;

	            try {
	              selectorText = rule.selectorText;
	            } catch (err) {
	              console.warn('The following CSS rule has an invalid selector: "' + rule + '"', err);
	            }

	            try {
	              if (selectorText) {
	                match = el.querySelector(selectorText);
	              }
	            } catch (err) {
	              console.warn('Invalid CSS selector "' + selectorText + '"', err);
	            }

	            if (match) {
	              var selector = selectorRemap ? selectorRemap(rule.selectorText) : rule.selectorText;
	              var cssText = modifyStyle ? modifyStyle(rule.style.cssText) : rule.style.cssText;
	              css += selector + " { " + cssText + " }\n";
	            } else if (rule.cssText.match(/^@font-face/)) {
	              // below we are trying to find matches to external link. E.g.
	              // @font-face {
	              //   // ...
	              //   src: local('Abel'), url(https://fonts.gstatic.com/s/abel/v6/UzN-iejR1VoXU2Oc-7LsbvesZW2xOQ-xsNqO47m55DA.woff2);
	              // }
	              //
	              // This regex will save extrnal link into first capture group
	              var fontUrlRegexp = /url\(["']?(.+?)["']?\)/;
	              // TODO: This needs to be changed to support multiple url declarations per font.
	              var fontUrlMatch = rule.cssText.match(fontUrlRegexp);

	              var externalFontUrl = fontUrlMatch && fontUrlMatch[1] || '';
	              var fontUrlIsDataURI = externalFontUrl.match(/^data:/);
	              if (fontUrlIsDataURI) {
	                // We should ignore data uri - they are already embedded
	                externalFontUrl = '';
	              }

	              if (externalFontUrl) {
	                // okay, we are lucky. We can fetch this font later
	                fontsQueue.push({
	                  text: rule.cssText,
	                  // Pass url regex, so that once font is downladed, we can run `replace()` on it
	                  fontUrlRegexp: fontUrlRegexp,
	                  format: getFontMimeTypeFromUrl(externalFontUrl),
	                  url: externalFontUrl
	                });
	              } else {
	                // otherwise, use previous logic
	                css += rule.cssText + '\n';
	              }
	            }
	          }
	        }
	      }
	    }

	    // Now all css is processed, it's time to handle scheduled fonts
	    processFontQueue(fontsQueue);

	    function getFontMimeTypeFromUrl(fontUrl) {
	      var supportedFormats = {
	        'woff2': 'font/woff2',
	        'woff': 'font/woff',
	        'otf': 'application/x-font-opentype',
	        'ttf': 'application/x-font-ttf',
	        'eot': 'application/vnd.ms-fontobject',
	        'sfnt': 'application/font-sfnt',
	        'svg': 'image/svg+xml'
	      };
	      var extensions = Object.keys(supportedFormats);
	      for (var i = 0; i < extensions.length; ++i) {
	        var extension = extensions[i];
	        // TODO: This is not bullet proof, it needs to handle edge cases...
	        if (fontUrl.indexOf('.' + extension) > 0) {
	          return supportedFormats[extension];
	        }
	      }

	      // If you see this error message, you probably need to update code above.
	      console.error('Unknown font format for ' + fontUrl + '; Fonts may not be working correctly');
	      return 'application/octet-stream';
	    }

	    function processFontQueue(queue) {
	      if (queue.length > 0) {
	        // load fonts one by one until we have anything in the queue:
	        var font = queue.pop();
	        processNext(font);
	      } else {
	        // no more fonts to load.
	        cssLoadedCallback(css);
	      }

	      function processNext(font) {
	        // TODO: This could benefit from caching.
	        var oReq = new XMLHttpRequest();
	        oReq.addEventListener('load', fontLoaded);
	        oReq.addEventListener('error', transferFailed);
	        oReq.addEventListener('abort', transferFailed);
	        oReq.open('GET', font.url);
	        oReq.responseType = 'arraybuffer';
	        oReq.send();

	        function fontLoaded() {
	          // TODO: it may be also worth to wait until fonts are fully loaded before
	          // attempting to rasterize them. (e.g. use https://developer.mozilla.org/en-US/docs/Web/API/FontFaceSet )
	          var fontBits = oReq.response;
	          var fontInBase64 = arrayBufferToBase64(fontBits);
	          updateFontStyle(font, fontInBase64);
	        }

	        function transferFailed(e) {
	          console.warn('Failed to load font from: ' + font.url);
	          console.warn(e);
	          css += font.text + '\n';
	          processFontQueue();
	        }

	        function updateFontStyle(font, fontInBase64) {
	          var dataUrl = 'url("data:' + font.format + ';base64,' + fontInBase64 + '")';
	          css += font.text.replace(font.fontUrlRegexp, dataUrl) + '\n';

	          // schedule next font download on next tick.
	          setTimeout(function () {
	            processFontQueue(queue);
	          }, 0);
	        }
	      }
	    }

	    function arrayBufferToBase64(buffer) {
	      var binary = '';
	      var bytes = new Uint8Array(buffer);
	      var len = bytes.byteLength;

	      for (var i = 0; i < len; i++) {
	        binary += String.fromCharCode(bytes[i]);
	      }

	      return window.btoa(binary);
	    }
	  }

	  function getDimension(el, clone, dim) {
	    var v = el.viewBox && el.viewBox.baseVal && el.viewBox.baseVal[dim] || clone.getAttribute(dim) !== null && !clone.getAttribute(dim).match(/%$/) && parseInt(clone.getAttribute(dim)) || el.getBoundingClientRect()[dim] || parseInt(clone.style[dim]) || parseInt(window.getComputedStyle(el).getPropertyValue(dim));
	    return typeof v === 'undefined' || v === null || isNaN(parseFloat(v)) ? 0 : v;
	  }

	  function reEncode(data) {
	    data = encodeURIComponent(data);
	    data = data.replace(/%([0-9A-F]{2})/g, function (match, p1) {
	      var c = String.fromCharCode('0x' + p1);
	      return c === '%' ? '%25' : c;
	    });
	    return decodeURIComponent(data);
	  }

	  out$.prepareSvg = function (el, options, cb) {
	    requireDomNode(el);

	    options = options || {};
	    options.scale = options.scale || 1;
	    options.responsive = options.responsive || false;
	    var xmlns = "http://www.w3.org/2000/xmlns/";

	    inlineImages(el, function () {
	      var outer = document.createElement("div");
	      var clone = el.cloneNode(true);
	      var width, height;
	      if (el.tagName == 'svg') {
	        width = options.width || getDimension(el, clone, 'width');
	        height = options.height || getDimension(el, clone, 'height');
	      } else if (el.getBBox) {
	        var box = el.getBBox();
	        width = box.x + box.width;
	        height = box.y + box.height;
	        clone.setAttribute('transform', clone.getAttribute('transform').replace(/translate\(.*?\)/, ''));

	        var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
	        svg.appendChild(clone);
	        clone = svg;
	      } else {
	        console.error('Attempted to render non-SVG element', el);
	        return;
	      }

	      clone.setAttribute("version", "1.1");
	      if (!clone.getAttribute('xmlns')) {
	        clone.setAttributeNS(xmlns, "xmlns", "http://www.w3.org/2000/svg");
	      }
	      if (!clone.getAttribute('xmlns:xlink')) {
	        clone.setAttributeNS(xmlns, "xmlns:xlink", "http://www.w3.org/1999/xlink");
	      }

	      if (options.responsive) {
	        clone.removeAttribute('width');
	        clone.removeAttribute('height');
	        clone.setAttribute('preserveAspectRatio', 'xMinYMin meet');
	      } else {
	        clone.setAttribute("width", width * options.scale);
	        clone.setAttribute("height", height * options.scale);
	      }

	      clone.setAttribute("viewBox", [options.left || 0, options.top || 0, width, height].join(" "));

	      var fos = clone.querySelectorAll('foreignObject > *');
	      for (var i = 0; i < fos.length; i++) {
	        if (!fos[i].getAttribute('xmlns')) {
	          fos[i].setAttributeNS(xmlns, "xmlns", "http://www.w3.org/1999/xhtml");
	        }
	      }

	      outer.appendChild(clone);

	      // In case of custom fonts we need to fetch font first, and then inline
	      // its url into data-uri format (encode as base64). That's why style
	      // processing is done asynchonously. Once all inlining is finshed
	      // cssLoadedCallback() is called.
	      styles(el, options, cssLoadedCallback);

	      function cssLoadedCallback(css) {
	        // here all fonts are inlined, so that we can render them properly.
	        var s = document.createElement('style');
	        s.setAttribute('type', 'text/css');
	        s.innerHTML = "<![CDATA[\n" + css + "\n]]>";
	        var defs = document.createElement('defs');
	        defs.appendChild(s);
	        clone.insertBefore(defs, clone.firstChild);

	        if (cb) {
	          var outHtml = outer.innerHTML;
	          outHtml = outHtml.replace(/NS\d+:href/gi, 'xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href');
	          cb(outHtml, width, height);
	        }
	      }
	    });
	  };

	  out$.svgAsDataUri = function (el, options, cb) {
	    out$.prepareSvg(el, options, function (svg) {
	      var uri = 'data:image/svg+xml;base64,' + window.btoa(reEncode(doctype + svg));
	      if (cb) {
	        cb(uri);
	      }
	    });
	  };

	  out$.svgAsPngUri = function (el, options, cb) {
	    requireDomNode(el);

	    options = options || {};
	    options.encoderType = options.encoderType || 'image/png';
	    options.encoderOptions = options.encoderOptions || 0.8;

	    var convertToPng = function (src, w, h) {
	      var canvas = document.createElement('canvas');
	      var context = canvas.getContext('2d');
	      canvas.width = w;
	      canvas.height = h;

	      if (options.canvg) {
	        options.canvg(canvas, src);
	      } else {
	        context.drawImage(src, 0, 0);
	      }

	      if (options.backgroundColor) {
	        context.globalCompositeOperation = 'destination-over';
	        context.fillStyle = options.backgroundColor;
	        context.fillRect(0, 0, canvas.width, canvas.height);
	      }

	      var png;
	      try {
	        png = canvas.toDataURL(options.encoderType, options.encoderOptions);
	      } catch (e) {
	        if (typeof SecurityError !== 'undefined' && e instanceof SecurityError || e.name == "SecurityError") {
	          console.error("Rendered SVG images cannot be downloaded in this browser.");
	          return;
	        } else {
	          throw e;
	        }
	      }
	      cb(png);
	    };

	    if (options.canvg) {
	      out$.prepareSvg(el, options, convertToPng);
	    } else {
	      out$.svgAsDataUri(el, options, function (uri) {
	        var image = new Image();

	        image.onload = function () {
	          convertToPng(image, image.width, image.height);
	        };

	        image.onerror = function () {
	          console.error('There was an error loading the data URI as an image on the following SVG\n', window.atob(uri.slice(26)), '\n', "Open the following link to see browser's diagnosis\n", uri);
	        };

	        image.src = uri;
	      });
	    }
	  };

	  out$.download = function (name, uri) {
	    if (navigator.msSaveOrOpenBlob) {
	      navigator.msSaveOrOpenBlob(uriToBlob(uri), name);
	    } else {
	      var saveLink = document.createElement('a');
	      var downloadSupported = 'download' in saveLink;
	      if (downloadSupported) {
	        saveLink.download = name;
	        saveLink.href = uri;
	        saveLink.style.display = 'none';
	        document.body.appendChild(saveLink);
	        saveLink.click();
	        document.body.removeChild(saveLink);
	      } else {
	        window.open(uri, '_temp', 'menubar=no,toolbar=no,status=no');
	      }
	    }
	  };

	  function uriToBlob(uri) {
	    var byteString = window.atob(uri.split(',')[1]);
	    var mimeString = uri.split(',')[0].split(':')[1].split(';')[0];
	    var buffer = new ArrayBuffer(byteString.length);
	    var intArray = new Uint8Array(buffer);
	    for (var i = 0; i < byteString.length; i++) {
	      intArray[i] = byteString.charCodeAt(i);
	    }
	    return new Blob([buffer], { type: mimeString });
	  }

	  out$.saveSvg = function (el, name, options) {
	    requireDomNode(el);

	    options = options || {};
	    out$.svgAsDataUri(el, options, function (uri) {
	      out$.download(name, uri);
	    });
	  };

	  out$.saveSvgAsPng = function (el, name, options) {
	    requireDomNode(el);

	    options = options || {};
	    out$.svgAsPngUri(el, options, function (uri) {
	      out$.download(name, uri);
	    });
	  };

	  // if define is defined create as an AMD module
	  if (true) {
	    !(__WEBPACK_AMD_DEFINE_RESULT__ = function () {
	      return out$;
	    }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
	  }
		})();

/***/ },
/* 242 */
/***/ function(module, exports, __webpack_require__) {

	var make_modal_skeleton = __webpack_require__(243);

	module.exports = function ini_modals(params) {

	  // share modal
	  ///////////////////////////////////////
	  var share_modal = make_modal_skeleton(params, 'share_info');

	  share_modal.header.append('a').attr('target', '_blank').attr('href', '/clustergrammer/');

	  share_modal.header.append('h4').classed('modal-title', true).html('Share the visualization using the current URL:');

	  share_modal.body.append('input').classed('bootstrap_highlight', true).classed('share_url', true);

	  // picture modal
	  ///////////////////////////////////////
	  var screenshot_modal = make_modal_skeleton(params, 'picture_info');

	  screenshot_modal.header.append('h4').classed('modal-title', true).html('Save a snapshot of the visualization');

	  screenshot_modal.body.append('div').classed('download_buttons', true);

	  // dendro modal
	  ///////////////////////////////////////
	  var dendro_modal = make_modal_skeleton(params, 'dendro_info');

	  dendro_modal.header.append('h4').classed('modal-title', true).html('Cluster Information');

	  dendro_modal.body.append('g').classed('cluster_info_container', true);

	  dendro_modal.body.append('div').classed('dendro_text', true).append('input').classed('bootstrap_highlight', true).classed('current_names', true).style('width', '100%');
		};

/***/ },
/* 243 */
/***/ function(module, exports) {

	module.exports = function make_modal_skeleton(params, modal_class) {

	  var modal_skeleton = {};

	  var modal = d3.select(params.root).append('div').classed('modal', true).classed('fade', true).classed(modal_class, true).attr('role', 'dialog');

	  var modal_dialog = modal.append('div').classed('modal-dialog', true);

	  var modal_content = modal_dialog.append('div').classed('modal-content', true);

	  modal_skeleton.header = modal_content.append('div').classed('modal-header', true);

	  modal_skeleton.header.append('button').attr('type', 'button').classed('close', true).attr('data-dismiss', 'modal').html('&times;');

	  modal_skeleton.body = modal_content.append('div').classed('modal-body', true);

	  return modal_skeleton;
		};

/***/ },
/* 244 */
/***/ function(module, exports) {

	module.exports = function set_up_opacity_slider(sidebar) {

	  var slider_container = sidebar.append('div').classed('opacity_slider_container', true).style('margin-top', '5px').style('padding-left', '10px').style('padding-right', '10px');

	  slider_container.append('div').classed('sidebar_text', true).classed('opacity_slider_text', true).style('margin-bottom', '3px').text('Opacity Slider');

	  slider_container.append('div').classed('slider', true).classed('opacity_slider', true);
		};

/***/ },
/* 245 */
/***/ function(module, exports) {

	module.exports = function make_colorbar(cgm) {

	  var params = cgm.params;

	  d3.select(params.root + ' .sidebar_wrapper').append('div').classed('sidebar_text', true).style('padding-left', '10px').style('padding-top', '5px').text('Matrix Values');

	  var colorbar_width = params.sidebar.width - 20;
	  var colorbar_height = 13;
	  var svg_height = 3 * colorbar_height;
	  var svg_width = 1.2 * colorbar_width;
	  var low_left_margin = 10;
	  var top_margin = 33;
	  var high_left_margin = colorbar_width + 10;
	  var bar_margin_left = 10;
	  var bar_margin_top = 3;

	  var network_data = params.network_data;

/*	  var max_link = _.max(network_data.links, function (d) {
	    return d.value;
	  }).value;

	  var min_link = _.min(network_data.links, function (d) {
	    return d.value;
	  }).value;
*/
	  var main_svg = d3.select(params.root + ' .sidebar_wrapper').append('svg').attr('height', svg_height + 'px').attr('width', svg_width + 'px');

	  //Append a defs (for definition) element to your SVG
	  var defs = main_svg.append("defs");

	  //Append a linearGradient element to the defs and give it a unique id
	  var linearGradient = defs.append("linearGradient").attr("id", "linear-gradient");

	  var special_case = 'none';

/*	  // no negative numbers
	  if (min_link >= 0) {

	    //Set the color for the start (0%)
	    linearGradient.append("stop").attr("offset", "0%").attr("stop-color", "white");

	    //Set the color for the end (100%)
	    linearGradient.append("stop").attr("offset", "100%").attr("stop-color", params.tile_colors[0]);

	    special_case = 'all_postiive';

	    // no positive numbers
	  } else if (max_link <= 0) {

	    //Set the color for the start (0%)
	    linearGradient.append("stop").attr("offset", "0%").attr("stop-color", params.tile_colors[1]);

	    //Set the color for the end (100%)
	    linearGradient.append("stop").attr("offset", "100%").attr("stop-color", "white");

	    special_case = 'all_negative';
	  }

	  // both postive and negative numbers
	  else {*/
	      //Set the color for the start (0%)
      linearGradient.append("stop").attr("offset", "0%").attr("stop-color", params.tile_colors[1]);

      //Set the color for the end (100%)
      linearGradient.append("stop").attr("offset", "50%").attr("stop-color", "white");

      //Set the color for the end (100%)
      linearGradient.append("stop").attr("offset", "100%").attr("stop-color", params.tile_colors[0]);
//	    }
	  // make colorbar
	  main_svg.append('rect').classed('background', true).attr('height', colorbar_height + 'px').attr('width', colorbar_width + 'px').attr('fill', 'url(#linear-gradient)').attr('transform', 'translate(' + bar_margin_left + ', ' + bar_margin_top + ')').attr('stroke', 'grey').attr('stroke-width', '0.25px');

	  // make title
	  ///////////////

	  var max_abs_val = Math.abs(Math.round(params.matrix.true_max * 10) / 10);
		var min_abs_val = Math.abs(Math.round(params.matrix.true_min * 10) / 10);
	  var font_size = 13;

	  main_svg.append('text').text(function () {
	    var inst_string;
	    if (params.matrix.true_min < 0) {
				inst_string = '-' + min_abs_val.toLocaleString();
	    } else {
	      inst_string = min_abs_val.toLocaleString();
	    }
	    return inst_string;
	  }).style('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif').style('font-weight', 300).style('font-size', font_size).attr('transform', 'translate(' + low_left_margin + ',' + top_margin + ')').attr('text-anchor', 'start');

	  main_svg.append('text').text(max_abs_val.toLocaleString()).text(function () {
	    return max_abs_val.toLocaleString();
	  }).style('font-family', '"Helvetica Neue", Helvetica, Arial, sans-serif').style('font-weight', 300).style('font-size', font_size).attr('transform', 'translate(' + high_left_margin + ',' + top_margin + ')').attr('text-anchor', 'end');
		};

/***/ }
/******/ ]);
//# sourceMappingURL=clustergrammer.js.map