(function webpackUniversalModuleDefinition(root, factory) {
	if(typeof exports === 'object' && typeof module === 'object')
		module.exports = factory();
	else if(typeof define === 'function' && define.amd)
		define("Vizabi", [], factory);
	else if(typeof exports === 'object')
		exports["Vizabi"] = factory();
	else
		root["Vizabi"] = factory();
})(this, function() {
return /******/ (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] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};

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

/******/ 		// Flag the module as loaded
/******/ 		module.l = 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;

/******/ 	// identity function for calling harmory imports with the correct context
/******/ 	__webpack_require__.i = function(value) { return value; };

/******/ 	// define getter function for harmory exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		Object.defineProperty(exports, name, {
/******/ 			configurable: false,
/******/ 			enumerable: true,
/******/ 			get: getter
/******/ 		});
/******/ 	};

/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__webpack_require__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__webpack_require__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};

/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };

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

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

var global    = __webpack_require__(4)
  , core      = __webpack_require__(34)
  , hide      = __webpack_require__(17)
  , redefine  = __webpack_require__(18)
  , ctx       = __webpack_require__(35)
  , PROTOTYPE = 'prototype';

var $export = function(type, name, source){
  var IS_FORCED = type & $export.F
    , IS_GLOBAL = type & $export.G
    , IS_STATIC = type & $export.S
    , IS_PROTO  = type & $export.P
    , IS_BIND   = type & $export.B
    , target    = IS_GLOBAL ? global : IS_STATIC ? global[name] || (global[name] = {}) : (global[name] || {})[PROTOTYPE]
    , exports   = IS_GLOBAL ? core : core[name] || (core[name] = {})
    , expProto  = exports[PROTOTYPE] || (exports[PROTOTYPE] = {})
    , key, own, out, exp;
  if(IS_GLOBAL)source = name;
  for(key in source){
    // contains in native
    own = !IS_FORCED && target && target[key] !== undefined;
    // export native or passed
    out = (own ? target : source)[key];
    // bind timers to global for call from export context
    exp = IS_BIND && own ? ctx(out, global) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;
    // extend global
    if(target)redefine(target, key, out, type & $export.U);
    // export
    if(exports[key] != out)hide(exports, key, exp);
    if(IS_PROTO && expProto[key] != out)expProto[key] = out;
  }
};
global.core = core;
// type bitmap
$export.F = 1;   // forced
$export.G = 2;   // global
$export.S = 4;   // static
$export.P = 8;   // proto
$export.B = 16;  // bind
$export.W = 32;  // wrap
$export.U = 64;  // safe
$export.R = 128; // real proto method for `library` 
module.exports = $export;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.setIcon = exports.pruneTree = exports.isTouchDevice = exports.debounce = exports.memoize = exports.post = exports.get = exports.ajax = exports.interpolatePoint = exports.interpolateVector = exports.nestArrayToObj = exports.hashCode = exports.clearDelay = exports.delay = exports.defer = exports.diffObject = exports.arrayLast = exports.arrayMedian = exports.arraySum = exports.arrayMean = exports.arrayMax = exports.arrayMin = exports.values = exports.keys = exports.throttle = exports.hasClass = exports.classed = exports.removeClass = exports.addClass = exports.countDecimals = exports.error = exports.groupEnd = exports.groupCollapsed = exports.warn = exports.timeStamp = exports.areaToRadius = exports.radiusToArea = exports.mapRows = exports.preventAncestorScrolling = exports.matchAny = exports.filterAny = exports.filter = exports.find = exports.uniqueLast = exports.unique = exports.without = exports.deepClone = exports.clone = exports.merge = exports.deepExtend = exports.extend = exports.forEach = exports.strToFloat = exports.roundStep = exports.findScrollableAncestor = exports.getViewportPosition = exports.comparePlainObjects = exports.arrayEquals = exports.isPlainObject = exports.isNumber = exports.isEmpty = exports.isNaN = exports.isString = exports.isDate = exports.isObject = exports.isArray = exports.isElement = exports.uniqueId = exports.approxEqual = undefined;

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

exports.makeAbsoluteContext = makeAbsoluteContext;
exports.firstBy = firstBy;

var _interpolators = __webpack_require__(453);

var _interpolators2 = _interopRequireDefault(_interpolators);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/*
 * Check if value A is in +- proximity of value B
 * @param {Number} a
 * @param {Number} b
 * @param {Number} tolerance
 * @returns {Boolean} true if values are approximately equal or false otherwise
 */
var approxEqual = exports.approxEqual = function approxEqual(a, b, tolerance) {
  tolerance = tolerance || 0;
  if (b > 0) {
    return (1 - tolerance) * b <= a && a <= b * (1 + tolerance);
  } else if (b < 0) {
    return (1 + tolerance) * b <= a && a <= b * (1 - tolerance);
  } else {
    return Math.abs(a) <= tolerance;
  }
};

/*
 * returns unique id with optional prefix
 * @param {String} prefix
 * @returns {String} id
 */
var uniqueId = exports.uniqueId = function () {
  var id = 0;
  return function (p) {
    return p ? p + (id += 1) : id += 1;
  };
}();

/*
 * checks whether obj is a DOM element
 * @param {Object} obj
 * @returns {Boolean}
 * from underscore: https://github.com/jashkenas/underscore/blob/master/underscore.js
 */
var isElement = exports.isElement = function isElement(obj) {
  return !!(obj && obj.nodeType === 1);
};

/*
 * checks whether obj is an Array
 * @param {Object} obj
 * @returns {Boolean}
 * from underscore: https://github.com/jashkenas/underscore/blob/master/underscore.js
 */
var isArray = exports.isArray = Array.isArray || function (obj) {
  return toString.call(obj) === '[object Array]';
};

/*
 * checks whether obj is an object
 * @param {Object} obj
 * @returns {Boolean}
 * from underscore: https://github.com/jashkenas/underscore/blob/master/underscore.js
 */
var isObject = exports.isObject = function isObject(obj) {
  var type = typeof obj === 'undefined' ? 'undefined' : _typeof(obj);
  return type === 'object' && !!obj;
};

/*
 * checks whether arg is a date
 * @param {Object} arg
 * @returns {Boolean}
 */
var isDate = exports.isDate = function isDate(arg) {
  return arg instanceof Date;
};

/*
 * checks whether arg is a string
 * @param {Object} arg
 * @returns {Boolean}
 */
var isString = exports.isString = function isString(arg) {
  return typeof arg === 'string';
};

/*
 * checks whether arg is a NaN
 * @param {*} arg
 * @returns {Boolean}
 * from lodash: https://github.com/lodash/lodash/blob/master/lodash.js
 */
var isNaN = exports.isNaN = function isNaN(arg) {
  // A `NaN` primitive is the only number that is not equal to itself
  return isNumber(arg) && arg !== +arg;
};

var isEmpty = exports.isEmpty = function isEmpty(obj) {
  return Object.keys(obj).length === 0 && obj.constructor === Object;
};

/*
 * checks whether arg is a number. NaN is a number too
 * @param {*} arg
 * @returns {Boolean}
 * from lodash: https://github.com/lodash/lodash/blob/master/lodash.js
 * dependencies are resolved and included here
 */
var isNumber = exports.isNumber = function isNumber(arg) {
  return typeof arg === 'number' || !!arg && (typeof arg === 'undefined' ? 'undefined' : _typeof(arg)) === 'object' && Object.prototype.toString.call(arg) === '[object Number]';
};

/*
 * checks whether obj is a plain object {}
 * @param {Object} obj
 * @returns {Boolean}
 */
var isPlainObject = exports.isPlainObject = function isPlainObject(obj) {
  return obj !== null && Object.prototype.toString.call(obj) === '[object Object]';
};

/*
 * checks whether two arrays are equal
 * @param {Array} a
 * @param {Array} b
 * @returns {Boolean}
 */
var arrayEquals = exports.arrayEquals = function arrayEquals(a, b) {
  if (a === b) return true;
  if (a == null || b == null) return false;
  if (a.length != b.length) return false;
  for (var i = 0; i < a.length; ++i) {
    if (a[i] !== b[i]) return false;
  }
  return true;
};

/**
 * Object Comparison
 *
 * http://stamat.wordpress.com/2013/06/22/javascript-object-comparison/
 *
 * No version
 *
 * @param a
 * @param b
 * @returns {boolean} if objects are equal
 */
var comparePlainObjects = exports.comparePlainObjects = function comparePlainObjects(a, b) {

  //Returns the object's class, Array, Date, RegExp, Object are of interest to us
  var getClass = function getClass(val) {
    return Object.prototype.toString.call(val).match(/^\[object\s(.*)\]$/)[1];
  };

  //Defines the type of the value, extended typeof
  var whatis = function whatis(val) {

    if (val === undefined) {
      return 'undefined';
    }
    if (val === null) {
      return 'null';
    }

    var type = typeof val === 'undefined' ? 'undefined' : _typeof(val);

    if (type === 'object') {
      type = getClass(val).toLowerCase();
    }

    if (type === 'number') {
      if (val.toString().indexOf('.') > 0) {
        return 'float';
      } else {
        return 'integer';
      }
    }

    return type;
  };

  var compare = function compare(a, b) {
    if (a === b) {
      return true;
    }
    for (var i in a) {
      if (b.hasOwnProperty(i)) {
        if (!equal(a[i], b[i])) {
          return false;
        }
      } else {
        return false;
      }
    }

    for (var i in b) {
      if (!a.hasOwnProperty(i)) {
        return false;
      }
    }
    return true;
  };

  var compareArrays = function compareArrays(a, b) {
    if (a === b) {
      return true;
    }
    if (a.length !== b.length) {
      return false;
    }
    for (var i = 0; i < a.length; i++) {
      if (!equal(a[i], b[i])) {
        return false;
      }
    }
    return true;
  };

  var _equal = {};
  _equal.array = compareArrays;
  _equal.object = compare;
  _equal.date = function (a, b) {
    return a.getTime() === b.getTime();
  };
  _equal.regexp = function (a, b) {
    return a.toString() === b.toString();
  };

  /**
   * Are two values equal, deep compare for objects and arrays.
   * @param a {any}
   * @param b {any}
   * @return {boolean} Are equal?
   */
  var equal = function equal(a, b) {
    if (a !== b) {
      var atype = whatis(a),
          btype = whatis(b);

      if (atype === btype) {
        return _equal.hasOwnProperty(atype) ? _equal[atype](a, b) : a == b;
      }

      return false;
    }

    return true;
  };

  return compare(a, b);
};

var getViewportPosition = exports.getViewportPosition = function getViewportPosition(element) {
  var xPosition = 0;
  var yPosition = 0;

  while (element) {
    xPosition += element.offsetLeft - element.scrollLeft + element.clientLeft;
    yPosition += element.offsetTop - element.scrollTop + element.clientTop;
    element = element.offsetParent;
  }

  return {
    x: xPosition,
    y: yPosition
  };
};

var findScrollableAncestor = exports.findScrollableAncestor = function findScrollableAncestor(node) {
  var scrollable = ["scroll", "auto"];
  while (node = node.parentNode) {
    var scrollHeight = node.scrollHeight,
        height = node.clientHeight;
    if (scrollHeight > height && scrollable.indexOf(d3.select(node).style("overflow")) !== -1) {
      return node;
    }
  }
  return null;
};

var roundStep = exports.roundStep = function roundStep(number, step) {
  return Math.round(number / step) * step;
};

/*
 * transforms a string into a validated fload value
 * @param {string} string to be transformed
 */
var strToFloat = exports.strToFloat = function strToFloat(string) {
  return +string.replace(/[^\d.-]/g, '');
};

/*
 * loops through an object or array
 * @param {Object|Array} obj object or array
 * @param {Function} callback callback function
 * @param {Object} ctx context object
 */
var forEach = exports.forEach = function forEach(obj, callback, ctx) {
  if (!obj) {
    return;
  }
  var i, size;
  if (isArray(obj)) {
    size = obj.length;
    for (i = 0; i < size; i += 1) {
      if (callback.apply(ctx, [obj[i], i]) === false) {
        break;
      }
    }
  } else {
    var keys = Object.keys(obj);
    size = keys.length;
    for (i = 0; i < size; i += 1) {
      if (callback.apply(ctx, [obj[keys[i]], keys[i]]) === false) {
        break;
      }
    }
  }
};

/*
 * extends an object
 * @param {Object} destination object
 * @returns {Object} extented object
 */
var extend = exports.extend = function extend(dest) {
  //objects to overwrite dest are next arguments
  var objs = Array.prototype.slice.call(arguments, 1);
  //loop through each obj and each argument, left to right
  forEach(objs, function (obj, i) {
    forEach(obj, function (value, k) {
      if (obj.hasOwnProperty(k)) {
        dest[k] = value;
      }
    });
  });
  return dest;
};

// Deep extend and helper functions
// https://github.com/unclechu/node-deep-extend/blob/master/lib/deep-extend.js

function isSpecificValue(val) {
  return val instanceof Date || val instanceof RegExp ? true : false;
}

function cloneSpecificValue(val) {
  if (val instanceof Date) {
    return new Date(val.getTime());
  } else if (val instanceof RegExp) {
    return new RegExp(val);
  } else {
    throw new Error('Unexpected situation');
  }
}

/**
 * Recursive cloning array.
 */
function deepCloneArray(arr) {
  var clone = [];
  forEach(arr, function (item, index) {
    if ((typeof item === 'undefined' ? 'undefined' : _typeof(item)) === 'object' && item !== null) {
      if (isArray(item)) {
        clone[index] = deepCloneArray(item);
      } else if (isSpecificValue(item)) {
        clone[index] = cloneSpecificValue(item);
      } else {
        clone[index] = deepExtend({}, item);
      }
    } else {
      clone[index] = item;
    }
  });
  return clone;
}

/**
 * Extening object that entered in first argument.
 *
 * Returns extended object or false if have no target object or incorrect type.
 *
 * If you wish to clone source object (without modify it), just use empty new
 * object as first argument, like this:
 *   deepExtend({}, yourObj_1, [yourObj_N]);
 */
var deepExtend = exports.deepExtend = function deepExtend() /*obj_1, [obj_2], [obj_N]*/{
  if (arguments.length < 1 || _typeof(arguments[0]) !== 'object') {
    return false;
  }

  if (arguments.length < 2) {
    return arguments[0];
  }

  var target = arguments[0];

  // convert arguments to array and cut off target object
  var args = Array.prototype.slice.call(arguments, 1);

  var val, src, clone;

  forEach(args, function (obj) {
    // skip argument if it is array or isn't object
    if ((typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) !== 'object' || isArray(obj)) {
      return;
    }

    forEach(Object.keys(obj), function (key) {
      src = target[key]; // source value
      val = obj[key]; // new value

      // recursion prevention
      if (val === target) {
        return;

        /**
         * if new value isn't object then just overwrite by new value
         * instead of extending.
         * 2016-11-07 / Jasper: Added specific check for val instanceof Model for merging defaults & values of ComponentModels
         * 2016-11-07 / Jasper: Hack because importing Model doesn't work: instead check for val._data
         */
      } else if ((typeof val === 'undefined' ? 'undefined' : _typeof(val)) !== 'object' || val === null || val._data) {
        target[key] = val;
        return;

        // just clone arrays (and recursive clone objects inside)
      } else if (isArray(val)) {
        target[key] = deepCloneArray(val);
        return;

        // custom cloning and overwrite for specific objects
      } else if (isSpecificValue(val)) {
        target[key] = cloneSpecificValue(val);
        return;

        // overwrite by new value if source isn't object or array
      } else if ((typeof src === 'undefined' ? 'undefined' : _typeof(src)) !== 'object' || src === null || isArray(src)) {
        target[key] = deepExtend({}, val);
        return;

        // source value and new value is objects both, extending...
      } else {
        target[key] = deepExtend(src, val);
        return;
      }
    });
  });

  return target;
};

/*
 * merges objects instead of replacing
 * @param {Object} destination object
 * @returns {Object} merged object
 */
var merge = exports.merge = function merge(dest) {

  // objects to overwrite dest are next arguments
  var objs = Array.prototype.slice.call(arguments, 1);

  // loop through each obj and each argument, left to right
  forEach(objs, function (obj, i) {
    forEach(obj, function (value, k) {
      if (obj.hasOwnProperty(k)) {
        if (dest.hasOwnProperty(k)) {
          if (!isArray(dest[k])) {
            dest[k] = [dest[k]];
          }
          dest[k].push(value);
        } else {
          dest[k] = value;
        }
      }
    });
  });
  return dest;
};

/*
 * clones an object (shallow copy)
 * @param {Object} src original object
 * @param {Array} arr filter keys
 * @returns {Object} cloned object
 */
var clone = exports.clone = function clone(src, arr, exclude) {
  if (isArray(src)) {
    return src.slice(0);
  }
  var clone = {};
  forEach(src, function (value, k) {
    if (arr && arr.indexOf(k) === -1 || exclude && exclude.indexOf(k) !== -1) {
      return;
    }
    if (src.hasOwnProperty(k)) {
      clone[k] = value;
    }
  });
  return clone;
};

/*
 * deep clones an object (deep copy)
 * @param {Object} src original object
 * @returns {Object} cloned object
 */
var deepClone = exports.deepClone = function deepClone(src) {
  var clone = {};
  if (isArray(src)) clone = [];

  forEach(src, function (value, k) {
    if (isObject(value) || isArray(value)) {
      clone[k] = deepClone(value);
    } else {
      clone[k] = value;
    }
  });
  return clone;
};

/*
 * Prints message to timestamp
 * @param {Arr} arr
 * @param {Object} el
 */
var without = exports.without = function without(arr, el) {
  var idx = arr.indexOf(el);
  if (idx !== -1) {
    arr.splice(idx, 1);
  }
  return arr;
};

/*
 * unique items in an array
 * @param {Array} arr original array
 * @param {Function} func optional evaluation function
 * @returns {Array} unique items
 * Based on:
 * http://stackoverflow.com/questions/1960473/unique-values-in-an-array
 */
var unique = exports.unique = function unique(arr, func) {
  var u = {};
  var a = [];
  if (!func) {
    func = function func(d) {
      return d;
    };
  }
  for (var i = 0, l = arr.length; i < l; i += 1) {
    var key = func(arr[i]);
    if (u.hasOwnProperty(key)) {
      continue;
    }
    a.push(arr[i]);
    u[key] = 1;
  }
  return a;
};

/*
 * unique items in an array keeping the last item
 * @param {Array} arr original array
 * @param {Function} func optional evaluation function
 * @returns {Array} unique items
 * Based on the previous method
 */
var uniqueLast = exports.uniqueLast = function uniqueLast(arr, func) {
  var u = {};
  var a = [];
  if (!func) {
    func = function func(d) {
      return d;
    };
  }
  for (var i = 0, l = arr.length; i < l; i += 1) {
    var key = func(arr[i]);
    if (u.hasOwnProperty(key)) {
      a.splice(u[key], 1); //remove old item from array
    }
    a.push(arr[i]);
    u[key] = a.length - 1;
  }
  return a;
};

/*
 * returns first value that passes the test
 * @param {Array} arr original collection
 * @returns {Function} func test function
 */
var find = exports.find = function find(arr, func) {
  var found;
  forEach(arr, function (i) {
    if (func(i)) {
      found = i;
      return false; //break
    }
  });
  return found;
};

/*
 * filters an array based on object properties
 * @param {Array} arr original array
 * @returns {Object} filter properties to use as filter
 */
var filter = exports.filter = function filter(arr, _filter) {
  var index = -1;
  var length = arr.length;
  var resIndex = -1;
  var result = [];
  var keys = Object.keys(_filter);
  var s_keys = keys.length;
  var i;
  var f;
  while ((index += 1) < length) {
    var value = arr[index];
    var match = true;
    for (i = 0; i < s_keys; i += 1) {
      f = keys[i];
      if (!value.hasOwnProperty(f) || value[f] !== _filter[f]) {
        match = false;
        break;
      }
    }
    if (match) {
      result[resIndex += 1] = value;
    }
  }
  return result;
};

/*
 * filters an array based on object properties.
 * Properties may be arrays determining possible values
 * @param {Array} arr original array
 * @returns {Object} filter properties to use as filter
 */
var filterAny = exports.filterAny = function filterAny(arr, filter, wildcard) {
  var index = -1;
  var length = arr.length;
  var resIndex = -1;
  var result = [];
  var keys = Object.keys(filter);
  var s_keys = keys.length;
  var i, f;
  while ((index += 1) < length) {
    var value = arr[index];
    //normalize to array
    var match = true;
    for (i = 0; i < s_keys; i += 1) {
      f = keys[i];
      if (!value.hasOwnProperty(f) || !matchAny(value[f], filter[f], wildcard)) {
        match = false;
        break;
      }
    }
    if (match) {
      result[resIndex += 1] = value;
    }
  }
  return result;
};

/*
 * checks if the value matches the comparison value or any in array
 * compare may be an determining possible values
 * @param value original value
 * @param compare value or array
 * @param {String} wildc wildcard value
 * @returns {Boolean} try
 */
var matchAny = exports.matchAny = function matchAny(values, compare, wildc) {
  //normalize value
  if (!isArray(values)) values = [values];
  if (!wildc) wildc = "*"; //star by default
  var match = false;
  for (var e = 0; e < values.length; e++) {
    var value = values[e];

    if (!isArray(compare) && value == compare) {
      match = true;
      break;
    } else if (isArray(compare)) {
      var found = -1;
      for (var i = 0; i < compare.length; i++) {
        var c = compare[i];
        if (!isArray(c) && (c == value || c === wildc)) {
          found = i;
          break;
        } else if (isArray(c)) {
          //range
          var min = c[0];
          var max = c[1] || min;
          if (value >= min && value <= max) {
            found = i;
            break;
          }
        }
      }
      if (found !== -1) {
        match = true;
        break;
      }
    }
  }
  return match;
};

/**
 * prevent scrolling parent scrollable elements for 2 second when element scrolled to end
 * @param node
 */

var preventAncestorScrolling = exports.preventAncestorScrolling = function preventAncestorScrolling(element) {
  var preventScrolling = false;
  element.on('mousewheel', function (d, i) {
    var scrollTop = this.scrollTop,
        scrollHeight = this.scrollHeight,
        height = element.node().offsetHeight,
        delta = d3.event.wheelDelta,
        up = delta > 0;
    var prevent = function prevent() {
      d3.event.stopPropagation();
      d3.event.preventDefault();
      d3.event.returnValue = false;
      return false;
    };

    var scrollTopTween = function scrollTopTween(scrollTop) {
      return function () {
        var i = d3.interpolateNumber(this.scrollTop, scrollTop);
        return function (t) {
          this.scrollTop = i(t);
        };
      };
    };
    if (!up) {
      // Scrolling down
      if (-delta > scrollHeight - height - scrollTop && scrollHeight != height + scrollTop) {
        element.transition().delay(0).duration(0).tween("scrolltween", scrollTopTween(scrollHeight));
        //freeze scrolling on 2 seconds on bottom position
        preventScrolling = true;
        setTimeout(function () {
          preventScrolling = false;
        }, 2000);
      } else if (scrollTop == 0) {
        //unfreeze when direction changed
        preventScrolling = false;
      }
    } else if (up) {
      // Scrolling up
      if (delta > scrollTop && scrollTop > 0) {
        //
        //freeze scrolling on 2 seconds on top position
        element.transition().delay(0).duration(0).tween("scrolltween", scrollTopTween(0));
        preventScrolling = true;
        setTimeout(function () {
          preventScrolling = false;
        }, 2000);
      } else if (scrollHeight == height + scrollTop) {
        //unfreeze when direction changed
        preventScrolling = false;
      }
    }
    if (preventScrolling) {
      return prevent();
    }
  });
};

/*
 * maps all rows according to the formatters
 * @param {Array} original original dataset
 * @param {Object} formatters formatters object
 * @returns {Boolean} try
 */
var mapRows = exports.mapRows = function mapRows(original, formatters) {

  function mapRow(value, fmt) {
    if (!isArray(value)) {
      return fmt(value);
    } else {
      var res = [];
      for (var i = 0; i < value.length; i++) {
        res[i] = mapRow(value[i], fmt);
      }
      return res;
    }
  }

  // default formatter turns empty strings in null and converts numeric values into number
  //TODO: default formatter is moved to utils. need to return it to hook prototype class, but retest #1212 #1230 #1253
  var defaultFormatter = function defaultFormatter(val) {
    var newVal = val;
    if (val === "") {
      newVal = null;
    } else {
      // check for numeric
      var numericVal = parseFloat(val);
      if (!isNaN(numericVal) && isFinite(val)) {
        newVal = numericVal;
      }
    }
    return newVal;
  };

  original = original.map(function (row) {
    var columns = Object.keys(row);

    for (var i = 0; i < columns.length; i++) {
      var col = columns[i];
      row[col] = mapRow(row[col], formatters[col] || defaultFormatter);
    }
    return row;
  });

  return original;
};

/*
 * Converts radius to area, simple math
 * @param {Number} radius
 * @returns {Number} area
 */
var radiusToArea = exports.radiusToArea = function radiusToArea(r) {
  return r * r * Math.PI;
};

/*
 * Converts area to radius, simple math
 * @param {Number} area
 * @returns {Number} radius
 */
var areaToRadius = exports.areaToRadius = function areaToRadius(a) {
  return Math.sqrt(a / Math.PI);
};

/*
 * Prints message to timestamp
 * @param {String} message
 */
var timeStamp = exports.timeStamp = function timeStamp(message) {
  if (console && typeof console.timeStamp === 'function') {
    console.timeStamp(message);
  }
};

/*
 * Prints warning
 * @param {String} message
 */
var warn = exports.warn = function warn(message) {
  message = Array.prototype.slice.call(arguments).map(function (m) {
    return m instanceof Object ? JSON.stringify(m, null, 4) : m;
  }).join(' ');
  if (console && typeof console.warn === 'function') {

    console.warn(message);
  }
  // "return true" is needed to find out if a parent function is exited with warning
  // example:
  // myfunction = function() { if(brokenstuff) return utils.warn("broken stuff found") }
  // if(myfunction()) return; // stopped execution after myfunction finds broken stuff
  // ... or moving on
  return true;
};

/*
 * Prints message for group
 * @param {String} message
 */
var groupCollapsed = exports.groupCollapsed = function groupCollapsed(message) {
  message = Array.prototype.slice.call(arguments).join(' ');
  if (console && typeof console.groupCollapsed === 'function') {
    console.groupCollapsed(message);
  }
};

/*
 * Prints end of group
 * @param {String} message
 */
var groupEnd = exports.groupEnd = function groupEnd() {
  if (console && typeof console.groupEnd === 'function') {
    console.groupEnd();
  }
};

/*
 * Prints error
 * @param {String} message
 */
var error = exports.error = function error(err) {
  if (console && typeof console.error === 'function') {
    if (err.stack) {
      console.error(err.stack);
    } else {
      console.error(err);
    }
    if (arguments.length > 1) {
      console.error.apply(this, Array.prototype.slice.call(arguments, 1));
    }
  }
};

/*
 * Count the number of decimal numbers
 * @param {Number} number
 */
var countDecimals = exports.countDecimals = function countDecimals(number) {
  if (Math.floor(number.valueOf()) === number.valueOf()) {
    return 0;
  }
  return number.toString().split('.')[1].length || 0;
};

/*
 * Adds class to DOM element
 * @param {Element} el
 * @param {String} className
 */
var addClass = exports.addClass = function addClass(el, className) {
  if (el.classList) {
    el.classList.add(className);
  } else {
    //IE<10
    el.className += ' ' + className;
  }
};

/*
 * Remove class from DOM element
 * @param {Element} el
 * @param {String} className
 */
var removeClass = exports.removeClass = function removeClass(el, className) {
  if (el.classList) {
    el.classList.remove(className);
  } else {
    //IE<10
    el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
  }
};

/*
 * Adds or removes class depending on value
 * @param {Element} el
 * @param {String} className
 * @param {Boolean} value
 */
var classed = exports.classed = function classed(el, className, value) {
  if (value === true) {
    addClass(el, className);
  } else if (value === false) {
    removeClass(el, className);
  } else {
    return hasClass(el, className);
  }
};

/*
 * Checks whether a DOM element has a class or not
 * @param {Element} el
 * @param {String} className
 * @return {Boolean}
 */
var hasClass = exports.hasClass = function hasClass(el, className) {
  if (el.classList) {
    return el.classList.contains(className);
  } else {
    //IE<10
    return new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className);
  }
};

/*
 * Throttles a function
 * @param {Function} func
 * @param {Number} ms duration
 * @return {Function}
 * Function recallLast was added to prototype of returned function.
 * Call Function.recallLast() - immediate recall func with last saved arguments,
 *                              else func will be called automaticly after ms duration
 */
var throttle = exports.throttle = function throttle(func, ms) {

  var throttled = false,
      savedArgs,
      savedThis,
      nextTime,
      wrapper = function wrapper() {

    if (nextTime > Date.now()) {
      throttled = true;
      savedArgs = arguments;
      savedThis = this;
      return;
    }

    nextTime = Date.now() + ms;
    throttled = false;

    func.apply(this, arguments);

    setTimeout(function () {
      __recallLast();
    }, ms);
  },
      __recallLast = function __recallLast() {
    if (throttled) {
      throttled = false;
      func.apply(savedThis, savedArgs);
    }
  };

  wrapper.recallLast = __recallLast;

  return wrapper;
};

/*
 * Returns keys of an object as array
 * @param {Object} arg
 * @returns {Array} keys
 */
var keys = exports.keys = function keys(arg) {
  return Object.keys(arg);
};

/*
 * returns the values of an object in an array format
 * @param {Object} obj
 * @return {Array}
 */
var values = exports.values = function values(obj) {
  var arr = [];
  var keys = Object.keys(obj);
  var size = keys.length;
  for (var i = 0; i < size; i += 1) {
    arr.push(obj[keys[i]]);
  }
  return arr;
};

/*
 * Computes the minumum value in an array
 * @param {Array} arr
 */
var arrayMin = exports.arrayMin = function arrayMin(arr) {
  return arr.reduce(function (p, v) {
    return p < v ? p : v;
  });
};

/*
 * Computes the minumum value in an array
 * @param {Array} arr
 */
var arrayMax = exports.arrayMax = function arrayMax(arr) {
  return arr.reduce(function (p, v) {
    return p > v ? p : v;
  });
};

/*
 * Computes the mean of an array
 * @param {Array} arr
 */
var arrayMean = exports.arrayMean = function arrayMean(arr) {
  return arraySum(arr) / arr.length;
};

/*
 * Computes the sum of an array
 * @param {Array} arr
 */
var arraySum = exports.arraySum = function arraySum(arr) {
  return arr.reduce(function (a, b) {
    return a + b;
  });
};

/*
 * Computes the median of an array
 * @param {Array} arr
 */
var arrayMedian = exports.arrayMedian = function arrayMedian(arr) {
  arr = arr.sort(function (a, b) {
    return a - b;
  });
  var middle = Math.floor((arr.length - 1) / 2);
  if (arr.length % 2) {
    return arr[middle];
  } else {
    return (arr[middle] + arr[middle + 1]) / 2;
  }
};

/*
 * Returns the last value of array
 * @param {Array} arr
 */
var arrayLast = exports.arrayLast = function arrayLast(arr) {
  if (!arr.length) return null;
  return arr[arr.length - 1];
};

/*
 * Returns the resulting object of the difference between two objects
 * @param {Object} obj2
 * @param {Object} obj1
 * @returns {Object}
 */
var diffObject = exports.diffObject = function diffObject(obj2, obj1) {
  var diff = {};
  forEach(obj2, function (value, key) {
    if (!obj1.hasOwnProperty(key)) {
      diff[key] = value;
    } else if (value !== obj1[key]) {
      if (isPlainObject(value) && isPlainObject(obj1[key])) {
        var d = diffObject(value, obj1[key]);
        if (Object.keys(d).length > 0) {
          diff[key] = d;
        }
      } else if (!isArray(value) || !isArray(obj1[key]) || !arrayEquals(value, obj1[key])) {
        diff[key] = value;
      }
    }
  });
  return diff;
};

/*
 * Defers a function
 * @param {Function} func
 */
var defer = exports.defer = function defer(func) {
  setTimeout(func, 1);
};

/*
 * Defers a function
 * @param {Function} func
 */
var delay = exports.delay = function delay(_delay) {
  return new Promise(function (resolve) {
    return setTimeout(resolve, _delay);
  });
};

var clearDelay = exports.clearDelay = function clearDelay(delayId) {
  return clearTimeout(delayId);
};

/*
 * Creates a hashcode for a string or array
 * @param {String|Array} str
 * @return {Number} hashCode
 */
var hashCode = exports.hashCode = function hashCode(str) {
  if (!isString(str)) {
    str = JSON.stringify(str);
  }
  var hash = 0;
  var size = str.length;
  var c;
  if (size === 0) {
    return hash;
  }
  for (var i = 0; i < size; i += 1) {
    c = str.charCodeAt(i);
    hash = (hash << 5) - hash + c;
    hash = hash & hash; // Convert to 32bit integer
  }
  return hash.toString();
};

/*
 * Converts D3 nest array into the object with key-value pairs, recursively
 * @param {Array} arr - array like this [{key: k, values: [a, b, ...]}, {...} ... {...}]
 * @return {Object} object like this {k: [a, b, ...], ...}
 */
//
var nestArrayToObj = exports.nestArrayToObj = function nestArrayToObj(arr) {
  if (!arr || !arr.length || !arr[0].key) return arr;
  var res = {};
  for (var i = 0; i < arr.length; i++) {
    res[arr[i].key] = nestArrayToObj(arr[i].values);
  };
  return res;
};

var interpolateVector = exports.interpolateVector = function interpolateVector() {};

/**
 * interpolates the specific value
 * @param {Array} items -- an array of items, sorted by "dimTime", filtered so that no item[which] is null
 * @param {String} use -- a use of hook that wants to interpolate. can be "indicator" or "property" or "constant"
 * @param {String} which -- a hook pointer to indicator or property, e.g. "lex"
 * @param {Number} next -- an index of next item in "items" array after the value to be interpolated. if omitted, then calculated here, but it's expensive
 * @param {String} dimTime -- a pointer to time dimension, usually "time"
 * @param {Date} time -- reference point for interpolation. here the valus is to be found
 * @param {String} method refers to which formula to use. "linear" or "exp". Falls back to "linear" if undefined
 * @param {Boolean} extrapolate indicates if we should use zero-order extrapolation outside the range of available data
 * @returns {Number} interpolated value
 */
var interpolatePoint = exports.interpolatePoint = function interpolatePoint(items, use, which, next, dimTime, time, method, extrapolate) {

  if (!items || items.length === 0) {
    warn('interpolatePoint failed because incoming array is empty. It was ' + which);
    return null;
  }
  // return constant for the use of "constant"
  if (use === 'constant') return which;

  // zero-order interpolation for the use of properties
  if (use === 'property') return items[0][which];

  // the rest is for the continuous measurements

  if (extrapolate) {
    // check if the desired value is out of range. 0-order extrapolation
    if (time - items[0][dimTime] <= 0) return items[0][which];
    if (time - items[items.length - 1][dimTime] >= 0) return items[items.length - 1][which];
  } else {
    // no extrapolation according to Ola's request
    if (time < items[0][dimTime] || time > items[items.length - 1][dimTime]) return null;
  }

  if (!next && next !== 0) next = d3.bisectLeft(items.map(function (m) {
    return m[dimTime];
  }), time);

  if (next === 0) return items[0][which];

  //return null if data is missing
  if (items[next] === undefined || items[next][which] === null || items[next - 1][which] === null || items[next][which] === "") {
    warn('interpolatePoint failed because next/previous points are bad in ' + which);
    return null;
  }

  //do the math to calculate a value between the two points
  var result = _interpolators2.default[method || "linear"](items[next - 1][dimTime], items[next][dimTime], items[next - 1][which], items[next][which], time);

  // cast to time object if we are interpolating time
  if (which === dimTime) result = new Date(result);
  if (isNaN(result)) {
    warn('interpolatePoint failed because result is NaN. It was ' + which);
    result = null;
  }

  return result;
};

/*
 * Performs an ajax request
 * @param {Object} options
 * @param {String} className
 * @return {Boolean}
 */
var ajax = exports.ajax = function ajax(options) {
  var request = new XMLHttpRequest();
  request.open(options.method, options.url, true);
  if (options.method === 'POST' && !options.json) {
    request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
  } else if (options.method === 'POST' && options.json) {
    request.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
  }
  request.onload = function () {
    if (request.status >= 200 && request.status < 400) {
      // Success!
      var data = options.json ? JSON.parse(request.responseText) : request.responseText;
      if (options.success) {
        options.success(data);
      }
    } else {
      if (options.error) {
        options.error();
      }
    }
  };
  request.onerror = function () {
    if (options.error) {
      options.error();
    }
  };
  request.send(options.data);
};

/*
 * Performs a GET http request
 */
var get = exports.get = function get(url, pars, success, error, json) {
  pars = pars || [];
  forEach(pars, function (value, key) {
    pars.push(key + '=' + value);
  });
  url = pars.length ? url + '?' + pars.join('&') : url;
  ajax({
    method: 'GET',
    url: url,
    success: success,
    error: error,
    json: json
  });
};

/*
 * Performs a POST http request
 */
var post = exports.post = function post(url, pars, success, error, json) {
  ajax({
    method: 'POST',
    url: url,
    success: success,
    error: error,
    json: json,
    data: pars
  });
};

/**
 * Make function memoized
 * @param {Function} fn
 * @returns {Function}
 */
var memoize = exports.memoize = function memoize(fn) {
  return function () {
    var args = Array.prototype.slice.call(arguments);
    var hash = '';
    var i = args.length;
    var currentArg = null;

    while (i--) {
      currentArg = args[i];
      hash += currentArg === Object(currentArg) ? JSON.stringify(currentArg) : currentArg;
      fn.memoize || (fn.memoize = {});
    }

    return hash in fn.memoize ? fn.memoize[hash] : fn.memoize[hash] = fn.apply(this, args);
  };
};

// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
var debounce = exports.debounce = function debounce(func, wait, immediate) {
  var timeout;
  return function () {
    var context = this,
        args = arguments;
    var later = function later() {
      timeout = null;
      if (!immediate) func.apply(context, args);
    };
    var callNow = immediate && !timeout;
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
    if (callNow) func.apply(context, args);
  };
};

var isTouchDevice = exports.isTouchDevice = function isTouchDevice() {
  //'ontouchstart' is not reliable in Google Chrome #2116, but Chrome has this firesTouchEvents flag
  if (((d3.event || {}).sourceCapabilities || {}).firesTouchEvents != null) {
    return d3.event.sourceCapabilities.firesTouchEvents;
  }
  return !!('ontouchstart' in window || window.DocumentTouch && document instanceof DocumentTouch);
};

//return a pruneed tree
var pruneTree = exports.pruneTree = function pruneTree(tree, filterCallback) {
  var filteredTree = {};
  var filteredChildrens = [];
  if (tree.hasOwnProperty("children")) {
    filteredChildrens = tree.children.map(function (childrenTree) {
      return pruneTree(childrenTree, filterCallback);
    }).filter(function (childrenTree) {
      return Object.keys(childrenTree).length !== 0;
    });
  }
  if (filteredChildrens.length != 0 || filterCallback(tree)) {
    //copy all the properties to the new tree
    forEach(tree, function (value, key) {
      filteredTree[key] = value;
    });
  }
  if (filteredChildrens.length != 0) {
    filteredTree["children"] = filteredChildrens;
  }
  return filteredTree;
};

var setIcon = exports.setIcon = function setIcon(element, icon) {
  element.selectAll('*').remove();
  element.node().appendChild(element.node().ownerDocument.importNode(new DOMParser().parseFromString(icon, 'application/xml').documentElement, true));
  return element;
};

//http://stackoverflow.com/questions/26049488/how-to-get-absolute-coordinates-of-object-inside-a-g-group
function makeAbsoluteContext(element, svgDocument) {
  return function (x, y) {
    var offset = svgDocument.getBoundingClientRect();
    var matrix = element.getScreenCTM();
    return {
      x: matrix.a * x + matrix.c * y + matrix.e - offset.left,
      y: matrix.b * x + matrix.d * y + matrix.f - offset.top
    };
  };
}

/***
   thenBy.js
   Copyright 2013 Teun Duynstee
   https://github.com/Teun/thenBy.js/blob/master/thenBy.module.js

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at
     http://www.apache.org/licenses/LICENSE-2.0
   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */
function firstBy() {

  function identity(v) {
    return v;
  }

  function ignoreCase(v) {
    return typeof v === "string" ? v.toLowerCase() : v;
  }

  function makeCompareFunction(f, opt) {
    opt = typeof opt === "number" ? { direction: opt } : opt || {};
    if (typeof f != "function") {
      var prop = f;
      // make unary function
      f = function f(v1) {
        return !!v1[prop] ? v1[prop] : "";
      };
    }
    if (f.length === 1) {
      // f is a unary function mapping a single item to its sort score
      var uf = f;
      var preprocess = opt.ignoreCase ? ignoreCase : identity;
      f = function f(v1, v2) {
        return preprocess(uf(v1)) < preprocess(uf(v2)) ? -1 : preprocess(uf(v1)) > preprocess(uf(v2)) ? 1 : 0;
      };
    }
    if (opt.direction === -1) return function (v1, v2) {
      return -f(v1, v2);
    };
    return f;
  }

  /* adds a secondary compare function to the target function (`this` context)
     which is applied in case the first one returns 0 (equal)
     returns a new compare function, which has a `thenBy` method as well */
  function tb(func, opt) {
    var x = typeof this == "function" ? this : false;
    var y = makeCompareFunction(func, opt);
    var f = x ? function (a, b) {
      return x(a, b) || y(a, b);
    } : y;
    f.thenBy = tb;
    return f;
  }
  return tb;
}

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _events = __webpack_require__(45);

var _events2 = _interopRequireDefault(_events);

var _model = __webpack_require__(46);

var _model2 = _interopRequireDefault(_model);

var _globals = __webpack_require__(44);

var _globals2 = _interopRequireDefault(_globals);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

var class_loading_first = 'vzb-loading-first';
var class_loading_data = 'vzb-loading-data';
var class_error = 'vzb-error';

var templates = {};
var Component = _events2.default.extend({

  /**
   * Initializes the component
   * @param {Object} config Initial config, with name and placeholder
   * @param {Object} parent Reference to tool
   */
  init: function init(config, parent) {
    this._id = this._id || utils.uniqueId('c');
    this._ready = false;
    this._readyOnce = false;
    this.name = this.name || config.name || this._id;
    this.template = this.template || '<div></div>';
    this.placeholder = this.placeholder || config.placeholder;
    this.template_data = this.template_data || {
      name: this.name
    };
    //make sure placeholder is DOM element
    if (this.placeholder && !utils.isElement(this.placeholder)) {
      try {
        this.placeholder = parent.placeholder.querySelector(this.placeholder);
      } catch (e) {
        utils.error('Error finding placeholder \'' + this.placeholder + '\' for component \'' + this.name + '\'');
      }
    }
    this.parent = parent || null;
    this.root = this.parent ? this.parent.root : this;

    this.components = this.components || [];
    this._components_config = this.components.map(function (x) {
      return utils.clone(x);
    });

    //define expected models for this component
    this.model_expects = this.model_expects || [];
    this.model_binds = this.model_binds || {};
    this.createModel(config.model);

    this.ui = this.model.ui || this.ui || config.ui;
    this._super();

    this.registerListeners();
  },

  createModel: function createModel(configModel) {
    this.model = this._modelMapping(configModel);
  },

  registerListeners: function registerListeners() {
    this.on({
      'readyOnce': this.readyOnce,
      'ready': this.ready,
      'domReady': this.domReady,
      'resize': this.resize
    });
  },

  /**
   * Recursively starts preloading in components
   * @return {[type]} [description]
   */
  startPreload: function startPreload() {

    var promises = [];
    promises.push(this.preload());

    utils.forEach(this.components, function (subComponent) {
      return promises.push(subComponent.startPreload());
    });

    return Promise.all(promises);
  },

  preload: function preload() {
    return Promise.resolve();
  },

  /**
   * Executes after preloading is finished
   */
  afterPreload: function afterPreload() {
    if (this.model) {
      this.model.afterPreload();
    }
    utils.forEach(this.components, function (subcomp) {
      subcomp.afterPreload();
    });
  },

  /**
   * Renders the component (after data is ready)
   */
  render: function render() {
    var _this = this;
    this.loadTemplate();
    this.loadSubComponents();

    //render each subcomponent
    utils.forEach(this.components, function (subcomp) {
      subcomp.render();
      _this.on('resize', function () {
        subcomp.trigger('resize');
      });
    });

    this.startLoading();
  },

  /**
   * Overloaded by Tool which starts loading of model
   * @return {[type]} [description]
   */
  startLoading: function startLoading() {
    var _this = this;

    // if a componente's model is ready, the component is ready
    this.model.on('ready', function () {
      _this.loadingDone();
    });

    if (!(this.model && this.model.isLoading())) {
      this.loadingDone();
    }
  },

  loadingDone: function loadingDone() {
    utils.removeClass(this.placeholder, class_loading_first);
    utils.removeClass(this.placeholder, class_loading_data);
    this.setReady();
  },

  renderError: function renderError() {
    utils.removeClass(this.placeholder, class_loading_first);
    utils.removeClass(this.placeholder, class_loading_data);
    utils.addClass(this.placeholder, class_error);
    this.setError({
      type: 'data'
    });
  },

  setError: function setError(opts) {
    if (typeof this.error === 'function') {
      this.error(opts);
    }
  },

  setReady: function setReady(value) {
    if (!this._readyOnce) {
      this.trigger('readyOnce');
      this._readyOnce = true;
    }
    this._ready = true;
    this.trigger('ready');
  },

  /**
   * Loads the template
   * @returns defer a promise to be resolved when template is loaded
   */
  loadTemplate: function loadTemplate() {
    var tmpl = this.template;
    var data = this.template_data;
    var _this = this;
    var rendered = '';
    if (!this.placeholder) {
      return;
    }
    //todo: improve t function getter + generalize this
    data = utils.extend(data, {
      t: this.getTranslationFunction(true)
    });
    if (this.template) {
      try {
        rendered = templateFunc(tmpl, data);
      } catch (e) {
        utils.error('Templating error for component: \'' + this.name + '\' - Check if template name is unique and correct. E.g.: \'bubblechart\'');

        utils.removeClass(this.placeholder, class_loading_data);
        utils.addClass(this.placeholder, class_error);
        this.setError({
          type: 'template'
        });
      }
    }
    //add loading class and html
    utils.addClass(this.placeholder, class_loading_data);
    utils.addClass(this.placeholder, class_loading_first);
    this.placeholder.innerHTML = rendered;
    this.element = this.placeholder.children[0];

    //template is ready
    this.trigger('domReady');
  },

  getActiveProfile: function getActiveProfile(profiles, presentationProfileChanges) {
    // get layout values
    var layoutProfile = this.getLayoutProfile();
    var presentationMode = this.getPresentationMode();
    var activeProfile = utils.deepClone(profiles[layoutProfile]); // clone so it can be extended without changing the original profile

    // extend the profile with presentation mode values
    if (presentationMode && (presentationProfileChanges || {})[layoutProfile]) {
      utils.deepExtend(activeProfile, presentationProfileChanges[layoutProfile]);
    }

    return activeProfile;
  },

  /*
   * Loads all subcomponents
   */
  loadSubComponents: function loadSubComponents() {
    var _this = this;
    var config;
    var comp;
    //use the same name for collection
    this.components = [];

    // Loops through components, loading them.
    utils.forEach(this._components_config, function (component_config) {

      component_config.model = component_config.model || {};

      if (!component_config.component) {
        utils.error('Error loading component: name not provided');
        return;
      }

      comp = utils.isString(component_config.component) ? Component.get(component_config.component) : component_config.component;

      if (!comp) return;

      config = utils.extend(component_config, {
        name: component_config.component,
        ui: _this._uiMapping(component_config.placeholder, component_config.ui)
      });
      //instantiate new subcomponent
      var subcomp = new comp(config, _this);
      _this.components.push(subcomp);
    });
  },

  /**
   * Returns subcomponent by name
   * @returns {Boolean}
   */
  findChildByName: function findChildByName(name) {
    return utils.find(this.components, function (f) {
      return f.name === name;
    });
  },

  /**
   * Get layout profile of the current resolution
   * @returns {String} profile
   */
  getLayoutProfile: function getLayoutProfile() {
    //get profile from parent if layout is not available
    if (this.model.ui) {
      return this.model.ui.currentProfile();
    } else {
      return this.parent.getLayoutProfile();
    }
  },

  /**
   * Get if presentation mode is set of the current tool
   * @returns {Bool} presentation mode
   */
  getPresentationMode: function getPresentationMode() {
    //get profile from parent if layout is not available
    if (this.model.ui) {
      return this.model.ui.getPresentationMode();
    } else {
      return this.parent.getPresentationMode();
    }
  },

  //TODO: make ui mapping more powerful
  /**
   * Maps the current ui to the subcomponents
   * @param {String} id subcomponent id (placeholder)
   * @param {Object} ui Optional ui parameters to overwrite existing
   * @returns {Object} the UI object
   */
  _uiMapping: function _uiMapping(id, ui) {
    //if overwritting UI
    if (ui) {
      return new _model2.default('ui', ui);
    }
    if (id && this.ui) {
      id = id.replace('.', '');
      //remove trailing period
      var sub_ui = this.ui[id];
      if (sub_ui) {
        return sub_ui;
      }
    }
    return this.ui;
  },

  /**
   * Maps the current model to the subcomponents
   * @param {String|Array} model_config Configuration of model
   * @returns {Object} the model
   */
  _modelMapping: function _modelMapping(model_config) {
    var _this = this;
    var values = {};
    //If model_config is an array, we map it
    if (utils.isArray(model_config) && utils.isArray(this.model_expects)) {

      //if there's a different number of models received and expected
      if (this.model_expects.length !== model_config.length) {
        utils.groupCollapsed('DIFFERENCE IN NUMBER OF MODELS EXPECTED AND RECEIVED');
        utils.warn("Please, configure the 'model_expects' attribute accordingly in '" + this.name + "' or check the models passed in '" + _this.parent.name + "'.\n\n" + "Component: '" + _this.parent.name + "'\n" + "Subcomponent: '" + this.name + "'\n" + "Number of Models Expected: " + this.model_expects.length + "\nNumber of Models Received: " + model_config.length);
        utils.groupEnd();
      }
      utils.forEach(model_config, function (m, i) {
        var model_info = _mapOne(m);
        var new_name;
        if (_this.model_expects[i]) {
          new_name = _this.model_expects[i].name;
          if (_this.model_expects[i].type && model_info.type !== _this.model_expects[i].type && (!utils.isArray(_this.model_expects[i].type) || _this.model_expects[i].type.indexOf(model_info.type) === -1)) {

            utils.groupCollapsed("UNEXPECTED MODEL TYPE: '" + model_info.type + "' instead of '" + _this.model_expects[i].type + "'");
            utils.warn("Please, configure the 'model_expects' attribute accordingly in '" + _this.name + "' or check the models passed in '" + _this.parent.name + "'.\n\n" + "Component: '" + _this.parent.name + "'\n" + "Subcomponent: '" + _this.name + "'\n" + "Expected Model: '" + _this.model_expects[i].type + "'\n" + "Received Model: '" + model_info.type + "'\n" + "Model order: " + i);
            utils.groupEnd();
          }
        } else {

          utils.groupCollapsed("UNEXPECTED MODEL: '" + model_config[i] + "'");
          utils.warn("Please, configure the 'model_expects' attribute accordingly in '" + _this.name + "' or check the models passed in '" + _this.parent.name + "'.\n\n" + "Component: '" + _this.parent.name + "'\n" + "Subcomponent: '" + _this.name + "'\n" + "Number of Models Expected: " + _this.model_expects.length + "\n" + "Number of Models Received: " + model_config.length);
          utils.groupEnd();
          new_name = model_info.name;
        }
        values[new_name] = model_info.model;
      });

      // fill the models that weren't passed with empty objects
      // e.g. if expected = [ui, locale, color] and passed/existing = [ui, locale]
      // it will fill values up to [ui, locale, {}]
      var existing = model_config.length;
      var expected = this.model_expects.length;
      if (expected > existing) {
        //skip existing
        this.model_expects.splice(0, existing);
        //adds new expected models if needed
        utils.forEach(expected, function (m) {
          values[m.name] = {};
        });
      }
    } else {
      return;
    }
    //return a new model with the defined submodels
    return new _model2.default(this.name, values, null, this.model_binds);
    /**
     * Maps one model name to current submodel and returns info
     * @param {String} name Full model path. E.g.: "state.marker.color"
     * @returns {Object} the model info, with name and the actual model
     */
    function _mapOne(name) {
      var parts = name.split('.');
      var current = _this.parent.model;
      var current_name = '';
      while (parts.length) {
        current_name = parts.shift();
        current = current[current_name];
      }
      return {
        name: name,
        model: current,
        type: current ? current.getType() : null
      };
    }
  },

  /**
   * Get translation function for templates
   * @param {Boolean} wrap wrap in spam tags
   * @returns {Function}
   */
  getTranslationFunction: function getTranslationFunction(wrap) {
    var t_func;
    try {
      t_func = this.model.get('locale').getTFunction();
    } catch (err) {
      if (this.parent && this.parent !== this) {
        t_func = this.parent.getTranslationFunction();
      }
    }
    if (!t_func) {
      t_func = function t_func(s) {
        return s;
      };
    }
    if (wrap) {
      return this._translatedStringFunction(t_func);
    } else {
      return t_func;
    }
  },

  /**
   * Get function for translated string
   * @param {Function} translation_function The translation function
   * @returns {Function}
   */
  _translatedStringFunction: function _translatedStringFunction(translation_function) {
    return function (string) {
      var translated = translation_function(string);
      return '<span data-vzb-translate="' + string + '">' + translated + '</span>';
    };
  },

  /**
   * Translate all strings in the template
   */
  translateStrings: function translateStrings() {
    var t = this.getTranslationFunction();
    var strings = this.placeholder.querySelectorAll('[data-vzb-translate]');
    if (strings.length === 0) {
      return;
    }
    utils.forEach(strings, function (str) {
      if (!str || !str.getAttribute) {
        return;
      }
      str.innerHTML = t(str.getAttribute('data-vzb-translate'));
    });
  },

  /**
   * Executes after the template is loaded and rendered.
   * Ideally, it contains HTML instantiations related to template
   * At this point, this.element and this.placeholder are available
   * as DOM elements
   */
  readyOnce: function readyOnce() {},

  /**
   * Executes after the template and model (if any) are ready
   */
  ready: function ready() {},

  /**
   * Executes when the resize event is triggered.
   * Ideally, it only contains operations related to size
   */
  resize: function resize() {},

  /**
   * Executed after template is loaded
   * Ideally, it contains instantiations related to template
   */
  domReady: function domReady() {},

  /**
   * Clears a component
   */
  clear: function clear() {
    this.freeze();
    if (this.model) this.model.freeze();
    utils.forEach(this.components, function (c) {
      c.clear();
    });
  }
});

// Based on Simple JavaScript Templating by John Resig
//generic templating function
function templateFunc(str, data) {

  var func = function func(obj) {
    return str.replace(/<%=([^\%]*)%>/g, function (match) {
      //match t("...")
      var s = match.match(/t\s*\(([^)]+)\)/g);
      //replace with translation
      if (s.length) {
        s = obj.t(s[0].match(/\"([^"]+)\"/g)[0].split('"').join(''));
      }
      //use object[name]
      else {
          s = match.match(/([a-z\-A-Z]+([a-z\-A-Z0-9]?[a-zA-Z0-9]?)?)/g)[0];
          s = obj[s] || s;
        }
      return s;
    });
  };
  // Figure out if we're getting a template, or if we need to
  // load the template - and be sure to cache the result.
  var fn = !/<[a-z][\s\S]*>/i.test(str) ? templates[str] = templates[str] || templateFunc(_globals2.default.templates[str]) : func;

  // Provide some basic currying to the user
  return data ? fn(data) : fn;
}

//utility function to check if a component is a component
//TODO: Move to utils?
Component.isComponent = function (c) {
  return c._id && (c._id[0] === 't' || c._id[0] === 'c');
};

exports.default = Component;

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

var isObject = __webpack_require__(6);
module.exports = function(it){
  if(!isObject(it))throw TypeError(it + ' is not an object!');
  return it;
};

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

// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
var global = module.exports = typeof window != 'undefined' && window.Math == Math
  ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')();
if(typeof __g == 'number')__g = global; // eslint-disable-line no-undef

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

module.exports = function(exec){
  try {
    return !!exec();
  } catch(e){
    return true;
  }
};

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

module.exports = function(it){
  return typeof it === 'object' ? it !== null : typeof it === 'function';
};

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

var store      = __webpack_require__(81)('wks')
  , uid        = __webpack_require__(57)
  , Symbol     = __webpack_require__(4).Symbol
  , USE_SYMBOL = typeof Symbol == 'function';

var $exports = module.exports = function(name){
  return store[name] || (store[name] =
    USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name));
};

$exports.store = store;

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

// Thank's IE8 for his funny defineProperty
module.exports = !__webpack_require__(5)(function(){
  return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7;
});

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

var anObject       = __webpack_require__(3)
  , IE8_DOM_DEFINE = __webpack_require__(159)
  , toPrimitive    = __webpack_require__(33)
  , dP             = Object.defineProperty;

exports.f = __webpack_require__(8) ? Object.defineProperty : function defineProperty(O, P, Attributes){
  anObject(O);
  P = toPrimitive(P, true);
  anObject(Attributes);
  if(IE8_DOM_DEFINE)try {
    return dP(O, P, Attributes);
  } catch(e){ /* empty */ }
  if('get' in Attributes || 'set' in Attributes)throw TypeError('Accessors not supported!');
  if('value' in Attributes)O[P] = Attributes.value;
  return O;
};

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
// source https://github.com/encharm/Font-Awesome-SVG-PNG/tree/master/black/svg

var paintbrush = exports.paintbrush = '<svg class="vzb-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1792 1792"><path d="M1615 0q70 0 122.5 46.5t52.5 116.5q0 63-45 151-332 629-465 752-97 91-218 91-126 0-216.5-92.5t-90.5-219.5q0-128 92-212l638-579q59-54 130-54zm-909 1034q39 76 106.5 130t150.5 76l1 71q4 213-129.5 347t-348.5 134q-123 0-218-46.5t-152.5-127.5-86.5-183-29-220q7 5 41 30t62 44.5 59 36.5 46 17q41 0 55-37 25-66 57.5-112.5t69.5-76 88-47.5 103-25.5 125-10.5z"/></svg>';
var search = exports.search = '<svg class="vzb-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1792 1792"><path d="M1216 832q0-185-131.5-316.5t-316.5-131.5-316.5 131.5-131.5 316.5 131.5 316.5 316.5 131.5 316.5-131.5 131.5-316.5zm512 832q0 52-38 90t-90 38q-54 0-90-38l-343-342q-179 124-399 124-143 0-273.5-55.5t-225-150-150-225-55.5-273.5 55.5-273.5 150-225 225-150 273.5-55.5 273.5 55.5 225 150 150 225 55.5 273.5q0 220-124 399l343 343q37 37 37 90z"/></svg>';
var circle = exports.circle = '<svg class="vzb-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1792 1792"><path d="M1664 896q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/></svg>';
var expand = exports.expand = '<svg class="vzb-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1792 1792"><path d="M883 1056q0 13-10 23l-332 332 144 144q19 19 19 45t-19 45-45 19h-448q-26 0-45-19t-19-45v-448q0-26 19-45t45-19 45 19l144 144 332-332q10-10 23-10t23 10l114 114q10 10 10 23zm781-864v448q0 26-19 45t-45 19-45-19l-144-144-332 332q-10 10-23 10t-23-10l-114-114q-10-10-10-23t10-23l332-332-144-144q-19-19-19-45t19-45 45-19h448q26 0 45 19t19 45z"/></svg>';
var asterisk = exports.asterisk = '<svg class="vzb-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1792 1792"><path d="M1546 1050q46 26 59.5 77.5t-12.5 97.5l-64 110q-26 46-77.5 59.5t-97.5-12.5l-266-153v307q0 52-38 90t-90 38h-128q-52 0-90-38t-38-90v-307l-266 153q-46 26-97.5 12.5t-77.5-59.5l-64-110q-26-46-12.5-97.5t59.5-77.5l266-154-266-154q-46-26-59.5-77.5t12.5-97.5l64-110q26-46 77.5-59.5t97.5 12.5l266 153v-307q0-52 38-90t90-38h128q52 0 90 38t38 90v307l266-153q46-26 97.5-12.5t77.5 59.5l64 110q26 46 12.5 97.5t-59.5 77.5l-266 154z"/></svg>';
var trails = exports.trails = '<svg class="vzb-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1792 1792"><path d="M 1381.375 17.1875 C 1375.7825 17.176804 1370.1216 17.316078 1364.4375 17.5625 C 1273.4913 21.505489 1197.0982 57.199956 1135.2188 124.6875 C 1076.5961 188.62338 1047.6964 263.96059 1048.5312 350.65625 L 835.71875 433 C 797.77288 391.67699 749.96961 361.96416 692.3125 343.84375 C 604.96227 316.39162 520.95691 323.70366 440.25 365.8125 C 359.5432 407.92133 305.45225 472.64985 278 560 C 250.54783 647.35004 257.89117 731.38694 300 812.09375 C 342.10886 892.80075 406.83755 946.89147 494.1875 974.34375 C 576.9404 1000.3512 657.38873 994.58645 735.5625 957.09375 L 959.28125 1171.4375 L 972.375 1184.4062 C 966.2931 1198.3454 961.94845 1209.2226 959.34375 1217.0625 C 956.73915 1224.9024 953.7186 1236.224 950.25 1251.0312 L 711.03125 1285.1875 C 669.59175 1209.0324 607.72526 1157.2863 525.40625 1129.9375 C 438.51381 1101.0693 354.34933 1107.021 272.96875 1147.8125 C 191.58796 1188.6039 136.49335 1252.4513 107.625 1339.3438 C 78.756758 1426.2362 84.708528 1510.3694 125.5 1591.75 C 166.29138 1673.1307 230.1387 1728.2567 317.03125 1757.125 C 403.92369 1785.9933 488.05682 1780.0415 569.4375 1739.25 C 650.81799 1698.4587 705.94425 1634.6111 734.8125 1547.7188 C 737.41718 1539.8788 740.43763 1528.5573 743.90625 1513.75 L 983.125 1479.5938 C 1024.5644 1555.7487 1086.4309 1607.4948 1168.75 1634.8438 C 1255.6425 1663.7119 1339.8069 1657.7603 1421.1875 1616.9688 C 1502.5682 1576.1772 1557.6631 1512.3299 1586.5312 1425.4375 C 1615.3996 1338.5451 1609.4477 1254.4119 1568.6562 1173.0312 C 1527.8647 1091.6506 1464.0174 1036.5244 1377.125 1007.6562 C 1294.9259 980.34721 1214.5066 984.74084 1135.8438 1020.8125 L 1120.2812 1005.9062 L 898.0625 785.96875 C 902.79653 774.40321 906.33847 765.03422 908.5 758.15625 C 920.42249 720.22 925.7916 682.90194 924.59375 646.21875 L 1130.9688 566.34375 C 1141.2015 577.59424 1149.3796 586.0106 1155.4688 591.59375 C 1222.9566 653.47326 1302.1474 682.44278 1393.0938 678.5 C 1484.04 674.55731 1560.4642 638.83151 1622.3438 571.34375 C 1684.2232 503.85591 1713.1929 424.6337 1709.25 333.6875 C 1705.3072 242.74139 1669.5816 166.34819 1602.0938 104.46875 C 1538.8238 46.456824 1465.2625 17.347946 1381.375 17.1875 z "/></svg>';
var lock = exports.lock = '<svg class="vzb-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1792 1792"><path d="M640 768h512v-192q0-106-75-181t-181-75-181 75-75 181v192zm832 96v576q0 40-28 68t-68 28h-960q-40 0-68-28t-28-68v-576q0-40 28-68t68-28h32v-192q0-184 132-316t316-132 316 132 132 316v192h32q40 0 68 28t28 68z"/></svg>';
var unlock = exports.unlock = '<svg class="vzb-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1792 1792"><path d="M1376 768q40 0 68 28t28 68v576q0 40-28 68t-68 28h-960q-40 0-68-28t-28-68v-576q0-40 28-68t68-28h32v-320q0-185 131.5-316.5t316.5-131.5 316.5 131.5 131.5 316.5q0 26-19 45t-45 19h-64q-26 0-45-19t-19-45q0-106-75-181t-181-75-181 75-75 181v320h736z"/></svg>';
var unexpand = exports.unexpand = '<svg class="vzb-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1792 1792"><path d="M896 960v448q0 26-19 45t-45 19-45-19l-144-144-332 332q-10 10-23 10t-23-10l-114-114q-10-10-10-23t10-23l332-332-144-144q-19-19-19-45t19-45 45-19h448q26 0 45 19t19 45zm755-672q0 13-10 23l-332 332 144 144q19 19 19 45t-19 45-45 19h-448q-26 0-45-19t-19-45v-448q0-26 19-45t45-19 45 19l144 144 332-332q10-10 23-10t23 10l114 114q10 10 10 23z"/></svg>';
var axes = exports.axes = '<svg class="vzb-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"><path d="M430.25,379.655l-75.982-43.869v59.771H120.73V151.966h59.774l-43.869-75.983L92.767,0L48.898,75.983L5.029,151.966h59.775 v271.557c0,15.443,12.52,27.965,27.963,27.965h261.5v59.773l75.982-43.869l75.982-43.867L430.25,379.655z"/></svg>';
var gear = exports.gear = '<svg class="vzb-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1792 1792"><path d="M1152 896q0-106-75-181t-181-75-181 75-75 181 75 181 181 75 181-75 75-181zm512-109v222q0 12-8 23t-20 13l-185 28q-19 54-39 91 35 50 107 138 10 12 10 25t-9 23q-27 37-99 108t-94 71q-12 0-26-9l-138-108q-44 23-91 38-16 136-29 186-7 28-36 28h-222q-14 0-24.5-8.5t-11.5-21.5l-28-184q-49-16-90-37l-141 107q-10 9-25 9-14 0-25-11-126-114-165-168-7-10-7-23 0-12 8-23 15-21 51-66.5t54-70.5q-27-50-41-99l-183-27q-13-2-21-12.5t-8-23.5v-222q0-12 8-23t19-13l186-28q14-46 39-92-40-57-107-138-10-12-10-24 0-10 9-23 26-36 98.5-107.5t94.5-71.5q13 0 26 10l138 107q44-23 91-38 16-136 29-186 7-28 36-28h222q14 0 24.5 8.5t11.5 21.5l28 184q49 16 90 37l142-107q9-9 24-9 13 0 25 10 129 119 165 170 7 8 7 22 0 12-8 23-15 21-51 66.5t-54 70.5q26 50 41 98l183 28q13 2 21 12.5t8 23.5z"/></svg>';
var stack = exports.stack = '<svg class="vzb-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 54.849 54.849"><g><path d="M54.497,39.614l-10.363-4.49l-14.917,5.968c-0.537,0.214-1.165,0.319-1.793,0.319c-0.627,0-1.254-0.104-1.79-0.318     l-14.921-5.968L0.351,39.614c-0.472,0.203-0.467,0.524,0.01,0.716L26.56,50.81c0.477,0.191,1.251,0.191,1.729,0L54.488,40.33     C54.964,40.139,54.969,39.817,54.497,39.614z"/><path d="M54.497,27.512l-10.364-4.491l-14.916,5.966c-0.536,0.215-1.165,0.321-1.792,0.321c-0.628,0-1.256-0.106-1.793-0.321     l-14.918-5.966L0.351,27.512c-0.472,0.203-0.467,0.523,0.01,0.716L26.56,38.706c0.477,0.19,1.251,0.19,1.729,0l26.199-10.479     C54.964,28.036,54.969,27.716,54.497,27.512z"/><path d="M0.361,16.125l13.662,5.465l12.537,5.015c0.477,0.191,1.251,0.191,1.729,0l12.541-5.016l13.658-5.463     c0.477-0.191,0.48-0.511,0.01-0.716L28.277,4.048c-0.471-0.204-1.236-0.204-1.708,0L0.351,15.41     C-0.121,15.614-0.116,15.935,0.361,16.125z"/></g></svg>';
var drag = exports.drag = '<svg class="vzb-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1792 1792"><path d="M896 384q-53 0-90.5 37.5t-37.5 90.5v128h-32v-93q0-48-32-81.5t-80-33.5q-46 0-79 33t-33 79v429l-32-30v-172q0-48-32-81.5t-80-33.5q-46 0-79 33t-33 79v224q0 47 35 82l310 296q39 39 39 102 0 26 19 45t45 19h640q26 0 45-19t19-45v-25q0-41 10-77l108-436q10-36 10-77v-246q0-48-32-81.5t-80-33.5q-46 0-79 33t-33 79v32h-32v-125q0-40-25-72.5t-64-40.5q-14-2-23-2-46 0-79 33t-33 79v128h-32v-122q0-51-32.5-89.5t-82.5-43.5q-5-1-13-1zm0-128q84 0 149 50 57-34 123-34 59 0 111 27t86 76q27-7 59-7 100 0 170 71.5t70 171.5v246q0 51-13 108l-109 436q-6 24-6 71 0 80-56 136t-136 56h-640q-84 0-138-58.5t-54-142.5l-308-296q-76-73-76-175v-224q0-99 70.5-169.5t169.5-70.5q11 0 16 1 6-95 75.5-160t164.5-65q52 0 98 21 72-69 174-69z"/></svg>';
var warn = exports.warn = '<svg class="vzb-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512.209 512.209"><path d="M507.345,439.683L288.084,37.688c-3.237-5.899-7.71-10.564-13.429-13.988c-5.705-3.427-11.893-5.142-18.554-5.142   s-12.85,1.718-18.558,5.142c-5.708,3.424-10.184,8.089-13.418,13.988L4.859,439.683c-6.663,11.998-6.473,23.989,0.57,35.98   c3.239,5.517,7.664,9.897,13.278,13.128c5.618,3.237,11.66,4.859,18.132,4.859h438.529c6.479,0,12.519-1.622,18.134-4.859   c5.62-3.23,10.038-7.611,13.278-13.128C513.823,463.665,514.015,451.681,507.345,439.683z M292.655,411.132   c0,2.662-0.91,4.897-2.71,6.704c-1.807,1.811-3.949,2.71-6.427,2.71h-54.816c-2.474,0-4.616-0.899-6.423-2.71   c-1.809-1.807-2.713-4.042-2.713-6.704v-54.248c0-2.662,0.905-4.897,2.713-6.704c1.807-1.811,3.946-2.71,6.423-2.71h54.812   c2.479,0,4.62,0.899,6.428,2.71c1.803,1.807,2.71,4.042,2.71,6.704v54.248H292.655z M292.088,304.357   c-0.198,1.902-1.198,3.47-3.001,4.709c-1.811,1.238-4.046,1.854-6.711,1.854h-52.82c-2.663,0-4.947-0.62-6.849-1.854   c-1.908-1.243-2.858-2.807-2.858-4.716l-4.853-130.47c0-2.667,0.953-4.665,2.856-5.996c2.474-2.093,4.758-3.14,6.854-3.14h62.809   c2.098,0,4.38,1.043,6.854,3.14c1.902,1.331,2.851,3.14,2.851,5.424L292.088,304.357z"/></svg>';
var pin = exports.pin = '<svg class="vzb-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1792 1792"><path d="M800 864v-448q0-14-9-23t-23-9-23 9-9 23v448q0 14 9 23t23 9 23-9 9-23zm672 352q0 26-19 45t-45 19h-429l-51 483q-2 12-10.5 20.5t-20.5 8.5h-1q-27 0-32-27l-76-485h-404q-26 0-45-19t-19-45q0-123 78.5-221.5t177.5-98.5v-512q-52 0-90-38t-38-90 38-90 90-38h640q52 0 90 38t38 90-38 90-90 38v512q99 0 177.5 98.5t78.5 221.5z"/></svg>';
var question = exports.question = '<svg class="vzb-icon" xmlns="http://www.w3.org/2000/svg" viewBox="17 17 483 483"> <circle stroke-width="40" cx="258.57" cy="258.57" r="220"/> <path d="M299.756,413.021v-61.78c0-3.003-0.966-5.472-2.896-7.401s-4.398-2.896-7.401-2.896h-61.78 c-3.003,0-5.47,0.965-7.4,2.896c-1.932,1.931-2.896,4.398-2.896,7.401v61.78c0,3.002,0.965,5.47,2.896,7.399 c1.931,1.931,4.396,2.896,7.4,2.896h61.779c3.003,0,5.472-0.967,7.401-2.896S299.756,416.021,299.756,413.021z"/> <path d="M382.128,196.789c0-18.877-5.952-36.36-17.856-52.449c-11.905-16.088-26.762-28.53-44.566-37.325 c-17.804-8.795-36.037-13.192-54.7-13.192c-52.127,0-91.919,22.845-119.377,68.537c-3.218,5.148-2.359,9.653,2.574,13.514 l42.474,32.177c1.502,1.287,3.54,1.931,6.114,1.931c3.433,0,6.115-1.287,8.044-3.861c11.369-14.587,20.594-24.454,27.672-29.603 c7.294-5.148,16.519-7.723,27.673-7.723c10.297,0,19.468,2.789,27.513,8.366c8.044,5.578,12.065,11.906,12.065,18.985 c0,8.151-2.146,14.694-6.437,19.628c-4.29,4.934-11.583,9.76-21.881,14.479c-13.514,6.006-25.901,15.284-37.164,27.834 c-11.263,12.549-16.894,26.01-16.894,40.382v11.583c0,3.004,0.965,5.472,2.896,7.401c1.931,1.93,4.396,2.896,7.4,2.896h61.779 c3.003,0,5.471-0.965,7.401-2.896c1.93-1.931,2.896-4.397,2.896-7.401c0-4.075,2.306-9.385,6.917-15.928 c4.612-6.542,10.458-11.852,17.537-15.927c6.863-3.861,12.119-6.918,15.768-9.171c3.646-2.252,8.579-6.008,14.802-11.263 c6.22-5.255,10.993-10.402,14.317-15.443c3.325-5.042,6.328-11.53,9.01-19.467C380.788,214.916,382.128,206.228,382.128,196.789z"/> </svg>';
var close = exports.close = '<svg class="vzb-icon vzb-icon-pin" viewBox="-150 -250 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1149 414q0 26 -19 45l-181 181l181 181q19 19 19 45q0 27 -19 46l-90 90q-19 19 -46 19q-26 0 -45 -19l-181 -181l-181 181q-19 19 -45 19q-27 0 -46 -19l-90 -90q-19 -19 -19 -46q0 -26 19 -45l181 -181l-181 -181q-19 -19 -19 -45q0 -27 19 -46l90 -90q19 -19 46 -19 q26 0 45 19l181 181l181 -181q19 -19 45 -19q27 0 46 19l90 90q19 19 19 46z"/></svg>';
var presentation = exports.presentation = '<svg class="vzb-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path id="flip-chart-1" d="M334.549,393.834l58.607,68.666h-45.096l-58.709-68.666H334.549z M240.333,462.5h34.333v-68.666h-34.333 V462.5z M360.5,153.5h-34.334v137.334H360.5V153.5z M121.566,462.5h45.113l58.709-68.666h-45.197L121.566,462.5z M206,273.666 h-34.333v17.168H206V273.666z M257.5,239.333h-34.333v51.5H257.5V239.333z M309,205h-34.334v85.834H309V205z M446.334,102h-17.168 v257.5H85.833V102H68.667V50.5h377.667V102z M394.834,102H120.167v223.166h274.667V102z"/></svg>';
var about = exports.about = '<svg class="vzb-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1792 1792"><path d="M1088 1256v240q0 16-12 28t-28 12h-240q-16 0-28-12t-12-28v-240q0-16 12-28t28-12h240q16 0 28 12t12 28zm316-600q0 54-15.5 101t-35 76.5-55 59.5-57.5 43.5-61 35.5q-41 23-68.5 65t-27.5 67q0 17-12 32.5t-28 15.5h-240q-15 0-25.5-18.5t-10.5-37.5v-45q0-83 65-156.5t143-108.5q59-27 84-56t25-76q0-42-46.5-74t-107.5-32q-65 0-108 29-35 25-107 115-13 16-31 16-12 0-25-8l-164-125q-13-10-15.5-25t5.5-28q160-266 464-266 80 0 161 31t146 83 106 127.5 41 158.5z"/></svg>';
var cursorArrow = exports.cursorArrow = '<svg class="vzb-icon" viewBox="-200 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1389 1043q31 30 14 69-17 40-59 40h-382l201 476q10 25 0 49t-34 35l-177 75q-25 10-49 0t-35-34l-191-452-312 312q-19 19-45 19-12 0-24-5-40-17-40-59v-1504q0-42 40-59 12-5 24-5 27 0 45 19z"/></svg>';
var cursorPlus = exports.cursorPlus = '<svg class="vzb-icon" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1088 800v64q0 13-9.5 22.5t-22.5 9.5h-224v224q0 13-9.5 22.5t-22.5 9.5h-64q-13 0-22.5-9.5t-9.5-22.5v-224h-224q-13 0-22.5-9.5t-9.5-22.5v-64q0-13 9.5-22.5t22.5-9.5h224v-224q0-13 9.5-22.5t22.5-9.5h64q13 0 22.5 9.5t9.5 22.5v224h224q13 0 22.5 9.5t9.5 22.5zm128 32q0-185-131.5-316.5t-316.5-131.5-316.5 131.5-131.5 316.5 131.5 316.5 316.5 131.5 316.5-131.5 131.5-316.5zm512 832q0 53-37.5 90.5t-90.5 37.5q-54 0-90-38l-343-342q-179 124-399 124-143 0-273.5-55.5t-225-150-150-225-55.5-273.5 55.5-273.5 150-225 225-150 273.5-55.5 273.5 55.5 225 150 150 225 55.5 273.5q0 220-124 399l343 343q37 37 37 90z"/></svg>';
var cursorMinus = exports.cursorMinus = '<svg class="vzb-icon" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1088 800v64q0 13-9.5 22.5t-22.5 9.5h-576q-13 0-22.5-9.5t-9.5-22.5v-64q0-13 9.5-22.5t22.5-9.5h576q13 0 22.5 9.5t9.5 22.5zm128 32q0-185-131.5-316.5t-316.5-131.5-316.5 131.5-131.5 316.5 131.5 316.5 316.5 131.5 316.5-131.5 131.5-316.5zm512 832q0 53-37.5 90.5t-90.5 37.5q-54 0-90-38l-343-342q-179 124-399 124-143 0-273.5-55.5t-225-150-150-225-55.5-273.5 55.5-273.5 150-225 225-150 273.5-55.5 273.5 55.5 225 150 150 225 55.5 273.5q0 220-124 399l343 343q37 37 37 90z"/></svg>';
var hundredPercent = exports.hundredPercent = '<svg class="vzb-icon" xmlns="http://www.w3.org/2000/svg"><g transform="translate(18 11)"><text transform="scale(0.9 1)" x="0" y="0">100</text><text transform="scale(0.6 1)" class="percent" x="0" y="0">%</text></g></svg>';
var percent = exports.percent = '<svg class="vzb-icon" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1408 1280q0-52-38-90t-90-38-90 38-38 90 38 90 90 38 90-38 38-90zm-768-768q0-52-38-90t-90-38-90 38-38 90 38 90 90 38 90-38 38-90zm1024 768q0 159-112.5 271.5t-271.5 112.5-271.5-112.5-112.5-271.5 112.5-271.5 271.5-112.5 271.5 112.5 112.5 271.5zm-96-1088q0 20-13 38l-1056 1408q-19 26-51 26h-160q-26 0-45-19t-19-45q0-20 13-38l1056-1408q19-26 51-26h160q26 0 45 19t19 45zm-672 320q0 159-112.5 271.5t-271.5 112.5-271.5-112.5-112.5-271.5 112.5-271.5 271.5-112.5 271.5 112.5 112.5 271.5z"/></svg>';

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _iconset = __webpack_require__(10);

var _requireAll = __webpack_require__(70);

var _requireAll2 = _interopRequireDefault(_requireAll);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

var dialogTemplates = (0, _requireAll2.default)(__webpack_require__(455));

/*!
 * VIZABI DIALOG
 * Reusable Dialog component
 */

var Dialog = _component2.default.extend({
  /**
   * Initializes the dialog
   * @param {Object} config Initial config, with name and placeholder
   * @param {Object} parent Reference to tool
   */
  init: function init(config, parent) {
    this.name = this.name || '';

    this.model_expects = this.model_expects || [{
      name: "state",
      type: "model"
    }, {
      name: "ui",
      type: "ui"
    }, {
      name: "locale",
      type: "locale"
    }];

    this.template = dialogTemplates[this.name];

    this._super(config, parent);
  },

  /**
   * Executed when the dialog has been rendered
   */
  readyOnce: function readyOnce() {
    this.element = d3.select(this.element);
    this.titleEl = this.element.selectAll('.vzb-top-dialog > .vzb-dialog-modal > .vzb-dialog-title');
    this.buttonsEl = this.element.selectAll('.vzb-top-dialog > .vzb-dialog-modal > .vzb-dialog-buttons');
    this.contentEl = this.element.selectAll('.vzb-top-dialog > .vzb-dialog-modal > .vzb-dialog-content');
  },

  ready: function ready() {
    var _this = this;
    this.placeholderEl = d3.select(this.placeholder);
    this.rootEl = this.root.element instanceof Array ? this.root.element : d3.select(this.root.element);
    this.dragHandler = this.placeholderEl.select("[data-click='dragDialog']");
    this.dragHandler.html(_iconset.drag);
    this.pinIcon = this.placeholderEl.select("[data-click='pinDialog']");
    this.pinIcon.html(_iconset.pin);
    this.topPos = '';
    var profile = this.getLayoutProfile();

    var dg = dialogDrag(this.placeholderEl, this.rootEl, 10);
    var dragBehavior = d3.behavior.drag().on('dragstart', function D3dialogDragStart() {
      var topPos = _this.placeholderEl.node().offsetTop;
      _this.placeholderEl.style({ 'top': topPos + 'px', 'bottom': 'auto' });
      _this.trigger('dragstart');
      dg.dragStart(d3.event);
    }).on('drag', function D3dialogDrag() {
      _this.trigger('drag');
      dg.drag(d3.event);
    }).on('dragend', function D3dialogDrag() {
      _this.rightPos = _this.placeholderEl.style('right');
      _this.topPos = _this.placeholderEl.style('top');
      _this.trigger('dragend');
    });
    this.dragHandler.call(dragBehavior);

    this.dragHandler.classed("vzb-hidden", profile === 'small');
    this.pinIcon.classed("vzb-hidden", profile === 'small');
    this.resize();
  },

  resize: function resize() {
    if (this.placeholderEl && this.rootEl && this.placeholderEl.classed('vzb-top-dialog')) {
      this.placeholderEl.classed('notransition', true);

      var profile = this.getLayoutProfile();

      if (profile !== 'small') {
        var chartWidth = parseInt(this.rootEl.style('width'), 10);
        var dialogRight = parseInt(this.rightPos, 10);
        var chartHeight = parseInt(this.rootEl.style('height'), 10);
        var dialogTop = parseInt(this.topPos, 10);
        var dialogWidth = parseInt(this.placeholderEl.style('width'), 10);
        var dialogHeight = parseInt(this.placeholderEl.style('height'), 10);
        var dialogRightMargin = parseInt(this.placeholderEl.style('margin-right'), 10) || 0;
        if (utils.isNumber(dialogRight) && dialogRight > chartWidth - dialogWidth - dialogRightMargin) {
          if (this.rightPos) {
            this.rightPos = chartWidth - dialogWidth - dialogRightMargin + 'px';
            if (this.isOpen) this.placeholderEl.style('right', this.rightPos);
          }
        }
        if (utils.isNumber(dialogTop) && utils.isNumber(dialogHeight) && dialogTop >= 0 && dialogTop > chartHeight - dialogHeight) {
          if (this.topPos) {
            this.topPos = (chartHeight - dialogHeight > 0 ? chartHeight - dialogHeight : 0) + 'px';
            if (this.isOpen) this.placeholderEl.style('top', this.topPos);
          }
        }

        if (this.topPos && this.getLayoutProfile() === 'large' && this.rootEl.classed("vzb-dialog-expand-true")) {
          this.placeholderEl.style('bottom', 'auto');
        }

        if (this.rootEl.classed('vzb-landscape')) {}
        // var contentHeight = parseInt(this.rootEl.style('height'));
        // var placeholderHeight = parseInt(this.placeholderEl.style('height'));
        // if (contentHeight < placeholderHeight) {
        //   this.topPos = (-contentHeight + 50) + 'px';
        //   this.rightPos = '';
        //   this.placeholderEl.style('right', this.rightPos);
        //   this.placeholderEl.style('bottom', 'auto');
        // } else {
        //   //this.topPos = '';
        //   this.placeholderEl.style('bottom', '');
        // }

        //this.placeholderEl.style('top', this.topPos);
        this.element.style('max-height', '');
      } else {
        this.rightPos = '';
        this.topPos = '';
        this.placeholderEl.attr('style', '');
        // var totalHeight = this.root.element.offsetHeight;
        // if(this.rootEl.classed('vzb-portrait')) totalHeight = totalHeight - 50;
        // this.element.style('max-height', (totalHeight - 10) + 'px');
      }

      this.dragHandler.classed("vzb-hidden", profile === 'small');
      this.pinIcon.classed("vzb-hidden", profile === 'small');

      this._setMaxHeight();
    }
  },

  _setMaxHeight: function _setMaxHeight() {
    var totalHeight = this.root.element.offsetHeight;
    if (this.getLayoutProfile() !== 'small') {
      if (!this.topPos && this.getLayoutProfile() === 'large' && this.rootEl.classed("vzb-dialog-expand-true")) {
        var dialogBottom = parseInt(this.placeholderEl.style('bottom'), 10);
        totalHeight = totalHeight - dialogBottom;
      } else {
        var topPos = this.topPos ? parseInt(this.topPos, 10) : this.placeholderEl[0][0].offsetTop;
        totalHeight = totalHeight - topPos;
      }
    } else {
      totalHeight = this.rootEl.classed('vzb-portrait') ? totalHeight - 50 : totalHeight - 10;
    }

    this.element.style('max-height', totalHeight + 'px');

    //set 'max-height' to content for IE11
    var contentHeight = totalHeight - this.titleEl.node().offsetHeight - this.buttonsEl.node().offsetHeight;
    this.contentEl.style('max-height', contentHeight + 'px');
  },

  beforeOpen: function beforeOpen() {
    var _this = this;

    this.transitionEvents = ['webkitTransitionEnd', 'transitionend', 'msTransitionEnd', 'oTransitionEnd'];
    this.transitionEvents.forEach(function (event) {
      _this.placeholderEl.on(event, _this.transitionEnd.bind(_this, event));
    });

    this.placeholderEl.classed('notransition', true);

    this.placeholderEl.style({ 'top': '', 'bottom': '' }); // issues: 369 & 442

    if (this.topPos && this.getLayoutProfile() === 'large' && this.rootEl.classed("vzb-dialog-expand-true")) {
      var topPos = this.placeholderEl.node().offsetTop;
      this.placeholderEl.style({ 'top': topPos + 'px', 'bottom': 'auto' }); // issues: 369 & 442
    } else if (this.getLayoutProfile() !== 'small') {
      //if(this.rightPos) this.placeholderEl.style('right', this.rightPos);
    }

    this.placeholderEl.node().offsetTop;
    this.placeholderEl.classed('notransition', false);

    if (this.getLayoutProfile() === 'small') {
      this.placeholderEl.style('top', ''); // issues: 369 & 442
    } else if (this.rootEl.classed('vzb-landscape')) {// need to recalculate popup position (Safari 8 bug)
      // var contentHeight = parseInt(this.rootEl.style('height'));
      // var placeholderHeight = parseInt(this.placeholderEl.style('height'));
      // if (contentHeight < placeholderHeight) {
      //   this.topPos = (-contentHeight + 50) + 'px';
      //   this.rightPos = '';
      //   this.placeholderEl.style('right', this.rightPos);
      //   this.placeholderEl.style('bottom', 'auto');
      // } else {
      //   this.topPos = '';
      //   this.placeholderEl.style('bottom', '');
      // }
      //this.placeholderEl.style('top', this.topPos);
    }
  },

  /**
   * User has clicked to open this dialog
   */
  open: function open() {
    this.isOpen = true;
    if (this.getLayoutProfile() !== 'small') {
      if (this.topPos) {
        this.placeholderEl.style('top', this.topPos);
        this.placeholderEl.style('right', this.rightPos);
      }
    }
  },

  beforeClose: function beforeClose() {
    //issues: 369 & 442
    if (this.rootEl.classed('vzb-portrait') && this.getLayoutProfile() === 'small') {
      this.placeholderEl.style('top', 'auto'); // issues: 369 & 442
    }
    if (this.getLayoutProfile() === 'large' && this.rootEl.classed("vzb-dialog-expand-true")) {
      this.topPos0 = this.topPos ? this.placeholderEl.node().parentNode.offsetHeight - this.placeholderEl.node().offsetHeight + 'px' : '';
    }
    this.placeholderEl.classed('notransition', false);
    this.placeholderEl.node().offsetHeight; // trigger a reflow (flushing the css changes)
  },

  /**
   * User has closed this dialog
   */
  close: function close() {
    //issues: 369 & 442
    if (!(this.rootEl.classed('vzb-portrait') && this.getLayoutProfile() === 'small')) {
      this.placeholderEl.style('top', ''); // issues: 369 & 442
      this.placeholderEl.style('right', ''); // issues: 369 & 442
    }

    if (this.getLayoutProfile() === 'large' && this.rootEl.classed("vzb-dialog-expand-true")) {
      this.placeholderEl.style({ 'top': this.topPos0, 'right': '' });
    }
    this.isOpen = false;
    this.trigger('close');
  },

  transitionEnd: function transitionEnd(eventName) {
    var _this = this;

    this.transitionEvents.forEach(function (event) {
      _this.placeholderEl.on(event, null);
    });
    if (this.isOpen) {
      this.placeholderEl.classed('notransition', true);
    }
  }

});

function dialogDrag(element, container, xOffset) {
  var posX, posY, divTop, divRight, marginRight, marginLeft, xOffsetRight, xOffsetLeft, eWi, eHe, cWi, cHe, diffX, diffY;

  return {
    move: function move(x, y) {
      element.style('right', x + 'px');
      element.style('top', y + 'px');
    },

    dragStart: function dragStart(evt) {
      if (!utils.isTouchDevice()) {
        posX = evt.sourceEvent.clientX;
        posY = evt.sourceEvent.clientY;
      } else {
        var touchCoord = d3.touches(container.node());
        posX = touchCoord[0][0];
        posY = touchCoord[0][1];
      }
      divTop = parseInt(element.style('top')) || 0;
      divRight = parseInt(element.style('right')) || 0;
      marginLeft = parseInt(element.style('margin-left')) || 0;
      marginRight = parseInt(element.style('margin-right')) || 0;
      xOffsetLeft = Math.min(xOffset, marginLeft);
      xOffsetRight = Math.min(xOffset, marginRight);
      eWi = parseInt(element.style('width')) + marginLeft - xOffsetLeft;
      eHe = parseInt(element.style('height'));
      cWi = parseInt(container.style('width')) - marginRight;
      cHe = parseInt(container.style('height'));
      diffX = posX + divRight;
      diffY = posY - divTop;
    },

    drag: function drag(evt) {
      if (!utils.isTouchDevice()) {
        posX = evt.sourceEvent.clientX;
        posY = evt.sourceEvent.clientY;
      } else {
        var touchCoord = d3.touches(container.node());
        posX = touchCoord[0][0];
        posY = touchCoord[0][1];
      }
      var aX = -posX + diffX,
          aY = posY - diffY;
      if (aX < -xOffsetRight) aX = -xOffsetRight;
      if (aY < 0) aY = 0;
      if (aX + eWi > cWi) aX = cWi - eWi;
      if (aY + eHe > cHe) aY = cHe - eHe;

      this.move(aX, aY);
    }
  };
}

exports.default = Dialog;

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

// 7.1.15 ToLength
var toInteger = __webpack_require__(43)
  , min       = Math.min;
module.exports = function(it){
  return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991
};

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

// 7.1.13 ToObject(argument)
var defined = __webpack_require__(29);
module.exports = function(it){
  return Object(defined(it));
};

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _model = __webpack_require__(46);

var _model2 = _interopRequireDefault(_model);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _events = __webpack_require__(45);

var _events2 = _interopRequireDefault(_events);

var _iconset = __webpack_require__(10);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

var class_loading_first = 'vzb-loading-first';
var class_loading_data = 'vzb-loading-data';
var class_placeholder = 'vzb-placeholder';
var class_buttons_off = 'vzb-buttonlist-off';

var templates = {};

//tool model is quite simple and doesn't need to be registered
var ToolModel = _model2.default.extend({
  /**
   * Initializes the tool model.
   * @param {Tool}   the tool this tool model belongs to
   * @param {Object} values The initial values of this model
   */
  init: function init(tool, external_model) {
    this._id = utils.uniqueId('tm');
    this._type = 'tool';
    this._component = tool;

    // defaults are defined on the Tool
    // this way, each tool can have it's own default model
    this.getClassDefaults = function () {
      return tool.default_model;
    };

    // combine listeners from tool and external page to one object
    var listeners = utils.extend(tool.getToolListeners(), external_model.bind);
    delete external_model.bind; // bind shouldn't go to model tree

    this._super(tool.name, external_model, null, listeners);
  },

  /**
   * @return {object} Defaults of tool model and children
   * Tool defaults overwrite other models' default
   */
  getDefaults: function getDefaults() {
    return utils.deepExtend({}, this.getSubmodelDefaults(), this.getClassDefaults());
  },

  validate: function validate() {

    var max = 10;
    var c = 0;
    var _this = this;

    function validate_func(c) {
      // ToolModel uses validate function declared on Tool so each Tool can have its own validation.
      var model = JSON.stringify(_this.getPlainObject());
      _this._component.validate(_this);
      var model2 = JSON.stringify(_this.getPlainObject());

      if (c >= max) {
        utils.error('Max validation loop.');
      } else if (model !== model2) {
        validate_func(c++);
      }
    }

    validate_func(c);
  }

});

//tool
var Tool = _component2.default.extend({
  /**
    * Initializes the tool
    * @param {Object} placeholder object
    * @param {Object} external_model External model such as state, data, etc
    */
  init: function init(placeholder, external_model) {
    this._id = utils.uniqueId('t');

    this.template = this.getToolTemplate();

    // super also calls createModel
    this._super({
      placeholder: placeholder,
      model: external_model
    });

    this.render();

    this.setCSSClasses();
    this.setResizeHandler();
  },

  createModel: function createModel(external_model) {
    external_model = external_model || {}; //external model can be undefined
    external_model.bind = external_model.bind || {}; //bind functions can be undefined
    this.model = new ToolModel(this, external_model);
    this.model.setInterModelListeners();
  },

  getToolTemplate: function getToolTemplate() {
    return this.template || '<div class="vzb-tool vzb-tool-' + this.name + '">' + '<div class="vzb-tool-stage">' + '<div class="vzb-tool-viz">' + '</div>' + '<div class="vzb-tool-timeslider">' + '</div>' + '</div>' + '<div class="vzb-tool-sidebar">' + '<div class="vzb-tool-dialogs">' + '</div>' + '<div class="vzb-tool-buttonlist">' + '</div>' + '</div>' + '<div class="vzb-tool-datanotes vzb-hidden">' + '</div>' + '<div class="vzb-tool-treemenu vzb-hidden">' + '</div>' + '<div class="vzb-tool-datawarning vzb-hidden">' + '</div>' + '<div class="vzb-tool-labels vzb-hidden">' + '</div>' + '</div>';
  },

  getToolListeners: function getToolListeners() {
    var _this2 = this;

    var _this = this;
    return utils.extend(this.model_binds, {
      'change': function change(evt, path) {
        if (_this._ready) {
          _this.model.validate();

          if (evt.source.persistent) _this.model.trigger(new _events.DefaultEvent(evt.source, 'persistentChange'));
        }
      },
      'hook_change': function hook_change() {
        if (!_this.model.state.time.splash) {
          // not block when it initial splash screen
          _this.beforeLoading();
        }
      },
      'resize:ui': function resizeUi() {
        if (_this._ready) {
          _this.triggerResize();
        }
      },
      'translate:locale': function translateLocale() {
        _this.translateStrings();
        _this.model.ui.setRTL(_this.model.locale.isRTL());
      },
      'load_error': function load_error() {
        _this2.renderError();
        _this2.error.apply(_this2, arguments);
      }
    });
  },

  setResizeHandler: function setResizeHandler() {
    //only tools have layout (manage sizes)
    this.model.ui.setContainer(this.element);
  },

  triggerResize: utils.throttle(function () {
    this.trigger('resize');
  }, 100),

  startLoading: function startLoading() {
    var _this3 = this;

    this._super();

    Promise.all([this.model.startPreload(), this.startPreload()]).then(this.afterPreload.bind(this)).then(this.loadSplashScreen.bind(this)).then(function () {
      return utils.delay(300);
    }).then(this.model.startLoading.bind(this.model)).then(this.finishLoading.bind(this)).catch(function (error) {
      _events2.default.unfreezeAll();
      _this3.model.triggerLoadError(error);
    });
  },

  loadSplashScreen: function loadSplashScreen() {
    if (this.model.ui.splash) {
      //TODO: cleanup hardcoded splash screen
      this.model.state.time.splash = true;
      return this.model.startLoading({
        splashScreen: true
      });
    } else {
      return Promise.resolve();
    }
  },

  finishLoading: function finishLoading() {
    this.model.state.time.splash = false;
  },

  getPersistentModel: function getPersistentModel() {
    //try to find functions in properties of model.
    var removeFunctions = function removeFunctions(model) {
      for (var childKey in model) {
        if (typeof model[childKey] === 'function') {
          delete model[childKey];
          utils.warn('minModel validation. Function found in enumerable properties of ' + childKey + ". This key is deleted from minModel");
        } else if (_typeof(model[childKey]) === 'object') removeFunctions(model[childKey]);
      }
    };

    var currentToolModel = this.model.getPlainObject(true); // true = get only persistent model values
    removeFunctions(currentToolModel);
    return currentToolModel;
  },

  getPersistentMinimalModel: function getPersistentMinimalModel(diffModel) {
    var defaultModel = this.model.getDefaults();
    var currentPersistentModel = this.getPersistentModel();
    var redundantModel = utils.deepExtend(defaultModel, diffModel);
    return utils.diffObject(currentPersistentModel, redundantModel);
  },

  /**
   * Clears a tool
   */

  clear: function clear() {
    this.model.ui.clear();
    this.setModel = this.getModel = function () {
      return;
    };
    this._super();
  },

  /**
   * Visually display errors
   */
  error: function error(options, message) {
    if (!message) {
      message = options && options.type === 'data' ? 'Error loading chart data. <br>Please, try again later.' : 'Error loading chart';
    }

    this.placeholder.innerHTML = '<div class="vzb-error-message"><h1>' + _iconset.warn + '</h1><p>' + message + '</p></div>';
  },


  /**
   * Sets model from external page
   * @param {Object} JSONModel new model in JSON format
   * @param {Boolean} overwrite overwrite everything instead of extending
   */
  setModel: function setModel(newModelJSON, overwrite) {
    if (overwrite) {
      this.model.reset(newModelJSON);
    } else {
      this.model.set(newModelJSON);
    }
    this.setCSSClasses();
  },

  /**
   * get model
   * @return {Object} JSON object of model
   */
  getModel: function getModel() {
    return this.model.getPlainObject() || {};
  },
  /**
   * Displays loading class
   */
  beforeLoading: function beforeLoading() {
    utils.addClass(this.placeholder, class_loading_data);
  },

  /* ==========================
   * Validation and query
   * ==========================
   */
  /**
   * Validating the tool model
   * @param model the current tool model to be validated
   */
  validate: function validate(model) {
    model = this.model || model;

    if (!model || !model.state) return utils.warn("tool validation aborted: model.state looks wrong: " + model);
  },

  setCSSClasses: function setCSSClasses() {
    //add placeholder class
    utils.addClass(this.placeholder, class_placeholder);
    //add-remove buttonlist class
    if (!this.model.ui || !this.model.ui.buttons || !this.model.ui.buttons.length) {
      utils.addClass(this.element, class_buttons_off);
    } else {
      utils.removeClass(this.element, class_buttons_off);
    }
  }

});

exports.default = Tool;

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

var hasOwnProperty = {}.hasOwnProperty;
module.exports = function(it, key){
  return hasOwnProperty.call(it, key);
};

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

module.exports = function(it){
  if(typeof it != 'function')throw TypeError(it + ' is not a function!');
  return it;
};

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

var dP         = __webpack_require__(9)
  , createDesc = __webpack_require__(42);
module.exports = __webpack_require__(8) ? function(object, key, value){
  return dP.f(object, key, createDesc(1, value));
} : function(object, key, value){
  object[key] = value;
  return object;
};

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

var global    = __webpack_require__(4)
  , hide      = __webpack_require__(17)
  , has       = __webpack_require__(15)
  , SRC       = __webpack_require__(57)('src')
  , TO_STRING = 'toString'
  , $toString = Function[TO_STRING]
  , TPL       = ('' + $toString).split(TO_STRING);

__webpack_require__(34).inspectSource = function(it){
  return $toString.call(it);
};

(module.exports = function(O, key, val, safe){
  var isFunction = typeof val == 'function';
  if(isFunction)has(val, 'name') || hide(val, 'name', key);
  if(O[key] === val)return;
  if(isFunction)has(val, SRC) || hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key)));
  if(O === global){
    O[key] = val;
  } else {
    if(!safe){
      delete O[key];
      hide(O, key, val);
    } else {
      if(O[key])O[key] = val;
      else hide(O, key, val);
    }
  }
// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
})(Function.prototype, TO_STRING, function toString(){
  return typeof this == 'function' && this[SRC] || $toString.call(this);
});

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

var $export = __webpack_require__(0)
  , fails   = __webpack_require__(5)
  , defined = __webpack_require__(29)
  , quot    = /"/g;
// B.2.3.2.1 CreateHTML(string, tag, attribute, value)
var createHTML = function(string, tag, attribute, value) {
  var S  = String(defined(string))
    , p1 = '<' + tag;
  if(attribute !== '')p1 += ' ' + attribute + '="' + String(value).replace(quot, '&quot;') + '"';
  return p1 + '>' + S + '</' + tag + '>';
};
module.exports = function(NAME, exec){
  var O = {};
  O[NAME] = exec(createHTML);
  $export($export.P + $export.F * fails(function(){
    var test = ''[NAME]('"');
    return test !== test.toLowerCase() || test.split('"').length > 3;
  }), 'String', O);
};

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

// to indexed object, toObject with fallback for non-array-like ES3 strings
var IObject = __webpack_require__(68)
  , defined = __webpack_require__(29);
module.exports = function(it){
  return IObject(defined(it));
};

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var initializing = false;
var fnTest = /xyz/.test(function () {
  xyz;
}) ? /\b_super\b/ : /.*/;

function extend(name, extensions) {

  //in case there are two args
  extensions = arguments.length === 1 ? name : extensions;
  var _super = this.prototype;
  initializing = true;
  var prototype = new this();
  initializing = false;

  (0, _utils.forEach)(extensions, function (method, name) {
    if (typeof extensions[name] === 'function' && typeof _super[name] === 'function' && fnTest.test(extensions[name])) {
      prototype[name] = function (name, fn) {
        return function () {
          var tmp = this._super;
          this._super = _super[name];
          var ret = fn.apply(this, arguments);
          this._super = tmp;
          return ret;
        };
      }(name, extensions[name]);
    } else {
      prototype[name] = method;
    }
  });

  function Class() {
    if (this.trackInstances) Class.instances.push(this);
    if (!initializing && this.init) {
      this.init.apply(this, arguments);
    }
  }

  // Populate our constructed prototype object
  Class.prototype = prototype;
  Class.prototype.constructor = Class;
  Class.extend = extend;

  Class._collection = {};
  Class.instances = [];
  Class.register = function (name, code) {
    if (typeof this._collection[name] !== 'undefined') {
      (0, _utils.warn)('"' + name + '" is already registered. Overwriting...');
    }
    this._collection[name] = code;
  };

  Class.unregister = function (name) {
    this._collection[name] = void 0;
  };

  Class.getCollection = function () {
    return this._collection;
  };

  //define a method or field in this prototype
  Class.define = function (name, value) {
    this.prototype[name] = value;
  };

  //get an item of the collection from this class
  Class.get = function (name, silent) {
    if (this._collection.hasOwnProperty(name)) {
      return this._collection[name];
    }
    if (!silent) {
      (0, _utils.warn)('"' + name + '" was not found.');
    }
    return false;
  };
  //register extension by name
  if (arguments.length > 1 && this.register) {
    this.register(name, Class);
  }
  return Class;
}

var Class = function Class() {};
Class.extend = extend;

exports.default = Class;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _iconset = __webpack_require__(10);

var iconset = _interopRequireWildcard(_iconset);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*!
 * VIZABI BUTTONLIST
 * Reusable buttonlist component
 */

//default existing buttons
var class_active = "vzb-active";
var class_hidden = "vzb-hidden";
var class_active_locked = "vzb-active-locked";
var class_expand_dialog = "vzb-dialog-side";
var class_hide_btn = "vzb-dialog-side-btn";
var class_unavailable = "vzb-unavailable";
var class_vzb_fullscreen = "vzb-force-fullscreen";
var class_container_fullscreen = "vzb-container-fullscreen";

var ButtonList = _component2.default.extend({

  /**
   * Initializes the buttonlist
   * @param config component configuration
   * @param context component context (parent)
   */
  init: function init(config, context) {

    //set properties
    var _this = this;
    this.name = this.name || 'gapminder-buttonlist';
    //    this.template = '<div class="vzb-buttonlist"></div>';

    this.model_expects = [{
      name: "state",
      type: "model"
    }, {
      name: "ui",
      type: "ui"
    }, {
      name: "locale",
      type: "locale"
    }];

    this._available_buttons = {
      'find': {
        title: "buttons/find",
        icon: "search",
        required: false
      },
      'show': {
        title: "buttons/show",
        icon: "asterisk",
        required: false
      },
      'moreoptions': {
        title: "buttons/more_options",
        icon: "gear",
        required: true
      },
      'colors': {
        title: "buttons/colors",
        icon: "paintbrush",
        required: false
      },
      'size': {
        title: "buttons/size",
        icon: "circle",
        required: false
      },
      'fullscreen': {
        title: "buttons/expand",
        icon: "expand",
        func: this.toggleFullScreen.bind(this),
        required: true
      },
      'trails': {
        title: "buttons/trails",
        icon: "trails",
        func: this.toggleBubbleTrails.bind(this),
        required: false,
        statebind: "ui.chart.trails",
        statebindfunc: this.setBubbleTrails.bind(this)
      },
      'lock': {
        title: "buttons/lock",
        icon: "lock",
        func: this.toggleBubbleLock.bind(this),
        required: false,
        statebind: "ui.chart.lockNonSelected",
        statebindfunc: this.setBubbleLock.bind(this)
      },
      'inpercent': {
        title: "buttons/inpercent",
        icon: "percent",
        func: this.toggleInpercent.bind(this),
        required: false,
        statebind: "ui.chart.inpercent",
        statebindfunc: this.setInpercent.bind(this)
      },
      'presentation': {
        title: "buttons/presentation",
        icon: "presentation",
        func: this.togglePresentationMode.bind(this),
        required: false,
        statebind: "ui.presentation",
        statebindfunc: this.setPresentationMode.bind(this)
      },
      'about': {
        title: "buttons/about",
        icon: "about",
        required: false
      },
      'axes': {
        title: "buttons/axes",
        icon: "axes",
        required: false
      },
      'axesmc': {
        title: "buttons/axesmc",
        icon: "axes",
        required: false
      },
      'stack': {
        title: "buttons/stack",
        icon: "stack",
        required: false
      },
      '_default': {
        title: "Button",
        icon: "asterisk",
        required: false
      }
    };

    this._active_comp = false;

    this.model_binds = {
      "change:state.marker.select": function changeStateMarkerSelect(evt) {
        if (!_this._readyOnce) return;

        _this.setBubbleTrails();
        _this.setBubbleLock();
        _this._toggleButtons();

        //scroll button list to end if bottons appeared or disappeared
        // if(_this.entitiesSelected_1 !== (_this.model.state.marker.select.length > 0)) {
        //   _this.scrollToEnd();
        // }
        // _this.entitiesSelected_1 = _this.model.state.marker.select.length > 0;
      },
      "change:ui.chart": function changeUiChart(evt, path) {
        if (path.indexOf("lockActive") > -1) {
          _this.setBubbleLock();
        }
      }
    };

    // config.ui is same as this.model.ui here but this.model.ui is not yet available because constructor hasn't been called. 
    // can't call constructor earlier because this.model_binds needs to be complete before calling constructor
    config.ui.buttons.forEach(function (buttonId) {
      var button = _this._available_buttons[buttonId];
      if (button && button.statebind) {
        _this.model_binds['change:' + button.statebind] = function (evt) {
          button.statebindfunc(buttonId, evt.source.value);
        };
      }
    });

    // builds model
    this._super(config, context);

    this.validatePopupButtons(this.model.ui.buttons, this.model.ui.dialogs);
  },

  readyOnce: function readyOnce() {
    var _this = this;

    this.element = d3.select(this.placeholder);
    this.element.selectAll("div").remove();

    this.root.findChildByName("gapminder-dialogs").on('close', function (evt, params) {
      _this.setButtonActive(params.id, false);
    });

    var button_expand = (this.model.ui.dialogs || {}).sidebar || [];

    // // if button_expand has been passed in with boolean param or array must check and covert to array
    // if (button_expand){
    //   this.model.ui.dialogs.sidebar = (button_expand === true) ? this.model.ui.buttons : button_expand;
    // }

    // if (button_expand && button_expand.length !== 0) {
    //     d3.select(this.root.element).classed("vzb-dialog-expand-true", true);
    // }

    var button_list = [].concat(this.model.ui.buttons);

    // (button_expand||[]).forEach(function(button) {
    //   if (button_list.indexOf(button) === -1) {
    //     button_list.push(button);
    //   }
    // });

    this.model.ui.buttons = button_list;

    //add buttons and render components
    this._addButtons(button_list, button_expand);

    //store body overflow
    this._prev_body_overflow = document.body.style.overflow;

    this.setBubbleTrails();
    this.setBubbleLock();
    this.setInpercent();
    this.setPresentationMode();

    this._toggleButtons();
  },

  proceedClick: function proceedClick(id) {
    var _this = this;
    var btn = _this.element.selectAll(".vzb-buttonlist-btn[data-btn='" + id + "']"),
        classes = btn.attr("class"),
        btn_config = _this._available_buttons[id];

    if (btn_config && btn_config.func) {
      btn_config.func(id);
    } else {
      var btn_active = classes.indexOf(class_active) === -1;

      btn.classed(class_active, btn_active);
      var evt = {};
      evt['id'] = id;
      evt['active'] = btn_active;
      _this.trigger('click', evt);
    }
  },

  validatePopupButtons: function validatePopupButtons(buttons, dialogs) {
    var _this = this;

    var popupDialogs = dialogs.popup;
    var popupButtons = buttons.filter(function (d) {
      return _this._available_buttons[d] && !_this._available_buttons[d].func;
    });
    for (var i = 0, j = popupButtons.length; i < j; i++) {
      if (popupDialogs.indexOf(popupButtons[i]) == -1) {
        return utils.error('Buttonlist: bad buttons config: "' + popupButtons[i] + '" is missing in popups list');
      }
    }
    return false; //all good
  },

  /*
   * reset buttons show state
   */
  _showAllButtons: function _showAllButtons() {
    // show all existing buttons
    var _this = this;
    var buttons = this.element.selectAll(".vzb-buttonlist-btn");
    buttons.each(function (d, i) {
      var button = d3.select(this);
      button.style('display', '');
    });
  },

  /*
  * determine which buttons are shown on the buttonlist
  */
  _toggleButtons: function _toggleButtons() {
    var _this = this;
    var parent = this.parent.element.node ? this.parent.element : d3.select(this.parent.element);

    //HERE
    var button_expand = (this.model.ui.dialogs || {}).sidebar || [];
    _this._showAllButtons();

    var buttons = this.element.selectAll(".vzb-buttonlist-btn");

    var container = this.element.node().getBoundingClientRect();

    var not_required = [];
    var required = [];

    var button_width = 80;
    var button_height = 80;
    var container_width = this.element.node().getBoundingClientRect().width;
    var container_height = this.element.node().getBoundingClientRect().height;
    var buttons_width = 0;
    var buttons_height = 0;

    buttons.each(function (d, i) {
      var button_data = d;
      var button = d3.select(this);
      var expandable = button_expand.indexOf(button_data.id) !== -1;
      var button_margin = { top: parseInt(button.style("margin-top")), right: parseInt(button.style("margin-right")), left: parseInt(button.style("margin-left")), bottom: parseInt(button.style("margin-bottom")) };
      button_width = button.node().getBoundingClientRect().width + button_margin.right + button_margin.left;
      button_height = button.node().getBoundingClientRect().height + button_margin.top + button_margin.bottom;

      if (!button.classed(class_hidden)) {
        if (!expandable || _this.getLayoutProfile() !== 'large') {
          buttons_width += button_width;
          buttons_height += button_height;
          //sort buttons between required and not required buttons.
          // Not required buttons will only be shown if there is space available
          if (button_data.required) {
            required.push(button);
          } else {
            not_required.push(button);
          }
        } else {
          button.style("display", "none");
        }
      }
    });
    var width_diff = buttons_width - container_width;
    var height_diff = buttons_height - container_height;
    var number_of_buttons = 1;

    //check if container is landscape or portrait
    // if portrait small or large with expand, use width
    if (parent.classed("vzb-large") && parent.classed("vzb-dialog-expand-true") || parent.classed("vzb-small") && parent.classed("vzb-portrait")) {
      //check if the width_diff is small. If it is, add to the container
      // width, to allow more buttons in a way that is still usable
      if (width_diff > 0 && width_diff <= 10) {
        container_width += width_diff;
      }
      number_of_buttons = Math.floor(container_width / button_width) - required.length;
      if (number_of_buttons < 0) {
        number_of_buttons = 0;
      }
      // else, use height
    } else {
      //check if the width_diff is small. If it is, add to the container
      // width, to allow more buttons in a way that is still usable
      if (height_diff > 0 && height_diff <= 10) {
        container_height += height_diff;
      }
      number_of_buttons = Math.floor(container_height / button_height) - required.length;
      if (number_of_buttons < 0) {
        number_of_buttons = 0;
      }
    }
    //change the display property of non required buttons, from right to
    // left
    not_required.reverse();
    var hiddenButtons = [];
    for (var i = 0, j = not_required.length - number_of_buttons; i < j; i++) {
      not_required[i].style("display", "none");
      hiddenButtons.push(not_required[i].attr("data-btn"));
    }

    var evt = {};
    evt['hiddenButtons'] = hiddenButtons;
    _this.trigger('toggle', evt);
  },

  /*
   * adds buttons configuration to the components and template_data
   * @param {Array} button_list list of buttons to be added
   */
  _addButtons: function _addButtons(button_list, button_expand) {
    var _this = this;
    this._components_config = [];
    var details_btns = [];
    if (!button_list.length) return;
    //add a component for each button
    for (var i = 0; i < button_list.length; i++) {

      var btn = button_list[i];
      var btn_config = this._available_buttons[btn];

      //add template data
      var d = btn_config ? btn : "_default";
      var details_btn = utils.clone(this._available_buttons[d]);
      if (d == "_default") {
        details_btn.title = "buttons/" + btn;
      }
      details_btn.id = btn;
      details_btn.icon = iconset[details_btn.icon];
      details_btns.push(details_btn);
    };

    var t = this.getTranslationFunction(true);

    this.element.selectAll('button').data(details_btns).enter().append("button").attr('class', function (d) {
      var cls = 'vzb-buttonlist-btn';
      if (button_expand.length > 0) {
        if (button_expand.indexOf(d.id) > -1) {
          cls += ' vzb-dialog-side-btn';
        }
      }

      return cls;
    }).attr('data-btn', function (d) {
      return d.id;
    }).html(function (btn) {
      return "<span class='vzb-buttonlist-btn-icon fa'>" + btn.icon + "</span><span class='vzb-buttonlist-btn-title'>" + t(btn.title) + "</span>";
    });

    var buttons = this.element.selectAll(".vzb-buttonlist-btn");

    //clicking the button
    buttons.on('click', function () {

      d3.event.preventDefault();
      d3.event.stopPropagation();

      var id = d3.select(this).attr("data-btn");
      _this.proceedClick(id);
    });
  },

  scrollToEnd: function scrollToEnd() {
    var target = 0;
    var parent = d3.select(".vzb-tool");

    if (parent.classed("vzb-portrait") && parent.classed("vzb-small")) {
      if (this.model.state.marker.select.length > 0) target = this.element[0][0].scrollWidth;
      this.element[0][0].scrollLeft = target;
    } else {
      if (this.model.state.marker.select.length > 0) target = this.element[0][0].scrollHeight;
      this.element[0][0].scrollTop = target;
    }
  },

  /*
   * RESIZE:
   * Executed whenever the container is resized
   * Ideally, it contains only operations related to size
   */
  resize: function resize() {
    //TODO: what to do when resizing?

    //toggle presentaion off is switch to 'small' profile
    if (this.getLayoutProfile() === 'small' && this.model.ui.presentation) {
      this.togglePresentationMode();
    }

    this._toggleButtons();
  },

  setButtonActive: function setButtonActive(id, boolActive) {
    var btn = this.element.selectAll(".vzb-buttonlist-btn[data-btn='" + id + "']");

    btn.classed(class_active, boolActive);
  },

  toggleBubbleTrails: function toggleBubbleTrails() {
    this.model.ui.chart.trails = !this.model.ui.chart.trails;
    this.setBubbleTrails();
  },
  setBubbleTrails: function setBubbleTrails() {
    var trails = (this.model.ui.chart || {}).trails;
    if (!trails && trails !== false) return;
    var id = "trails";
    var btn = this.element.selectAll(".vzb-buttonlist-btn[data-btn='" + id + "']");
    if (!btn.node()) return utils.warn("setBubbleTrails: no button '" + id + "' found in DOM. doing nothing");

    btn.classed(class_active_locked, trails);
    btn.classed(class_hidden, this.model.state.marker.select.length == 0);
  },
  toggleBubbleLock: function toggleBubbleLock(id) {
    var active = (this.model.ui.chart || {}).lockActive;

    if (this.model.state.marker.select.length == 0 && !active) return;

    var locked = this.model.ui.chart.lockNonSelected;
    var time = this.model.state.time;
    locked = locked ? 0 : time.formatDate(time.value);
    this.model.ui.chart.lockNonSelected = locked;

    this.setBubbleLock();
  },
  setBubbleLock: function setBubbleLock() {
    var locked = (this.model.ui.chart || {}).lockNonSelected;
    var active = (this.model.ui.chart || {}).lockActive;
    if (!locked && locked !== 0) return;

    if (locked !== 0 && this.model.state.marker.select.length === 0 && !active) {
      locked = this.model.ui.chart.lockNonSelected = 0;
    }

    var id = "lock";
    var btn = this.element.selectAll(".vzb-buttonlist-btn[data-btn='" + id + "']");
    if (!btn.node()) return utils.warn("setBubbleLock: no button '" + id + "' found in DOM. doing nothing");

    var translator = this.model.locale.getTFunction();

    btn.classed(class_unavailable, this.model.state.marker.select.length == 0 && !active);
    if (typeof active == "undefined") {
      btn.classed(class_hidden, this.model.state.marker.select.length == 0);
    } else {
      btn.classed(class_hidden, !active);
    }

    btn.classed(class_active_locked, locked);
    btn.select(".vzb-buttonlist-btn-title").text(locked ? locked : translator("buttons/lock"));

    btn.select(".vzb-buttonlist-btn-icon").html(iconset[locked ? "lock" : "unlock"]);
  },
  toggleInpercent: function toggleInpercent() {
    this.model.ui.chart.inpercent = !this.model.ui.chart.inpercent;
    this.setInpercent();
  },
  setInpercent: function setInpercent() {
    if (typeof (this.model.ui.chart || {}).inpercent == "undefined") return;
    var id = 'inpercent';
    var translator = this.model.locale.getTFunction();
    var btn = this.element.selectAll(".vzb-buttonlist-btn[data-btn='" + id + "']");

    btn.classed(class_active_locked, this.model.ui.chart.inpercent);
  },
  togglePresentationMode: function togglePresentationMode() {
    this.model.ui.presentation = !this.model.ui.presentation;
    this.setPresentationMode();
  },
  setPresentationMode: function setPresentationMode() {
    var id = 'presentation';
    var translator = this.model.locale.getTFunction();
    var btn = this.element.selectAll(".vzb-buttonlist-btn[data-btn='" + id + "']");

    btn.classed(class_active_locked, this.model.ui.presentation);
  },
  toggleFullScreen: function toggleFullScreen(id, emulateClick) {

    if (!window) return;

    var component = this;
    var pholder = component.placeholder;
    var pholder_found = false;
    var btn = this.element.selectAll(".vzb-buttonlist-btn[data-btn='" + id + "']");
    var fs = !this.model.ui.fullscreen;
    var body_overflow = fs ? "hidden" : this._prev_body_overflow;

    while (!(pholder_found = utils.hasClass(pholder, 'vzb-placeholder'))) {
      component = component.parent;
      pholder = component.placeholder;
    }

    //TODO: figure out a way to avoid fullscreen resize delay in firefox
    if (fs) {
      this.resizeInExitHandler = false;
      launchIntoFullscreen(pholder);
      subscribeFullscreenChangeEvent.call(this, this.toggleFullScreen.bind(this, id, true));
    } else {
      this.resizeInExitHandler = emulateClick ? false : true;
      exitFullscreen.call(this);
    }
    utils.classed(pholder, class_vzb_fullscreen, fs);
    if (typeof container != 'undefined') {
      utils.classed(container, class_container_fullscreen, fs);
    }

    this.model.ui.fullscreen = fs;
    var translator = this.model.locale.getTFunction();
    btn.classed(class_active_locked, fs);

    btn.select(".vzb-buttonlist-btn-icon").html(iconset[fs ? "unexpand" : "expand"]);

    btn.select(".vzb-buttonlist-btn-title>span").text(translator("buttons/" + (fs ? "unexpand" : "expand"))).attr("data-vzb-translate", "buttons/" + (fs ? "unexpand" : "expand"));

    //restore body overflow
    document.body.style.overflow = body_overflow;

    if (!this.resizeInExitHandler) this.root.ui.resizeHandler();

    //force window resize event
    // utils.defer(function() {
    //   event = window.document.createEvent("HTMLEvents");
    //   event.initEvent("resize", true, true);
    //   event.eventName = "resize";
    //   window.dispatchEvent(event);
    // });
  }

});

function isFullscreen() {
  if (!window) return false;
  if (window.document.webkitIsFullScreen !== undefined) return window.document.webkitIsFullScreen;
  if (window.document.mozFullScreen !== undefined) return window.document.mozFullScreen;
  if (window.document.msFullscreenElement !== undefined) return window.document.msFullscreenElement;

  return false;
}

function exitHandler(emulateClickFunc) {
  if (!isFullscreen()) {
    removeFullscreenChangeEvent.call(this);
    if (!this.resizeInExitHandler) {
      emulateClickFunc();
    } else {
      this.root.ui.resizeHandler();
    }
  }
}

function subscribeFullscreenChangeEvent(exitFunc) {
  if (!window) return;
  var doc = window.document;

  this.exitFullscreenHandler = exitHandler.bind(this, exitFunc);
  doc.addEventListener('webkitfullscreenchange', this.exitFullscreenHandler, false);
  doc.addEventListener('mozfullscreenchange', this.exitFullscreenHandler, false);
  doc.addEventListener('fullscreenchange', this.exitFullscreenHandler, false);
  doc.addEventListener('MSFullscreenChange', this.exitFullscreenHandler, false);
}

function removeFullscreenChangeEvent() {
  var doc = window.document;

  doc.removeEventListener('webkitfullscreenchange', this.exitFullscreenHandler);
  doc.removeEventListener('mozfullscreenchange', this.exitFullscreenHandler);
  doc.removeEventListener('fullscreenchange', this.exitFullscreenHandler);
  doc.removeEventListener('MSFullscreenChange', this.exitFullscreenHandler);
}

function launchIntoFullscreen(elem) {
  if (elem.requestFullscreen) {
    elem.requestFullscreen();
  } else if (elem.msRequestFullscreen) {
    elem.msRequestFullscreen();
  } else if (elem.mozRequestFullScreen) {
    elem.mozRequestFullScreen();
  } else if (elem.webkitRequestFullscreen) {
    if (!(navigator.vendor && navigator.vendor.indexOf('Apple') > -1 && navigator.userAgent && !navigator.userAgent.match('CriOS'))) {
      elem.webkitRequestFullscreen();
    }
  }
}

function exitFullscreen() {
  if (document.exitFullscreen) {
    document.exitFullscreen();
  } else if (document.msExitFullscreen) {
    document.msExitFullscreen();
  } else if (document.mozCancelFullScreen) {
    document.mozCancelFullScreen();
  } else if (document.webkitExitFullscreen) {
    document.webkitExitFullscreen();
  } else {
    removeFullscreenChangeEvent.call(this);
    this.resizeInExitHandler = false;
  }
}

exports.default = ButtonList;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _requireAll = __webpack_require__(70);

var _requireAll2 = _interopRequireDefault(_requireAll);

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _iconset = __webpack_require__(10);

var iconset = _interopRequireWildcard(_iconset);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

//dialogs
var dialogs = (0, _requireAll2.default)(__webpack_require__(456), 1);

/*!
 * VIZABI DIALOGS
 * Reusable dialogs component
 */

//default existing dialogs
var class_active = "vzb-active";
var class_expand_dialog = "vzb-dialog-side";

var Dialogs = _component2.default.extend({

  /**
   * Initializes the dialogs
   * @param config component configuration
   * @param context component context (parent)
   */
  init: function init(config, context) {

    //set properties
    var _this = this;
    this.name = 'gapminder-dialogs';
    this._curr_dialog_index = 20;

    this.model_expects = [{
      name: "state",
      type: "model"
    }, {
      name: "ui",
      type: "ui"
    }, {
      name: "locale",
      type: "locale"
    }];

    this._available_dialogs = {
      'timedisplay': {
        dialog: dialogs.timedisplay
      },
      'find': {
        dialog: dialogs.find
      },
      'show': {
        dialog: dialogs.show
      },
      'moreoptions': {
        dialog: dialogs.moreoptions
      },
      'colors': {
        dialog: dialogs.colors
      },
      'size': {
        dialog: dialogs.size
      },
      'side': {
        dialog: dialogs.side
      },
      'label': {
        dialog: dialogs.label
      },
      'zoom': {
        dialog: dialogs.zoom
      },
      'axes': {
        dialog: dialogs.axes
      },
      'axesmc': {
        dialog: dialogs.axesmc
      },
      'stack': {
        dialog: dialogs.stack
      },
      'speed': {
        dialog: dialogs.speed
      },
      'opacity': {
        dialog: dialogs.opacity
      },
      'presentation': {
        dialog: dialogs.presentation
      },
      'about': {
        dialog: dialogs.about
      }
    };

    this._super(config, context);
  },

  domReady: function domReady() {
    var dialog_popup = (this.model.ui.dialogs || {}).popup || [];
    var dialog_sidebar = (this.model.ui.dialogs || {}).sidebar || [];

    this.rootEl = this.root.element instanceof Array ? this.root.element : d3.select(this.root.element);

    // if dialog_sidebar has been passed in with boolean param or array must check and covert to array
    if (dialog_sidebar === true) {
      dialog_sidebar = dialog_popup;
      (this.model.ui.dialogs || {}).sidebar = dialog_sidebar;
    }
    if (dialog_sidebar.length !== 0) {
      this.rootEl.classed("vzb-dialog-expand-true", true);
    }
    this.dialog_popup = dialog_popup;
    this.dialog_sidebar = dialog_sidebar;
  },

  readyOnce: function readyOnce() {
    var _this = this;

    this.element = d3.select(this.placeholder);
    this.element.selectAll("div").remove();

    this._addDialogs(this.dialog_popup, this.dialog_sidebar);

    this.resize();

    if (this.dialog_popup.length !== 0) {
      this.root.findChildByName("gapminder-buttonlist").on("click", function (evt, button) {
        if (!_this._available_dialogs[button.id]) return;

        if (button.active) {
          _this.openDialog(button.id);
        } else {
          _this.closeDialog(button.id);
        }
      });

      var popupDialogs = this.element.selectAll(".vzb-top-dialog").filter(function (d) {
        return _this.dialog_popup.indexOf(d.id) > -1;
      });

      var close_buttons = popupDialogs.select(".vzb-top-dialog>.vzb-dialog-modal>.vzb-dialog-buttons>[data-click='closeDialog']");
      close_buttons.on('click', function (d, i) {
        _this.closeDialog(d.id);
      });

      var pinDialog = popupDialogs.select(".vzb-top-dialog>.vzb-dialog-modal>[data-click='pinDialog']");
      pinDialog.on('click', function (d, i) {
        _this.pinDialog(d.id);
      });

      this.rootEl.node().addEventListener('click', function () {
        _this.closeAllDialogs();
      });

      this.rootEl.on("mousedown", function (e) {
        if (!this._active_comp) return; //don't do anything if nothing is open

        var target = d3.event.target;
        var closeDialog = true;
        while (target) {
          if (target.classList.contains("vzb-dialog-modal")) {
            closeDialog = false;
            break;
          }
          target = target.parentElement;
        }
        if (closeDialog) {
          _this.closeAllDialogs();
        }
      });
    }

    this.element.on('click', function () {
      d3.event.stopPropagation();
    });
  },

  resize: function resize() {
    var _this = this;
    var profile = this.getLayoutProfile();

    this.element.selectAll(".vzb-top-dialog").each(function (d) {
      var dialogEl = d3.select(this);
      var cls = dialogEl.attr('class').replace(' vzb-popup', '').replace(' vzb-sidebar', '');

      if (profile === 'large' && _this.dialog_sidebar.indexOf(d.id) > -1) {
        cls += ' vzb-sidebar';
      } else if (_this.dialog_popup.indexOf(d.id) > -1) {
        cls += ' vzb-popup';
      }

      dialogEl.attr('class', cls);
    });
  },

  /*
   * adds dialogs configuration to the components and template_data
   * @param {Array} dialog_list list of dialogs to be added
   */
  _addDialogs: function _addDialogs(dialog_popup, dialog_sidebar) {

    var profile = this.getLayoutProfile();
    var dialog_list = [];

    dialog_list = dialog_popup ? dialog_list.concat(dialog_popup) : dialog_list;
    dialog_list = dialog_sidebar ? dialog_list.concat(dialog_sidebar) : dialog_list;

    dialog_list = utils.unique(dialog_list);

    this._components_config = [];
    var details_dlgs = [];
    if (!dialog_list.length) return;
    //add a component for each dialog
    for (var i = 0; i < dialog_list.length; i++) {

      var dlg = dialog_list[i];
      var dlg_config = this._available_dialogs[dlg];

      //if it's a dialog, add component
      if (dlg_config && dlg_config.dialog) {
        var comps = this._components_config;

        //add corresponding component
        comps.push({
          component: dlg_config.dialog,
          placeholder: '.vzb-dialogs-dialog[data-dlg="' + dlg + '"]',
          model: ["state", "ui", "locale"]
        });

        dlg_config.component = comps.length - 1;
      }

      dlg_config.id = dlg;
      details_dlgs.push(dlg_config);
    }
    ;

    this.element.selectAll('div').data(details_dlgs).enter().append("div").attr('data-dlg', function (d) {
      return d.id;
    }).attr('class', 'vzb-top-dialog vzb-dialogs-dialog vzb-dialog-shadow');

    this.loadSubComponents();

    var _this = this;
    //render each subcomponent
    utils.forEach(this.components, function (subcomp) {
      subcomp.render();
      _this.on('resize', function () {
        subcomp.trigger('resize');
      });
      subcomp.on('dragstart', function () {
        _this.bringForward(subcomp.name);
      });
      subcomp.on('close', function () {
        this.placeholderEl.each(function (d) {
          var evt = {};
          evt.id = d.id;
          _this.trigger('close', evt);
        });
      });
    });
  },

  bringForward: function bringForward(id) {
    var dialog = this.element.select(".vzb-popup.vzb-dialogs-dialog[data-dlg='" + id + "']");
    dialog.style('z-index', this._curr_dialog_index);
    this._curr_dialog_index += 10;
  },

  //TODO: make opening/closing a dialog via update and model
  /*
   * Activate a dialog
   * @param {String} id dialog id
   */
  openDialog: function openDialog(id) {
    //close pinned dialogs for small profile
    var forceClose = this.getLayoutProfile() === 'small' ? true : false;
    this.closeAllDialogs(forceClose);

    var dialog = this.element.selectAll(".vzb-popup.vzb-dialogs-dialog[data-dlg='" + id + "']");

    this._active_comp = this.components[this._available_dialogs[id].component];

    this._active_comp.beforeOpen();
    //add classes
    dialog.classed(class_active, true);

    this.bringForward(id);

    //call component function
    this._active_comp.open();
  },

  pinDialog: function pinDialog(id) {
    var dialog = this.element.select(".vzb-popup.vzb-dialogs-dialog[data-dlg='" + id + "']");

    if (this._available_dialogs[id].ispin) {
      dialog.classed('pinned', false);
      this._available_dialogs[id].ispin = false;
    } else {
      dialog.classed('pinned', true);
      this._available_dialogs[id].ispin = true;
    }
  },

  /*
   * Closes a dialog
   * @param {String} id dialog id
   */
  closeDialog: function closeDialog(id) {
    var dialog = this.element.selectAll(".vzb-popup.vzb-dialogs-dialog[data-dlg='" + id + "']");

    this._active_comp = this.components[this._available_dialogs[id].component];

    if (this._active_comp && !this._active_comp.isOpen) return;

    if (this._available_dialogs[id].ispin) this.pinDialog(id);

    if (this._active_comp) {
      this._active_comp.beforeClose();
    }
    //remove classes
    dialog.classed(class_active, false);

    //call component close function
    if (this._active_comp) {
      this._active_comp.close();
    }
    this._active_comp = false;
  },

  /*
   * Close all dialogs
   */
  closeAllDialogs: function closeAllDialogs(forceclose) {
    var _this = this;
    //remove classes
    var dialogClass = forceclose ? ".vzb-popup.vzb-dialogs-dialog.vzb-active" : ".vzb-popup.vzb-dialogs-dialog.vzb-active:not(.pinned)";
    var all_dialogs = this.element.selectAll(dialogClass);
    all_dialogs.each(function (d) {
      _this.closeDialog(d.id);
    });
  }

});

exports.default = Dialogs;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

var precision = 1;

//constants
var class_playing = "vzb-playing";
var class_loading = "vzb-ts-loading";
var class_hide_play = "vzb-ts-hide-play-button";
var class_dragging = "vzb-ts-dragging";
var class_axis_aligned = "vzb-ts-axis-aligned";
var class_show_value = "vzb-ts-show-value";
var class_show_value_when_drag_play = "vzb-ts-show-value-when-drag-play";

//margins for slider
var profiles = {
  small: {
    margin: {
      top: 7,
      right: 15,
      bottom: 10,
      left: 15
    },
    radius: 8,
    label_spacing: 10
  },
  medium: {
    margin: {
      top: 16,
      right: 15,
      bottom: 10,
      left: 15
    },
    radius: 9,
    label_spacing: 12
  },
  large: {
    margin: {
      top: 14,
      right: 15,
      bottom: 10,
      left: 15
    },
    radius: 11,
    label_spacing: 14
  }
};

var presentationProfileChanges = {
  "medium": {
    margin: {
      top: 9
    }
  },
  "large": {
    margin: {}
  }
};

var TimeSlider = _component2.default.extend({
  /**
   * Initializes the timeslider.
   * Executed once before any template is rendered.
   * @param model The model passed to the component
   * @param context The component's parent
   */
  init: function init(model, context) {

    this.name = "gapminder-timeslider";
    this.template = this.template || __webpack_require__(441);
    this.prevPosition = null;
    //define expected models/hooks for this component
    this.model_expects = [{
      name: "time",
      type: "time"
    }, {
      name: "entities",
      type: "entities"
    }, {
      name: "marker",
      type: "model"
    }, {
      name: "ui",
      type: "ui"
    }];

    var _this = this;
    //binds methods to this model
    this.model_binds = {
      'change:time': function changeTime(evt, path) {
        if (_this.slide) {
          if (['time.start', 'time.end'].indexOf(path) !== -1) {
            if (!_this.xScale) return;
            _this.changeLimits();
          }
          _this._optionClasses();
          //only set handle position if change is external
          if (!_this.model.time.dragging) _this._setHandle(_this.model.time.playing);
        }
      },
      'change:time.start': function changeTimeStart(evt, path) {
        if (_this.slide) {
          //only set handle position if change is external
          if (!_this.model.time.dragging) _this._setHandle(_this.model.time.playing);
        }
      },
      'change:time.end': function changeTimeEnd(evt, path) {
        if (_this.slide) {
          //only set handle position if change is external
          if (!_this.model.time.dragging) _this._setHandle(_this.model.time.playing);
        }
      },
      'change:time.startSelected': function changeTimeStartSelected(evt, path) {
        if (_this.slide) {
          _this.updateSelectedStartLimiter();
        }
      },
      'change:time.endSelected': function changeTimeEndSelected(evt, path) {
        if (_this.slide) {
          _this.updateSelectedEndLimiter();
        }
      },
      'change:marker.select': function changeMarkerSelect(evt, path) {
        _this.setSelectedLimits();
      }
    };

    // Same constructor as the superclass
    this._super(model, context);

    // Sort of defaults. Actually should be in ui default or bubblechart. 
    // By not having "this.model.ui =" we prevent it from going to url (not defined in defaults)
    // Should be in defaults when we make components config part of external config (& every component gets own config)
    this.ui = utils.extend({
      show_limits: false,
      show_value: false,
      show_value_when_drag_play: true,
      show_button: true,
      class_axis_aligned: false
    }, model.ui, this.ui);

    //defaults
    this.width = 0;
    this.height = 0;
    this.availableTimeFrames = [];
    this.completedTimeFrames = [];
    this.getValueWidth = utils.memoize(this.getValueWidth);
    this._setTime = utils.throttle(this._setTime, 50);
  },

  //template is ready
  readyOnce: function readyOnce() {

    var _this = this;

    //DOM to d3
    //TODO: remove this ugly hack
    this.element = utils.isArray(this.element) ? this.element : d3.select(this.element);

    //html elements
    this.slider_outer = this.element.select(".vzb-ts-slider");
    this.slider = this.slider_outer.select("g");
    this.axis = this.element.select(".vzb-ts-slider-axis");
    this.select = this.element.select(".vzb-ts-slider-select");
    this.progressBar = this.element.select(".vzb-ts-slider-progress");
    this.slide = this.element.select(".vzb-ts-slider-slide");
    this.handle = this.slide.select(".vzb-ts-slider-handle");
    this.valueText = this.slide.select('.vzb-ts-slider-value');
    //Scale
    this.xScale = d3.time.scale.utc().clamp(true);

    //Axis
    this.xAxis = d3.svg.axis().orient("bottom").tickSize(0);
    //Value
    this.valueText.attr("text-anchor", "middle").attr("dy", "-0.7em");

    var brushed = _this._getBrushed(),
        brushedEnd = _this._getBrushedEnd();

    //Brush for dragging
    this.brush = d3.svg.brush().x(this.xScale).extent([0, 0]).on("brush", function () {
      brushed.call(this);
    }).on("brushend", function () {
      brushedEnd.call(this);
    });

    //Slide
    this.slide.call(this.brush);

    this.slider_outer.on("mousewheel", function () {
      //do nothing and dont pass the event on if we are currently dragging the slider
      if (_this.model.time.dragging) {
        d3.event.stopPropagation();
        d3.event.preventDefault();
        d3.event.returnValue = false;
        return false;
      }
    });

    this.slide.selectAll(".extent,.resize").remove();

    this._setSelectedLimitsId = 0; //counter for setSelectedLimits

    if (this.model.time.startSelected > this.model.time.start) {
      _this.updateSelectedStartLimiter();
    }

    if (this.model.time.endSelected < this.model.time.end) {
      _this.updateSelectedEndLimiter();
    }

    // special for linechart: resize timeslider to match time x-axis length
    this.parent.on('myEvent', function (evt, arg) {
      var layoutProfile = _this.getLayoutProfile();

      if (arg.profile && arg.profile.margin) {
        profiles[layoutProfile].margin = arg.profile.margin;
      }

      // set the right margin that depends on longest label width
      _this.element.select(".vzb-ts-slider-wrapper").style("right", arg.mRight - profiles[layoutProfile].margin.right + "px");

      _this.updateSize([0, arg.rangeMax]);
    });

    this.on("resize", function () {
      _this.updateSize();
    });
  },

  //template and model are ready
  ready: function ready() {
    if (this.model.time.splash) return;

    this.element.classed(class_loading, false);

    var play = this.element.select(".vzb-ts-btn-play");
    var pause = this.element.select(".vzb-ts-btn-pause");
    var _this = this;
    var time = this.model.time;

    play.on('click', function () {

      _this.model.time.play();
    });

    pause.on('click', function () {
      _this.model.time.pause("soft");
    });

    this.changeLimits();
    this.changeTime();
    this.updateSize();

    _this._updateProgressBar();
    _this.model.marker.listenFramesQueue(null, function (time) {
      _this._updateProgressBar(time);
    });
    _this.setSelectedLimits(true);
  },

  changeLimits: function changeLimits() {
    var minValue = this.model.time.start;
    var maxValue = this.model.time.end;
    //scale
    this.xScale.domain([minValue, maxValue]);
    //axis
    this.xAxis.tickValues([minValue, maxValue]).tickFormat(this.model.time.getFormatter());
  },

  changeTime: function changeTime() {
    //time slider should always receive a time model
    var time = this.model.time.value;
    //special classes
    this._optionClasses();
  },

  /**
   * Executes everytime the container or vizabi is resized
   * Ideally,it contains only operations related to size
   */
  updateSize: function updateSize(range) {
    if (this.model.time.splash) return;

    this.model.time.pause();

    this.profile = this.getActiveProfile(profiles, presentationProfileChanges);

    var slider_w = parseInt(this.slider_outer.style("width"), 10) || 0;
    var slider_h = parseInt(this.slider_outer.style("height"), 10) || 0;

    if (!slider_h || !slider_w) return utils.warn("time slider resize() aborted because element is too small or has display:none");

    this.width = slider_w - this.profile.margin.left - this.profile.margin.right;
    this.height = slider_h - this.profile.margin.bottom - this.profile.margin.top;
    var _this = this;

    //translate according to margins
    this.slider.attr("transform", "translate(" + this.profile.margin.left + "," + this.profile.margin.top + ")");

    this.xScale.range(range || [0, this.width]);

    //adjust axis with scale
    this.xAxis = this.xAxis.scale(this.xScale).tickPadding(this.profile.label_spacing);

    this.axis.attr("transform", "translate(0," + this.height / 2 + ")").call(this.xAxis);

    this.select.attr("transform", "translate(0," + this.height / 2 + ")");
    this.progressBar.attr("transform", "translate(0," + this.height / 2 + ")");

    this.slide.select(".background").attr("height", this.height);

    //size of handle
    this.handle.attr("transform", "translate(0," + this.height / 2 + ")").attr("r", this.profile.radius);

    this.sliderWidth = _this.slider.node().getBoundingClientRect().width;

    this.resizeSelectedLimiters();
    this._resizeProgressBar();
    this._setHandle();
  },

  setSelectedLimits: function setSelectedLimits(force) {
    var _this = this;
    this._setSelectedLimitsId++;
    var _setSelectedLimitsId = this._setSelectedLimitsId;

    var select = _this.model.marker.select;
    if (select.length == 0) {
      _this.model.time.set({
        startSelected: new Date(_this.model.time.start),
        endSelected: new Date(_this.model.time.end)
      }, null, false /*make change non-persistent for URL and history*/);
      return;
    }
    var KEY = _this.model.entities.getDimension();
    var proms = [];
    utils.forEach(select, function (entity) {
      proms.push(_this.model.marker.getEntityLimits(entity[KEY]));
    });
    Promise.all(proms).then(function (limits) {
      if (_setSelectedLimitsId != _this._setSelectedLimitsId) return;
      var first = limits.shift();
      var min = first.min;
      var max = first.max;
      utils.forEach(limits, function (limit) {
        if (min - limit.min > 0) min = limit.min;
        if (max - limit.max < 0) max = limit.max;
      });
      _this.model.time.set({
        startSelected: d3.max([min, new Date(_this.model.time.start)]),
        endSelected: d3.min([max, new Date(_this.model.time.end)])
      }, force, false /*make change non-persistent for URL and history*/);
    });
  },

  updateSelectedStartLimiter: function updateSelectedStartLimiter() {
    var _this = this;
    this.select.select('#clip-start-' + _this._id).remove();
    this.select.select(".selected-start").remove();
    if (this.model.time.startSelected && this.model.time.startSelected > this.model.time.start) {
      this.select.append("clipPath").attr("id", "clip-start-" + _this._id).append('rect');
      this.select.append('path').attr("clip-path", "url(" + location.pathname + "#clip-start-" + _this._id + ")").classed('selected-start', true);
      this.resizeSelectedLimiters();
    }
  },

  updateSelectedEndLimiter: function updateSelectedEndLimiter() {
    var _this = this;
    this.select.select('#clip-end-' + _this._id).remove();
    this.select.select(".selected-end").remove();
    if (this.model.time.endSelected && this.model.time.endSelected < this.model.time.end) {
      this.select.append("clipPath").attr("id", "clip-end-" + _this._id).append('rect');
      this.select.append('path').attr("clip-path", "url(" + location.pathname + "#clip-end-" + _this._id + ")").classed('selected-end', true);
      this.resizeSelectedLimiters();
    }
  },

  resizeSelectedLimiters: function resizeSelectedLimiters() {
    var _this = this;
    this.select.select('.selected-start').attr('d', "M0,0H" + this.xScale(this.model.time.startSelected));
    this.select.select("#clip-start-" + _this._id).select('rect').attr("x", -this.height / 2).attr("y", -this.height / 2).attr("height", this.height).attr("width", this.xScale(this.model.time.startSelected) + this.height / 2);
    this.select.select('.selected-end').attr('d', "M" + this.xScale(this.model.time.endSelected) + ",0H" + this.xScale(this.model.time.end));
    this.select.select("#clip-end-" + _this._id).select('rect').attr("x", this.xScale(this.model.time.endSelected)).attr("y", -this.height / 2).attr("height", this.height).attr("width", this.xScale(this.model.time.end) - this.xScale(this.model.time.endSelected) + this.height / 2);
  },

  _resizeProgressBar: function _resizeProgressBar() {
    var _this = this;
    this.progressBar.selectAll('path').each(function (d) {
      d3.select(this).attr('d', "M" + _this.xScale(d[0]) + ",0H" + _this.xScale(d[1]));
    });
  },

  _updateProgressBar: function _updateProgressBar(time) {
    var _this = this;
    if (time) {
      if (_this.completedTimeFrames.indexOf(time) != -1) return;
      _this.completedTimeFrames.push(time);
      var next = _this.model.time.incrementTime(time);
      var prev = _this.model.time.decrementTime(time);
      if (next > _this.model.time.end) {
        if (time - _this.model.time.end == 0) {
          next = time;
          time = prev;
        } else {
          return;
        }
      }
      if (_this.availableTimeFrames.length == 0 || _this.availableTimeFrames[_this.availableTimeFrames.length - 1][1] < time) {
        _this.availableTimeFrames.push([time, next]);
      } else if (next < _this.availableTimeFrames[0][0]) {
        _this.availableTimeFrames.unshift([time, next]);
      } else {
        for (var i = 0; i < _this.availableTimeFrames.length; i++) {
          if (time - _this.availableTimeFrames[i][1] == 0) {
            if (i + 1 < _this.availableTimeFrames.length && next - _this.availableTimeFrames[i + 1][0] == 0) {
              _this.availableTimeFrames[i][1] = _this.availableTimeFrames[i + 1][1];
              _this.availableTimeFrames.splice(i + 1, 1);
            } else {
              _this.availableTimeFrames[i][1] = next;
            }
            break;
          }
          if (next - _this.availableTimeFrames[i][0] == 0) {
            _this.availableTimeFrames[i][0] = time;
            break;
          }
          if (time - _this.availableTimeFrames[i][1] > 0 && next - _this.availableTimeFrames[i + 1][0] < 0) {
            _this.availableTimeFrames.splice(i + 1, 0, [time, next]);
            break;
          }
        }
      }
    } else {
      _this.availableTimeFrames = [];
      _this.completedTimeFrames = [];
    }

    var progress = this.progressBar.selectAll('path').data(_this.availableTimeFrames);
    progress.exit().remove();
    progress.enter().append('path').attr('class', 'domain');
    progress.each(function (d) {
      var element = d3.select(this);
      element.attr('d', "M" + _this.xScale(d[0]) + ",0H" + _this.xScale(d[1])).classed("rounded", _this.availableTimeFrames.length == 1);
    });
  },

  /**
   * Returns width of slider text value.
   * Parameters in this function needed for memoize function, so they are not redundant.
   */
  getValueWidth: function getValueWidth(layout, value) {
    return this.valueText.node().getBoundingClientRect().width;
  },

  /**
   * Gets brushed function to be executed when dragging
   * @returns {Function} brushed function
   */
  _getBrushed: function _getBrushed() {
    var _this = this;
    return function () {

      if (_this.model.time.playing) _this.model.time.pause();

      _this._optionClasses();
      _this.element.classed(class_dragging, true);

      var value = _this.brush.extent()[0];

      //set brushed properties

      if (d3.event.sourceEvent) {
        // Prevent window scrolling on cursor drag in Chrome/Chromium.
        d3.event.sourceEvent.preventDefault();

        _this.model.time.dragStart();
        var posX = utils.roundStep(Math.round(d3.mouse(this)[0]), precision);
        value = _this.xScale.invert(posX);
        var maxPosX = _this.width;

        if (posX > maxPosX) {
          posX = maxPosX;
        } else if (posX < 0) {
          posX = 0;
        }

        //set handle position
        _this.handle.attr("cx", posX);
        _this.valueText.attr("transform", "translate(" + posX + "," + _this.height / 2 + ")");
        _this.valueText.text(_this.model.time.formatDate(value, 'ui'));
      }

      //set time according to dragged position
      if (value - _this.model.time.value !== 0) {
        _this._setTime(value);
      }
    };
  },

  /**
   * Gets brushedEnd function to be executed when dragging ends
   * @returns {Function} brushedEnd function
   */
  _getBrushedEnd: function _getBrushedEnd() {
    var _this = this;
    return function () {
      _this._setTime.recallLast();
      _this.element.classed(class_dragging, false);
      _this.model.time.dragStop();
      _this.model.time.snap();
    };
  },

  /**
   * Sets the handle to the correct position
   * @param {Boolean} transition whether to use transition or not
   */
  _setHandle: function _setHandle(transition) {
    var _this = this;
    var value = this.model.time.value;
    this.slide.call(this.brush.extent([value, value]));

    this.element.classed("vzb-ts-disabled", this.model.time.end <= this.model.time.start);
    //    this.valueText.text(this.model.time.formatDate(value));

    //    var old_pos = this.handle.attr("cx");
    var new_pos = this.xScale(value);
    if (_this.prevPosition == null) _this.prevPosition = new_pos;
    var delayAnimations = new_pos > _this.prevPosition ? this.model.time.delayAnimations : 0;
    if (transition) {
      this.handle.attr("cx", _this.prevPosition).transition().duration(delayAnimations).ease("linear").attr("cx", new_pos);

      this.valueText.attr("transform", "translate(" + _this.prevPosition + "," + this.height / 2 + ")").transition('text').delay(delayAnimations).text(this.model.time.formatDate(value, 'ui'));
      this.valueText.transition().duration(delayAnimations).ease("linear").attr("transform", "translate(" + new_pos + "," + this.height / 2 + ")");
    } else {
      this.handle
      //cancel active transition
      .interrupt().attr("cx", new_pos);

      this.valueText
      //cancel active transition
      .interrupt().interrupt('text').transition('text');
      this.valueText.attr("transform", "translate(" + new_pos + "," + this.height / 2 + ")").text(this.model.time.formatDate(value, 'ui'));
    }
    _this.prevPosition = new_pos;
  },

  /**
   * Sets the current time model to time
   * @param {number} time The time
   */
  _setTime: function _setTime(time) {
    //update state
    var _this = this;
    //  frameRate = 50;

    //avoid updating more than once in "frameRate"
    //var now = new Date();
    //if (this._updTime != null && now - this._updTime < frameRate) return;
    //this._updTime = now;
    var persistent = !this.model.time.dragging && !this.model.time.playing;
    _this.model.time.getModelObject('value').set(time, false, persistent); // non persistent
  },

  /**
   * Applies some classes to the element according to options
   */
  _optionClasses: function _optionClasses() {
    //show/hide classes

    var show_limits = this.ui.show_limits;
    var show_value = this.ui.show_value;
    var show_value_when_drag_play = this.ui.show_value_when_drag_play;
    var axis_aligned = this.ui.axis_aligned;
    var show_play = this.ui.show_button && this.model.time.playable;

    if (!show_limits) {
      this.xAxis.tickValues([]).ticks(0);
    }

    this.element.classed(class_hide_play, !show_play);
    this.element.classed(class_playing, this.model.time.playing);
    this.element.classed(class_show_value, show_value);
    this.element.classed(class_show_value_when_drag_play, show_value_when_drag_play);
    this.element.classed(class_axis_aligned, axis_aligned);
  }
});

exports.default = TimeSlider;

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

var pIE            = __webpack_require__(69)
  , createDesc     = __webpack_require__(42)
  , toIObject      = __webpack_require__(20)
  , toPrimitive    = __webpack_require__(33)
  , has            = __webpack_require__(15)
  , IE8_DOM_DEFINE = __webpack_require__(159)
  , gOPD           = Object.getOwnPropertyDescriptor;

exports.f = __webpack_require__(8) ? gOPD : function getOwnPropertyDescriptor(O, P){
  O = toIObject(O);
  P = toPrimitive(P, true);
  if(IE8_DOM_DEFINE)try {
    return gOPD(O, P);
  } catch(e){ /* empty */ }
  if(has(O, P))return createDesc(!pIE.f.call(O, P), O[P]);
};

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

// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)
var has         = __webpack_require__(15)
  , toObject    = __webpack_require__(13)
  , IE_PROTO    = __webpack_require__(104)('IE_PROTO')
  , ObjectProto = Object.prototype;

module.exports = Object.getPrototypeOf || function(O){
  O = toObject(O);
  if(has(O, IE_PROTO))return O[IE_PROTO];
  if(typeof O.constructor == 'function' && O instanceof O.constructor){
    return O.constructor.prototype;
  } return O instanceof Object ? ObjectProto : null;
};

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _class = __webpack_require__(21);

var _class2 = _interopRequireDefault(_class);

var _iconset = __webpack_require__(10);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*!
 * VIZABI INDICATOR PICKER
 * Reusable indicator picker component
 */

var INDICATOR = "which";
var SCALETYPE = "scaleType";
var MODELTYPE_COLOR = "color";
var MENU_HORIZONTAL = 1;
var MENU_VERTICAL = 2;

//css custom classes
var css = {
  wrapper: 'vzb-treemenu-wrap',
  wrapper_outer: 'vzb-treemenu-wrap-outer',
  background: 'vzb-treemenu-background',
  close: 'vzb-treemenu-close',
  search: 'vzb-treemenu-search',
  list: 'vzb-treemenu-list',
  list_outer: 'vzb-treemenu-list-outer',
  list_item: 'vzb-treemenu-list-item',
  list_item_leaf: 'vzb-treemenu-list-item-leaf',
  leaf: 'vzb-treemenu-leaf',
  leaf_content: 'vzb-treemenu-leaf-content',
  leaf_content_item: 'vzb-treemenu-leaf-content-item',
  leaf_content_item_title: 'vzb-treemenu-leaf-content-item-title',
  leaf_content_item_descr: 'vzb-treemenu-leaf-content-item-descr',
  hasChild: 'vzb-treemenu-list-item-children',
  list_item_label: 'vzb-treemenu-list-item-label',
  list_top_level: 'vzb-treemenu-list-top',
  search_wrap: 'vzb-treemenu-search-wrap',
  isSpecial: 'vzb-treemenu-list-item-special',
  hidden: 'vzb-hidden',
  title: 'vzb-treemenu-title',
  scaletypes: 'vzb-treemenu-scaletypes',
  scaletypesDisabled: 'vzb-treemenu-scaletypes-disabled',
  scaletypesActive: 'vzb-treemenu-scaletypes-active',
  alignYt: 'vzb-align-y-top',
  alignYb: 'vzb-align-y-bottom',
  alignXl: 'vzb-align-x-left',
  alignXr: 'vzb-align-x-right',
  alignXc: 'vzb-align-x-center',
  menuHorizontal: 'vzb-treemenu-horizontal',
  menuVertical: 'vzb-treemenu-vertical',
  absPosVert: 'vzb-treemenu-abs-pos-vert',
  absPosHoriz: 'vzb-treemenu-abs-pos-horiz',
  menuOpenLeftSide: 'vzb-treemenu-open-left-side',
  noTransition: 'notransition'
};

//options and globals
var OPTIONS = {
  MOUSE_LOCS: [], //contains last locations of mouse
  MOUSE_LOCS_TRACKED: 3, //max number of locations of mouse
  DELAY: 200, //amazons multilevel delay
  TOLERANCE: 150, //this parameter is used for controlling the angle of multilevel dropdown
  LAST_DELAY_LOC: null, //this is cached location of mouse, when was a delay
  TIMEOUT: null, //timeout id
  SEARCH_PROPERTY: 'id', //property in input data we we'll search by
  SUBMENUS: 'children', //property for submenus (used by search)
  SEARCH_MIN_STR: 1, //minimal length of query string to start searching
  RESIZE_TIMEOUT: null, //container resize timeout
  MOBILE_BREAKPOINT: 400, //mobile breakpoint
  CURRENT_PATH: [], //current active path
  MIN_COL_WIDTH: 60, //minimal column size
  MENU_DIRECTION: MENU_HORIZONTAL,
  MAX_MENU_WIDTH: 320,
  MENU_OPEN_LEFTSIDE: false
};

var Menu = _class2.default.extend({
  init: function init(parent, menu, options) {
    var _this = this;
    this.parent = parent;
    this.entity = menu;
    this.OPTIONS = options;
    this.width = this.OPTIONS.MIN_COL_WIDTH;
    this.direction = this.OPTIONS.MENU_DIRECTION;
    this._setDirectionClass();
    this.menuItems = [];
    var menuItemsHolder;

    if (this.entity.empty()) return this;

    this.entity.each(function () {
      menuItemsHolder = d3.selectAll(this.childNodes).filter(function () {
        return d3.select(this).classed(css.list);
      });
    });
    if (menuItemsHolder.empty()) menuItemsHolder = this.entity;
    menu.selectAll('.' + css.list_item).filter(function () {
      return this.parentNode == menuItemsHolder.node();
    }).each(function () {
      _this.addSubmenu(d3.select(this));
    });
    return this;
  },
  setWidth: function setWidth(width, recursive, immediate) {
    if (this.width != width && this.entity.node()) {
      this.width = width;
      if ((this.entity.classed(css.list_top_level) || this.entity.classed('active')) && this.direction == MENU_HORIZONTAL) {
        if (!immediate) {
          this.entity.transition().delay(0).duration(100).style('width', this.width + "px");
        } else {
          this.entity.style('width', this.width + "px");
        }
      }
      if (this.entity.classed(css.list_top_level)) {
        this.entity.selectAll('.' + css.leaf).style('width', this.width - 1 + "px");
      }
      if (recursive) {
        for (var i = 0; i < this.menuItems.length; i++) {
          this.menuItems[i].setWidth(this.width, recursive, immediate);
        }
      }
      return this;
    }
  },
  /**
   * configure menu type (horizontal or vertical)
   * @param direction MENU_HORIZONTAL or MENU_VERTICAL
   * @param recursive change direction over menu sublevels
   * @returns {Menu}
   */
  setDirection: function setDirection(direction, recursive) {
    this.direction = direction;
    this.entity.style('width', '').style('height', '');
    if (recursive) {
      for (var i = 0; i < this.menuItems.length; i++) {
        this.menuItems[i].setDirection(this.direction, recursive);
      }
    }
    this._setDirectionClass();
    return this;
  },
  _setDirectionClass: function _setDirectionClass() {
    if (this.direction == MENU_HORIZONTAL) {
      this.entity.classed(css.menuVertical, false);
      this.entity.classed(css.menuHorizontal, true);
    } else {
      this.entity.classed(css.menuHorizontal, false);
      this.entity.classed(css.menuVertical, true);
    }
  },
  addSubmenu: function addSubmenu(item) {
    this.menuItems.push(new MenuItem(this, item, this.OPTIONS));
  },
  open: function open() {
    var _this = this;
    if (!this.isActive()) {
      _this.parent.parentMenu.openSubmenuNow = true;
      this.closeNeighbors(function () {
        if (_this.direction == MENU_HORIZONTAL) {
          _this._openHorizontal();
          _this.calculateMissingWidth(0);
        } else {
          _this._openVertical();
        }
      });
      _this.parent.parentMenu.openSubmenuNow = false;
    }
    return this;
  },
  /**
   * recursively calculate missed width for last menu level
   * @param width
   * @param cb
   */
  calculateMissingWidth: function calculateMissingWidth(width, cb) {
    var _this = this;
    if (this.entity.classed(css.list_top_level)) {
      if (width > this.OPTIONS.MAX_MENU_WIDTH) {
        if (typeof cb === "function") cb(width - this.OPTIONS.MAX_MENU_WIDTH);
      }
    } else {
      this.parent.parentMenu.calculateMissingWidth(width + this.width, function (widthToReduce) {
        if (widthToReduce > 0) {
          _this.reduceWidth(widthToReduce, function (newWidth) {
            if (typeof cb === "function") cb(newWidth); // callback is not defined if it is emitted from this level
          });
        } else if (typeof cb === "function") cb(widthToReduce);
      });
    }
  },
  /**
   * restore width (if it was reduced before)
   * @param width
   * @param isClosedElement (parameter for check if curent element emit this action)
   * @param cb
   */
  restoreWidth: function restoreWidth(width, isClosedElement, cb) {
    var _this = this;
    if (isClosedElement) {
      this.parent.parentMenu.restoreWidth(width, false, cb);
    } else if (width <= 0) {
      if (typeof cb === "function") cb();
    } else if (!this.entity.classed(css.list_top_level)) {
      var currentElementWidth = this.entity.node().offsetWidth;
      var newElementWidth = Math.min(width, _this.width);
      if (currentElementWidth < newElementWidth) {
        var duration = 250 * (currentElementWidth / newElementWidth);
        this.entity.transition().delay(0).duration(duration).style('width', newElementWidth + "px").each('end', function () {});
        _this.parent.parentMenu.restoreWidth(width - newElementWidth, false, cb);
      } else {
        this.parent.parentMenu.restoreWidth(width, false, cb);
      }
    } else {
      if (typeof cb === "function") cb();
    }
  },
  /**
   * made element narrower to free space for other element
   * @param width
   * @param cb
   */
  reduceWidth: function reduceWidth(width, cb) {
    var _this = this;
    var currWidth = this.entity.node().offsetWidth;

    if (currWidth <= this.OPTIONS.MIN_COL_WIDTH) {
      cb(width - _this.width + currWidth);
    } else {

      var newElementWidth = Math.max(this.OPTIONS.MIN_COL_WIDTH, _this.width - width);
      var duration = 250 / (_this.width / newElementWidth);
      this.entity.transition().delay(0).duration(duration).style('width', newElementWidth + "px").each('end', function () {
        cb(width - _this.width + newElementWidth);
      });
    }
  },
  _openHorizontal: function _openHorizontal() {
    var _this = this;
    _this.entity.classed('active', true).transition().delay(0).duration(250).style('width', _this.width + "px").each('end', function () {
      _this.marqueeToggle(true);
    });
  },
  _openVertical: function _openVertical() {
    var _this = this;
    _this.entity.style('height', '0px');
    _this.entity.transition().delay(0).duration(250).style('height', 36 * _this.menuItems.length + "px").each('end', function () {
      _this.entity.style('height', 'auto');
      _this.marqueeToggle(true);
      _this.scrollToFitView();
    });
    _this.entity.classed('active', true);
  },
  closeAllChildren: function closeAllChildren(cb) {
    var callbacks = 0;
    for (var i = 0; i < this.menuItems.length; i++) {
      if (this.menuItems[i].isActive()) {
        ++callbacks;
        this.menuItems[i].submenu.close(function () {
          if (--callbacks == 0) {
            if (typeof cb === "function") cb();
          }
        });
      }
    }
    if (callbacks == 0) {
      if (typeof cb === "function") cb();
    }
  },
  closeNeighbors: function closeNeighbors(cb) {
    if (this.parent) {
      this.parent.closeNeighbors(cb);
    } else {
      cb();
    }
  },
  close: function close(cb) {
    var _this = this;
    this.closeAllChildren(function () {
      if (_this.direction == MENU_HORIZONTAL) {
        _this._closeHorizontal(cb);
      } else {
        _this._closeVertical(cb);
      }
    });
  },
  _closeHorizontal: function _closeHorizontal(cb) {
    var elementWidth = this.entity.node().offsetWidth;
    var _this = this;
    var openSubmenuNow = _this.parent.parentMenu.openSubmenuNow;
    _this.entity.transition().delay(0).duration(20).style('width', 0 + "px").each('end', function () {
      _this.marqueeToggle(false);
      _this.entity.classed('active', false);
      if (!openSubmenuNow) {
        _this.restoreWidth(_this.OPTIONS.MAX_MENU_WIDTH, true, function () {
          if (typeof cb === "function") cb();
        });
      } else {
        if (typeof cb === "function") cb();
      }
    });
  },
  _closeVertical: function _closeVertical(cb) {
    var _this = this;
    _this.entity.transition().delay(0).duration(100).style('height', 0 + "px").each('end', function () {
      _this.marqueeToggle(false);
      _this.entity.classed('active', false);
      if (typeof cb === "function") cb();
    });
  },
  isActive: function isActive() {
    return this.entity.classed('active');
  },
  marqueeToggle: function marqueeToggle(toggle) {
    for (var i = 0; i < this.menuItems.length; i++) {
      this.menuItems[i].marqueeToggle(toggle);
    }
  },
  marqueeToggleAll: function marqueeToggleAll(toggle) {
    for (var i = 0; i < this.menuItems.length; i++) {
      this.menuItems[i].marqueeToggleAll(toggle);
    }
  },
  findItemById: function findItemById(id) {
    for (var i = 0; i < this.menuItems.length; i++) {
      if (this.menuItems[i].entity.data().id == id) {
        return this.menuItems[i];
      }
      if (this.menuItems[i].submenu) {
        var item = this.menuItems[i].submenu.findItemById(id);
        if (item) return item;
      }
    }
    return null;
  },
  getTopMenu: function getTopMenu() {
    if (this.parent) {
      return this.parent.parentMenu.getTopMenu();
    } else {
      return this;
    }
  },

  scrollToFitView: function scrollToFitView() {
    var treeMenuNode = this.getTopMenu().entity.node().parentNode;
    var parentItemNode = this.entity.node().parentNode;
    var menuRect = treeMenuNode.getBoundingClientRect();
    var itemRect = parentItemNode.getBoundingClientRect();
    var viewportItemTop = itemRect.top - menuRect.top;
    if (viewportItemTop + itemRect.height > menuRect.height) {
      var newItemTop = itemRect.height > menuRect.height ? menuRect.height - 10 : itemRect.height + 10;

      var newScrollTop = treeMenuNode.scrollTop + newItemTop - menuRect.height + viewportItemTop;

      var scrollTopTween = function scrollTopTween(scrollTop) {
        return function () {
          var i = d3.interpolateNumber(this.scrollTop, scrollTop);
          return function (t) {
            this.scrollTop = i(t);
          };
        };
      };

      d3.select(treeMenuNode).transition().duration(20).tween("scrolltoptween", scrollTopTween(newScrollTop));

      //treeMenuNode.scrollTop = scrollTop;
    }
  }

});

var MenuItem = _class2.default.extend({
  init: function init(parent, item, options) {
    var _this = this;
    this.parentMenu = parent;
    this.entity = item;
    var submenu = item.select('.' + css.list_outer);
    if (submenu.node()) {
      this.submenu = new Menu(this, submenu, options);
    }
    var label = this.entity.select('.' + css.list_item_label).on('mouseenter', function () {
      if (utils.isTouchDevice()) return;
      if (_this.parentMenu.direction == MENU_HORIZONTAL) {
        _this.openSubmenu();
        _this.marqueeToggle(true);
      }
    }).on('click.item', function () {
      if (utils.isTouchDevice()) return;
      d3.event.stopPropagation();
      if (_this.parentMenu.direction == MENU_HORIZONTAL) {
        _this.openSubmenu();
      } else {
        var view = d3.select(this);
        //only for leaf nodes
        if (!view.attr("children")) return;
        _this.toggleSubmenu();
      }
    }).onTap(function (evt) {
      d3.event.stopPropagation();
      if (_this.parentMenu.direction == MENU_VERTICAL) {
        var view = _this.entity.select('.' + css.list_item_label);
        //only for leaf nodes
        if (!view.attr("children")) return;
      }
      _this.toggleSubmenu();
    });
    return this;
  },
  setWidth: function setWidth(width, recursive, immediate) {
    if (this.submenu && recursive) {
      this.submenu.setWidth(width, recursive, immediate);
    }
    return this;
  },
  setDirection: function setDirection(direction, recursive) {
    if (this.submenu && recursive) {
      this.submenu.setDirection(direction, recursive);
    }
    return this;
  },
  toggleSubmenu: function toggleSubmenu() {
    if (this.submenu) {
      if (this.submenu.isActive()) {
        this.submenu.close();
      } else {
        this.submenu.open();
      }
    }
  },
  openSubmenu: function openSubmenu() {
    if (this.submenu) {
      this.submenu.open();
    } else {
      this.closeNeighbors();
    }
  },
  closeNeighbors: function closeNeighbors(cb) {
    this.parentMenu.closeAllChildren(cb);
  },
  isActive: function isActive() {
    return this.submenu && this.submenu.isActive();
  },
  marqueeToggleAll: function marqueeToggleAll(toggle) {
    var _this = this;
    var labels = this.entity.selectAll('.' + css.list_item_label);
    labels.each(function () {
      var label = d3.select(this).select('span');
      var parent = d3.select(this.parentNode);
      parent.classed('marquee', false);
      label.style("left", '');
      label.style("right", '');
      if (toggle) {
        if (label.node().scrollWidth > label.node().offsetWidth) {
          label.attr("data-content", label.text());
          var space = 30;
          label.style("left", -space - label.node().scrollWidth + 'px');
          label.style("right", -space - label.node().scrollWidth + 'px');
          parent.classed('marquee', true);
        }
      }
    });
  },
  marqueeToggle: function marqueeToggle(toggle) {
    var label = this.entity.select('.' + css.list_item_label).select('span');
    this.entity.classed('marquee', false);
    label.style("left", '');
    label.style("right", '');
    if (toggle) {
      if (label.node().scrollWidth > label.node().offsetWidth) {
        label.attr("data-content", label.text());
        var space = 30;
        label.style("left", -space - label.node().scrollWidth + 'px');
        label.style("right", -space - label.node().scrollWidth + 'px');
        this.entity.classed('marquee', true);
      }
    }
  }
});

var TreeMenu = _component2.default.extend({

  //setters-getters
  tree: function tree(input) {
    if (!arguments.length) return this._tree;
    this._tree = input;
    return this;
  },
  callback: function callback(input) {
    if (!arguments.length) return this._callback;
    this._callback = input;
    return this;
  },
  markerID: function markerID(input) {
    if (!arguments.length) return this._markerID;
    this._markerID = input;
    return this;
  },
  alignX: function alignX(input) {
    if (!arguments.length) return this._alignX;
    this._alignX = input;
    return this;
  },
  alignY: function alignY(input) {
    if (!arguments.length) return this._alignY;
    this._alignY = input;
    return this;
  },
  top: function top(input) {
    if (!arguments.length) return this._top;
    this._top = input;
    return this;
  },
  left: function left(input) {
    if (!arguments.length) return this._left;
    this._left = input;
    return this;
  },

  init: function init(config, context) {

    var _this = this;

    this.name = 'gapminder-treemenu';
    this.model_expects = [{
      name: "marker",
      type: "model"
    }, {
      name: "marker_tags",
      type: "model"
    }, {
      name: "time",
      type: "time"
    }, {
      name: "locale",
      type: "locale"
    }];

    this.context = context;
    // object for manipulation with menu representation level
    this.menuEntity = null;
    this.model_binds = {
      "change:marker": function changeMarker(evt, path) {
        if (path.indexOf(_this._markerID + '.which') == -1 && path.indexOf(_this._markerID + '.scaleType') == -1) return;
        _this.updateView();
      }
    };

    //contructor is the same as any component
    this._super(config, context);

    //default callback
    this._callback = function (indicator) {
      console.log("Indicator selector: stub callback fired. New indicator is ", indicator);
    };
    this._alignX = "center";
    this._alignY = "center";

    //options
    this.OPTIONS = utils.deepClone(OPTIONS);
  },

  ready: function ready() {
    this.updateView();

    //TODO: hack! potentially unsafe operation here
    var tags = this.model.marker_tags.label.getData();
    this._buildIndicatorsTree(tags);
  },

  readyOnce: function readyOnce() {
    //this function is only called once at start, when both DOM and this.model are ready
    //this.element contains the view where you can append the menu
    this.element = d3.select(this.placeholder);
    //menu class private
    var _this = this;

    this.element.selectAll("div").remove();

    //general markup

    this.element.append("div").attr("class", css.background).on("click", function () {
      d3.event.stopPropagation();
      _this.toggle();
    });

    this.wrapperOuter = this.element.append('div').classed(css.wrapper_outer, true).classed(css.noTransition, true);

    this.wrapper = this.wrapperOuter.append('div').classed(css.wrapper, true).classed(css.noTransition, true).classed("vzb-dialog-scrollable", true);

    this.wrapper.on("click", function () {
      d3.event.stopPropagation();
    });

    this.wrapper.append("div").attr("class", css.close).html(_iconset.close).on("click", function () {
      d3.event.stopPropagation();
      _this.toggle();
    }).select("svg").attr("width", "0px").attr("height", "0px").attr("class", css.close + '-icon');

    this.wrapper.append('div').classed(css.scaletypes, true).append('span');
    this.wrapper.append('div').classed(css.title, true).append('span');

    this.wrapper.append('div').classed(css.search_wrap, true).append('input').classed(css.search, true).attr('type', 'search').attr('id', css.search);

    //init functions
    d3.select('body').on('mousemove', _this._mousemoveDocument);
    this.wrapper.on('mouseleave', function () {
      //if(_this.menuEntity.direction != MENU_VERTICAL) _this.menuEntity.closeAllChildren();
    });

    this.translator = this.model.locale.getTFunction();

    _this._enableSearch();

    _this.resize();
  },

  _buildIndicatorsTree: function _buildIndicatorsTree(tagsArray) {
    if (tagsArray === true || !tagsArray) tagsArray = [];

    var _this = this;
    var ROOT = "_root";
    var DEFAULT = "_default";
    var UNCLASSIFIED = "_unclassified";
    var ADVANCED = "advanced";

    var indicatorsTree;

    //init the dictionary of tags
    var tags = {};
    tags[ROOT] = { id: ROOT, children: [] };
    tags[UNCLASSIFIED] = { id: UNCLASSIFIED, type: "folder", name: this.translator("buttons/unclassified"), children: [] };

    //populate the dictionary of tags
    tagsArray.forEach(function (tag) {
      tags[tag.tag] = { id: tag.tag, name: tag.name, type: "folder", children: [] };
    });

    //init the tag tree
    indicatorsTree = tags[ROOT];
    indicatorsTree.children.push({ "id": DEFAULT });
    indicatorsTree.children.push(tags[UNCLASSIFIED]);

    //populate the tag tree
    tagsArray.forEach(function (tag) {
      if (!tag.parent || !tags[tag.parent]) {
        // add tag to a root
        indicatorsTree.children.push(tags[tag.tag]);
      } else {
        //add tag to a branch
        tags[tag.parent].children.push(tags[tag.tag]);
      }
    });

    utils.forEach(this.model.marker._root._data, function (dataSource) {
      if (dataSource._type !== "data") return;

      var indicatorsDB = dataSource.getConceptprops();
      var datasetName = dataSource.getDatasetName();
      tags[datasetName] = { id: datasetName, type: "dataset", children: [] };
      tags[ROOT].children.push(tags[datasetName]);

      utils.forEach(indicatorsDB, function (entry, id) {
        //if entry's tag are empty don't include it in the menu
        if (entry.tags == "_none") return;
        if (!entry.tags) entry.tags = datasetName || UNCLASSIFIED;
        var concept = { id: id, name: entry.name, unit: entry.unit, description: entry.description, dataSource: dataSource._name };
        entry.tags.split(",").forEach(function (tag) {
          if (tags[tag.trim()]) {
            tags[tag.trim()].children.push(concept);
          } else {
            //if entry's tag is not found in the tag dictionary
            if (!_this.consoleGroupOpen) {
              console.groupCollapsed("Some tags were are not found, so indicators went under 'Unclassified' menu");
              _this.consoleGroupOpen = true;
            }
            utils.warn("tag '" + tag + "' for indicator '" + id + "'");
            tags[UNCLASSIFIED].children.push(concept);
          }
        });
      });
    });
    if (_this.consoleGroupOpen) {
      console.groupEnd();
      delete _this.consoleGroupOpen;
    }
    this._sortChildren(indicatorsTree);
    this.indicatorsTree = indicatorsTree;
  },

  _sortChildren: function _sortChildren(tree, isSubfolder) {
    var _this = this;
    if (!tree.children) return;
    tree.children.sort(utils
    //in each folder including root: put subfolders below loose items
    .firstBy()(function (a, b) {
      a = a.type === "dataset" ? 1 : 0;b = b.type === "dataset" ? 1 : 0;return b - a;
    }).thenBy(function (a, b) {
      a = a.children ? 1 : 0;b = b.children ? 1 : 0;return a - b;
    }).thenBy(function (a, b) {
      //in the root level put "time" on top and send "anvanced" to the bottom
      if (!isSubfolder) {
        if (a.id == "time") return -1;
        if (b.id == "time") return 1;
        if (a.id == "advanced") return 1;
        if (b.id == "advanced") return -1;
      }
      //sort items alphabetically. folders go down because of the emoji folder in the beginning of the name
      return a.name > b.name ? 1 : -1;
    }));

    //recursively sort items in subfolders too
    tree.children.forEach(function (d) {
      _this._sortChildren(d, true);
    });
  },

  //happens on resizing of the container
  resize: function resize() {
    var _this = this;

    this.profiles = {
      "small": {
        col_width: 200
      },
      "medium": {
        col_width: 200
      },
      "large": {
        col_width: 200
      }
    };

    var top = this._top;
    var left = this._left;

    this.wrapper.classed(css.noTransition, true);
    this.wrapper.node().scrollTop = 0;

    this.activeProfile = this.profiles[this.getLayoutProfile()];
    this.OPTIONS.IS_MOBILE = this.getLayoutProfile() === "small";

    if (this.menuEntity) {
      this.menuEntity.setWidth(this.activeProfile.col_width, true, true);

      if (this.OPTIONS.IS_MOBILE) {
        if (this.menuEntity.direction != MENU_VERTICAL) {
          this.menuEntity.setDirection(MENU_VERTICAL, true);
          this.OPTIONS.MENU_DIRECTION = MENU_VERTICAL;
        }
      } else {
        if (this.menuEntity.direction != MENU_HORIZONTAL) {
          this.menuEntity.setDirection(MENU_HORIZONTAL, true);
          this.OPTIONS.MENU_DIRECTION = MENU_HORIZONTAL;
        }
      }
    }

    this.width = _this.element.node().offsetWidth;
    this.height = _this.element.node().offsetHeight;
    var rect = this.wrapperOuter.node().getBoundingClientRect();
    var containerWidth = rect.width;
    var containerHeight = rect.height;
    if (containerWidth) {
      if (this.OPTIONS.IS_MOBILE) {
        this.clearPos();
      } else {
        if (top || left) {
          if (this.wrapperOuter.node().offsetTop < 10) {
            this.wrapperOuter.style('top', '10px');
          }
          if (this.height - _this.wrapperOuter.node().offsetTop - containerHeight < 0) {
            if (containerHeight > this.height) {
              containerHeight = this.height - 20;
            }
            this.wrapperOuter.style({ 'top': this.height - containerHeight - 10 + 'px', 'bottom': 'auto' });
          }
          if (top) top = _this.wrapperOuter.node().offsetTop;
        }

        var maxHeight;
        if (this.wrapperOuter.classed(css.alignYb)) {
          maxHeight = this.wrapperOuter.node().offsetTop + this.wrapperOuter.node().offsetHeight;
        } else {
          maxHeight = this.height - this.wrapperOuter.node().offsetTop;
        }
        this.wrapper.style('max-height', maxHeight - 10 + 'px');

        this.wrapperOuter.classed(css.alignXc, this._alignX === "center");
        this.wrapperOuter.style("margin-left", this._alignX === "center" ? "-" + containerWidth / 2 + "px" : null);
        if (this._alignX === "center") {
          this.OPTIONS.MAX_MENU_WIDTH = this.width / 2 - containerWidth * 0.5 - 10;
        } else {
          this.OPTIONS.MAX_MENU_WIDTH = this.width - this.wrapperOuter.node().offsetLeft - containerWidth - 10; // 10 - padding around wrapper
        }

        var minMenuWidth = this.activeProfile.col_width + this.OPTIONS.MIN_COL_WIDTH * 2;
        var leftPos = this.wrapperOuter.node().offsetLeft;
        this.OPTIONS.MENU_OPEN_LEFTSIDE = this.OPTIONS.MAX_MENU_WIDTH < minMenuWidth && leftPos > this.OPTIONS.MAX_MENU_WIDTH + 10;
        if (this.OPTIONS.MENU_OPEN_LEFTSIDE) {
          if (leftPos < minMenuWidth + 10) leftPos = minMenuWidth + 10;
          this.OPTIONS.MAX_MENU_WIDTH = leftPos - 10; // 10 - padding around wrapper
        } else {
          if (this.OPTIONS.MAX_MENU_WIDTH < minMenuWidth) {
            leftPos = leftPos - (minMenuWidth - this.OPTIONS.MAX_MENU_WIDTH);
            this.OPTIONS.MAX_MENU_WIDTH = minMenuWidth;
          }
        }

        if (left) {
          left = leftPos;
        } else {
          if (leftPos != this.wrapperOuter.node().offsetLeft) {
            this.wrapperOuter.style({ 'left': 'auto', 'right': this.width - leftPos - rect.width + 'px' });
          }
        }

        this._top = top;
        this._left = left;

        if (left || top) this.setPos();

        this.wrapperOuter.classed('vzb-treemenu-open-left-side', !this.OPTIONS.IS_MOBILE && this.OPTIONS.MENU_OPEN_LEFTSIDE);
      }
    }

    this.wrapper.node().offsetHeight;
    this.wrapper.classed(css.noTransition, false);

    this.setHorizontalMenuHeight();

    return this;
  },

  toggle: function toggle() {
    var _this = this;
    var hidden = !this.element.classed(css.hidden);
    this.element.classed(css.hidden, hidden);

    if (hidden) {
      this.clearPos();
      this.menuEntity.marqueeToggle(false);
    } else {
      if (top || left) this.setPos();
      this.resize();
      this.scrollToSelected();
    }

    this.wrapper.classed(css.noTransition, hidden);

    this.parent.components.forEach(function (c) {
      if (c.name == "gapminder-dialogs") {
        d3.select(c.placeholder.parentNode).classed("vzb-blur", !hidden);
      } else if (c.element.classed) {
        c.element.classed("vzb-blur", c != _this && !hidden);
      } else {
        d3.select(c.element).classed("vzb-blur", c != _this && !hidden);
      }
    });

    this.width = _this.element.node().offsetWidth;
  },

  scrollToSelected: function scrollToSelected() {
    var _this = this;
    var scrollToItem = function scrollToItem(listNode, itemNode) {
      listNode.scrollTop = 0;
      var rect = listNode.getBoundingClientRect();
      var itemRect = itemNode.getBoundingClientRect();
      var scrollTop = itemRect.bottom - rect.top - listNode.offsetHeight + 10;
      listNode.scrollTop = scrollTop;
    };

    if (this.menuEntity.direction == MENU_VERTICAL) {
      scrollToItem(this.wrapper.node(), this.selectedNode);
      _this.menuEntity.marqueeToggleAll(true);
    } else {
      var selectedItem = this.menuEntity.findItemById(d3.select(this.selectedNode).data().id);
      selectedItem.submenu.calculateMissingWidth(0, function () {
        _this.menuEntity.marqueeToggleAll(true);
      });

      var parent = this.selectedNode;
      var listNode;
      while (!utils.hasClass(parent, css.list_top_level)) {
        if (parent.tagName == 'LI') {
          listNode = utils.hasClass(parent.parentNode, css.list_top_level) ? parent.parentNode.parentNode : parent.parentNode;
          scrollToItem(listNode, parent);
        }
        parent = parent.parentNode;
      }
    }
  },

  setPos: function setPos() {
    var top = this._top;
    var left = this._left;
    var rect = this.wrapperOuter.node().getBoundingClientRect();

    if (top) {
      this.wrapperOuter.style({ 'top': top + 'px', 'bottom': 'auto' });
      this.wrapperOuter.classed(css.absPosVert, top);
    }
    if (left) {
      var right = this.element.node().offsetWidth - left - rect.width;
      right = right < 10 ? 10 : right;
      this.wrapperOuter.style({ 'right': right + 'px', 'left': 'auto' });
      this.wrapperOuter.classed(css.absPosHoriz, right);
    }
  },

  clearPos: function clearPos() {
    this._top = '';
    this._left = '';
    this.wrapperOuter.attr("style", "");
    this.wrapperOuter.classed(css.absPosVert, '');
    this.wrapperOuter.classed(css.absPosHoriz, '');
    this.wrapperOuter.classed(css.menuOpenLeftSide, '');
    this.wrapper.style('max-height', '');
  },

  setHorizontalMenuHeight: function setHorizontalMenuHeight() {
    var wrapperHeight = null;
    if (this.menuEntity && this.OPTIONS.MENU_DIRECTION == MENU_HORIZONTAL && this.menuEntity.menuItems.length) {
      var oneItemHeight = parseInt(this.menuEntity.menuItems[0].entity.style('height'), 10);
      var menuMaxHeight = oneItemHeight * this._maxChildCount;
      var rootMenuHeight = Math.max(this.menuEntity.menuItems.length, 3) * oneItemHeight + this.menuEntity.entity.node().offsetTop + parseInt(this.wrapper.style('padding-bottom'), 10);
      wrapperHeight = "" + Math.max(menuMaxHeight, rootMenuHeight) + "px";
    }
    this.wrapper.classed(css.noTransition, true);
    this.wrapper.node().offsetHeight;
    this.wrapper.style("height", wrapperHeight);
    this.wrapper.node().offsetHeight;
    this.wrapper.classed(css.noTransition, false);
  },
  //search listener
  _enableSearch: function _enableSearch() {
    var _this = this;

    var input = this.wrapper.select('.' + css.search);

    //it forms the array of possible queries
    var getMatches = function getMatches(value) {
      var matches = {
        _id: 'root',
        children: []
      };

      //translation integration
      var translationMatch = function translationMatch(value, data, i) {

        var translate = data[i].name;
        if (!translate && _this.translator) {
          var t1 = _this.translator('indicator' + '/' + data[i][_this.OPTIONS.SEARCH_PROPERTY] + '/' + _this.model.marker[_this._markerID]._type);
          translate = t1 || _this.translator('indicator/' + data[i][_this.OPTIONS.SEARCH_PROPERTY]);
        }
        return translate && translate.toLowerCase().indexOf(value.toLowerCase()) >= 0;
      };

      var matching = function matching(data) {
        var SUBMENUS = _this.OPTIONS.SUBMENUS;
        for (var i = 0; i < data.length; i++) {
          var match = false;
          match = translationMatch(value, data, i);
          if (match) {
            matches.children.push(data[i]);
          }
          if (!match && data[i][SUBMENUS]) {
            matching(data[i][SUBMENUS]);
          }
        }
      };
      matching(_this.dataFiltered.children);
      return matches;
    };

    var searchValueNonEmpty = false;

    var searchIt = utils.debounce(function () {
      var value = input.node().value;

      //Protection from unwanted IE11 input events.
      //IE11 triggers an 'input' event when 'placeholder' attr is set to input element and
      //on 'focusin' and on 'focusout', if nothing has been entered into the input.
      if (!searchValueNonEmpty && value == "") return;
      searchValueNonEmpty = value != "";

      if (value.length >= _this.OPTIONS.SEARCH_MIN_STR) {
        _this.redraw(getMatches(value), true);
      } else {
        _this.redraw();
      }
    }, 250);

    input.on('input', searchIt);
  },

  _selectIndicator: function _selectIndicator(value) {
    this._callback("which", value, this._markerID);
    this.toggle();
  },

  //function is redrawing data and built structure
  redraw: function redraw(data, useDataFiltered) {
    var _this = this;

    var markerID = this._markerID;

    var dataFiltered;

    var indicatorsDB = {};
    utils.forEach(this.model.marker._root._data, function (m) {
      if (m._type === "data") utils.deepExtend(indicatorsDB, m.getConceptprops());
    });

    var hookType = _this.model.marker[markerID]._type;

    if (useDataFiltered) {
      dataFiltered = data;
    } else {
      if (data == null) data = this._tree;

      var allowedIDs = utils.keys(indicatorsDB).filter(function (f) {
        //check if indicator is denied to show with allow->names->!indicator
        if (_this.model.marker[markerID].allow && _this.model.marker[markerID].allow.names && _this.model.marker[markerID].allow.names.indexOf('!' + f) != -1) return false;
        //keep indicator if nothing is specified in tool properties
        if (!_this.model.marker[markerID].allow || !_this.model.marker[markerID].allow.scales) return true;
        //keep indicator if any scale is allowed in tool properties
        if (_this.model.marker[markerID].allow.scales[0] == "*") return true;

        // if no scales defined, all are allowed
        if (!indicatorsDB[f].scales) return true;

        //check if there is an intersection between the allowed tool scale types and the ones of indicator
        for (var i = indicatorsDB[f].scales.length - 1; i >= 0; i--) {
          if (_this.model.marker[markerID].allow.scales.indexOf(indicatorsDB[f].scales[i]) > -1) return true;
        }

        return false;
      });

      dataFiltered = utils.pruneTree(data, function (f) {
        return allowedIDs.indexOf(f.id) > -1;
      });

      this.dataFiltered = dataFiltered;
    }

    this.wrapper.select('ul').remove();

    this.element.select('.' + css.title).select("span").text(this.translator("buttons/" + markerID));

    this.element.select('.' + css.search).attr("placeholder", this.translator("placeholder/search") + "...");

    this._maxChildCount = 0;

    var createSubmeny = function createSubmeny(select, data, toplevel) {
      if (!data.children) return;
      _this._maxChildCount = Math.max(_this._maxChildCount, data.children.length);
      var _select = toplevel ? select : select.append('div').classed(css.list_outer, true);

      var li = _select.append('ul').classed(css.list, !toplevel).classed(css.list_top_level, toplevel).classed("vzb-dialog-scrollable", true).selectAll('li').data(data.children, function (d) {
        return d['id'];
      }).enter().append('li');

      li.append('span').classed(css.list_item_label, true)
      // .attr("info", function(d) {
      //   return d.id;
      // })
      .attr("children", function (d) {
        return d.children ? "true" : null;
      }).attr("type", function (d) {
        return d.type ? d.type : null;
      }).on('click', function (d) {
        var view = d3.select(this);
        //only for leaf nodes
        if (view.attr("children")) return;
        d3.event.stopPropagation();
        _this._selectIndicator({ concept: d.id, dataSource: d.dataSource });
      }).append('span').text(function (d) {
        //Let the indicator "_default" in tree menu be translated differnetly for every hook type
        var translated = d.id === "_default" ? _this.translator("indicator/_default/" + hookType) : d.name || d.id;
        if (!translated && translated !== "") utils.warn("translation missing: NAME of " + d.id);
        return translated || "";
      });

      li.classed(css.list_item, true).classed(css.hasChild, function (d) {
        return d['children'];
      }).classed(css.isSpecial, function (d) {
        return d['special'];
      }).each(function (d) {
        var view = d3.select(this);

        //deepLeaf
        if (!d.children) {
          var deepLeaf = view.append('div').attr('class', css.menuHorizontal + ' ' + css.list_outer + ' ' + css.list_item_leaf);
          deepLeaf.on('click', function (d) {
            _this._selectIndicator({ concept: d.id, dataSource: d.dataSource });
          });
          var deepLeafContent = deepLeaf.append('div').classed(css.leaf + ' ' + css.leaf_content + " vzb-dialog-scrollable", true);
          deepLeafContent.append('span').classed(css.leaf_content_item + ' ' + css.leaf_content_item_title, true).text(function (d) {
            //Let the indicator "_default" in tree menu be translated differnetly for every hook type
            var translated = d.id === "_default" ? _this.translator("indicator/_default/" + hookType) : d.name;
            return translated || "";
          });
          var hideUnits;
          var units = deepLeafContent.append('span').classed(css.leaf_content_item, true).text(function (d) {
            //Let the indicator "_default" in tree menu be translated differnetly for every hook type
            var translated = d.id === "_default" ? _this.translator("unit/_default/" + hookType) : d.unit;
            hideUnits = !translated;
            return _this.translator('hints/units') + ': ' + translated || "";
          });
          units.classed('vzb-hidden', hideUnits);
          var hideDescription;
          var description = deepLeafContent.append('span').classed(css.leaf_content_item + ' ' + css.leaf_content_item_descr, true).text(function (d) {
            //Let the indicator "_default" in tree menu be translated differnetly for every hook type
            var translated = d.id === "_default" ? _this.translator("description/_default/" + hookType) : d.description;
            hideDescription = !translated;
            return hideUnits && hideDescription ? _this.translator("hints/nodescr") : translated || "";
          });
          description.classed('vzb-hidden', hideDescription && !hideUnits);
        }

        if (d.id == _this.model.marker[markerID].which) {
          var parent;
          if (_this.selectedNode && toplevel) {
            parent = _this.selectedNode.parentNode;
            d3.select(_this.selectedNode).select('.' + css.list_item_leaf).classed('active', false);
            while (!utils.hasClass(parent, css.list_top_level)) {
              if (parent.tagName == 'UL') {
                d3.select(parent.parentNode).classed('active', false);
              }
              parent = parent.parentNode;
            }
          }
          if (!_this.selectedNode || toplevel) {
            parent = this.parentNode;
            d3.select(this).classed('item-active', true).select('.' + css.list_item_leaf).classed('active', true);
            while (!utils.hasClass(parent, css.list_top_level)) {
              if (parent.tagName == 'UL') {
                d3.select(parent.parentNode).classed('active', true);
              }
              if (parent.tagName == 'LI') {
                d3.select(parent).classed('item-active', true);
              }
              parent = parent.parentNode;
            }
            _this.selectedNode = this;
          }
        }
        createSubmeny(view, d);
      });
    };

    if (this.OPTIONS.IS_MOBILE) {
      this.OPTIONS.MENU_DIRECTION = MENU_VERTICAL;
    } else {
      this.OPTIONS.MENU_DIRECTION = MENU_HORIZONTAL;
    }
    this.selectedNode = null;
    createSubmeny(this.wrapper, dataFiltered, true);
    this.menuEntity = new Menu(null, this.wrapper.selectAll('.' + css.list_top_level), this.OPTIONS);
    if (this.menuEntity) this.menuEntity.setDirection(this.OPTIONS.MENU_DIRECTION);
    if (this.menuEntity) this.menuEntity.setWidth(this.activeProfile.col_width, true, true);

    this.setHorizontalMenuHeight();

    if (!useDataFiltered) {
      var pointer = "_default";
      if (allowedIDs.indexOf(this.model.marker[markerID].which) > -1) pointer = this.model.marker[markerID].which;
      if (!indicatorsDB[pointer]) utils.error("Concept properties of " + pointer + " are missing from the set, or the set is empty. Put a breakpoint here and check what you have in indicatorsDB");

      if (!indicatorsDB[pointer].scales) {
        this.element.select('.' + css.scaletypes).classed(css.hidden, true);
        return true;
      }
      var scaleTypesData = indicatorsDB[pointer].scales.filter(function (f) {
        if (!_this.model.marker[markerID].allow || !_this.model.marker[markerID].allow.scales) return true;
        if (_this.model.marker[markerID].allow.scales[0] == "*") return true;
        return _this.model.marker[markerID].allow.scales.indexOf(f) > -1;
      });
      if (scaleTypesData.length == 0) {
        this.element.select('.' + css.scaletypes).classed(css.hidden, true);
      } else {

        var scaleTypes = this.element.select('.' + css.scaletypes).classed(css.hidden, false).selectAll("span").data(scaleTypesData, function (d) {
          return d;
        });

        scaleTypes.exit().remove();

        scaleTypes.enter().append("span").on("click", function (d) {
          d3.event.stopPropagation();
          _this._setModel("scaleType", d, _this._markerID);
        });

        var mdlScaleType = _this.model.marker[markerID].scaleType;

        scaleTypes.classed(css.scaletypesDisabled, scaleTypesData.length < 2).classed(css.scaletypesActive, function (d) {
          return (d == mdlScaleType || d === "log" && mdlScaleType === "genericLog") && scaleTypesData.length > 1;
        }).text(function (d) {
          return _this.translator("scaletype/" + d);
        });
      }
    }

    return this;
  },

  updateView: function updateView() {
    var _this = this;

    if (!this._markerID) return;

    this.wrapperOuter.classed(css.absPosVert, this._top);
    this.wrapperOuter.classed(css.alignYt, this._alignY === "top");
    this.wrapperOuter.classed(css.alignYb, this._alignY === "bottom");
    this.wrapperOuter.classed(css.absPosHoriz, this._left);
    this.wrapperOuter.classed(css.alignXl, this._alignX === "left");
    this.wrapperOuter.classed(css.alignXr, this._alignX === "right");

    var setModel = this._setModel.bind(this);
    this.callback(setModel).tree(this.indicatorsTree).redraw();

    this.wrapper.select('.' + css.search).node().value = "";

    return this;
  },

  _setModel: function _setModel(what, value, hookID) {

    var mdl = this.model.marker[hookID];
    if (what == 'which') mdl.setWhich(value);
    if (what == 'scaleType') mdl.setScaleType(value);
  }

});

exports.default = TreeMenu;

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

var toString = {}.toString;

module.exports = function(it){
  return toString.call(it).slice(8, -1);
};

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

// 7.2.1 RequireObjectCoercible(argument)
module.exports = function(it){
  if(it == undefined)throw TypeError("Can't call method on  " + it);
  return it;
};

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

var fails = __webpack_require__(5);

module.exports = function(method, arg){
  return !!method && fails(function(){
    arg ? method.call(null, function(){}, 1) : method.call(null);
  });
};

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

// 0 -> Array#forEach
// 1 -> Array#map
// 2 -> Array#filter
// 3 -> Array#some
// 4 -> Array#every
// 5 -> Array#find
// 6 -> Array#findIndex
var ctx      = __webpack_require__(35)
  , IObject  = __webpack_require__(68)
  , toObject = __webpack_require__(13)
  , toLength = __webpack_require__(12)
  , asc      = __webpack_require__(230);
module.exports = function(TYPE, $create){
  var IS_MAP        = TYPE == 1
    , IS_FILTER     = TYPE == 2
    , IS_SOME       = TYPE == 3
    , IS_EVERY      = TYPE == 4
    , IS_FIND_INDEX = TYPE == 6
    , NO_HOLES      = TYPE == 5 || IS_FIND_INDEX
    , create        = $create || asc;
  return function($this, callbackfn, that){
    var O      = toObject($this)
      , self   = IObject(O)
      , f      = ctx(callbackfn, that, 3)
      , length = toLength(self.length)
      , index  = 0
      , result = IS_MAP ? create($this, length) : IS_FILTER ? create($this, 0) : undefined
      , val, res;
    for(;length > index; index++)if(NO_HOLES || index in self){
      val = self[index];
      res = f(val, index, O);
      if(TYPE){
        if(IS_MAP)result[index] = res;            // map
        else if(res)switch(TYPE){
          case 3: return true;                    // some
          case 5: return val;                     // find
          case 6: return index;                   // findIndex
          case 2: result.push(val);               // filter
        } else if(IS_EVERY)return false;          // every
      }
    }
    return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : result;
  };
};

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

// most Object methods by ES6 should accept primitives
var $export = __webpack_require__(0)
  , core    = __webpack_require__(34)
  , fails   = __webpack_require__(5);
module.exports = function(KEY, exec){
  var fn  = (core.Object || {})[KEY] || Object[KEY]
    , exp = {};
  exp[KEY] = exec(fn);
  $export($export.S + $export.F * fails(function(){ fn(1); }), 'Object', exp);
};

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

// 7.1.1 ToPrimitive(input [, PreferredType])
var isObject = __webpack_require__(6);
// instead of the ES6 spec version, we didn't implement @@toPrimitive case
// and the second argument - flag - preferred type is a string
module.exports = function(it, S){
  if(!isObject(it))return it;
  var fn, val;
  if(S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;
  if(typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it)))return val;
  if(!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;
  throw TypeError("Can't convert object to primitive value");
};

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

var core = module.exports = {version: '2.4.0'};
if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef

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

// optional / simple context binding
var aFunction = __webpack_require__(16);
module.exports = function(fn, that, length){
  aFunction(fn);
  if(that === undefined)return fn;
  switch(length){
    case 1: return function(a){
      return fn.call(that, a);
    };
    case 2: return function(a, b){
      return fn.call(that, a, b);
    };
    case 3: return function(a, b, c){
      return fn.call(that, a, b, c);
    };
  }
  return function(/* ...args */){
    return fn.apply(that, arguments);
  };
};

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

var Map     = __webpack_require__(175)
  , $export = __webpack_require__(0)
  , shared  = __webpack_require__(81)('metadata')
  , store   = shared.store || (shared.store = new (__webpack_require__(178)));

var getOrCreateMetadataMap = function(target, targetKey, create){
  var targetMetadata = store.get(target);
  if(!targetMetadata){
    if(!create)return undefined;
    store.set(target, targetMetadata = new Map);
  }
  var keyMetadata = targetMetadata.get(targetKey);
  if(!keyMetadata){
    if(!create)return undefined;
    targetMetadata.set(targetKey, keyMetadata = new Map);
  } return keyMetadata;
};
var ordinaryHasOwnMetadata = function(MetadataKey, O, P){
  var metadataMap = getOrCreateMetadataMap(O, P, false);
  return metadataMap === undefined ? false : metadataMap.has(MetadataKey);
};
var ordinaryGetOwnMetadata = function(MetadataKey, O, P){
  var metadataMap = getOrCreateMetadataMap(O, P, false);
  return metadataMap === undefined ? undefined : metadataMap.get(MetadataKey);
};
var ordinaryDefineOwnMetadata = function(MetadataKey, MetadataValue, O, P){
  getOrCreateMetadataMap(O, P, true).set(MetadataKey, MetadataValue);
};
var ordinaryOwnMetadataKeys = function(target, targetKey){
  var metadataMap = getOrCreateMetadataMap(target, targetKey, false)
    , keys        = [];
  if(metadataMap)metadataMap.forEach(function(_, key){ keys.push(key); });
  return keys;
};
var toMetaKey = function(it){
  return it === undefined || typeof it == 'symbol' ? it : String(it);
};
var exp = function(O){
  $export($export.S, 'Reflect', O);
};

module.exports = {
  store: store,
  map: getOrCreateMetadataMap,
  has: ordinaryHasOwnMetadata,
  get: ordinaryGetOwnMetadata,
  set: ordinaryDefineOwnMetadata,
  keys: ordinaryOwnMetadataKeys,
  key: toMetaKey,
  exp: exp
};

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

"use strict";
'use strict';
if(__webpack_require__(8)){
  var LIBRARY             = __webpack_require__(50)
    , global              = __webpack_require__(4)
    , fails               = __webpack_require__(5)
    , $export             = __webpack_require__(0)
    , $typed              = __webpack_require__(82)
    , $buffer             = __webpack_require__(111)
    , ctx                 = __webpack_require__(35)
    , anInstance          = __webpack_require__(49)
    , propertyDesc        = __webpack_require__(42)
    , hide                = __webpack_require__(17)
    , redefineAll         = __webpack_require__(54)
    , toInteger           = __webpack_require__(43)
    , toLength            = __webpack_require__(12)
    , toIndex             = __webpack_require__(56)
    , toPrimitive         = __webpack_require__(33)
    , has                 = __webpack_require__(15)
    , same                = __webpack_require__(172)
    , classof             = __webpack_require__(67)
    , isObject            = __webpack_require__(6)
    , toObject            = __webpack_require__(13)
    , isArrayIter         = __webpack_require__(96)
    , create              = __webpack_require__(51)
    , getPrototypeOf      = __webpack_require__(26)
    , gOPN                = __webpack_require__(52).f
    , getIterFn           = __webpack_require__(113)
    , uid                 = __webpack_require__(57)
    , wks                 = __webpack_require__(7)
    , createArrayMethod   = __webpack_require__(31)
    , createArrayIncludes = __webpack_require__(72)
    , speciesConstructor  = __webpack_require__(105)
    , ArrayIterators      = __webpack_require__(114)
    , Iterators           = __webpack_require__(62)
    , $iterDetect         = __webpack_require__(78)
    , setSpecies          = __webpack_require__(55)
    , arrayFill           = __webpack_require__(89)
    , arrayCopyWithin     = __webpack_require__(152)
    , $DP                 = __webpack_require__(9)
    , $GOPD               = __webpack_require__(25)
    , dP                  = $DP.f
    , gOPD                = $GOPD.f
    , RangeError          = global.RangeError
    , TypeError           = global.TypeError
    , Uint8Array          = global.Uint8Array
    , ARRAY_BUFFER        = 'ArrayBuffer'
    , SHARED_BUFFER       = 'Shared' + ARRAY_BUFFER
    , BYTES_PER_ELEMENT   = 'BYTES_PER_ELEMENT'
    , PROTOTYPE           = 'prototype'
    , ArrayProto          = Array[PROTOTYPE]
    , $ArrayBuffer        = $buffer.ArrayBuffer
    , $DataView           = $buffer.DataView
    , arrayForEach        = createArrayMethod(0)
    , arrayFilter         = createArrayMethod(2)
    , arraySome           = createArrayMethod(3)
    , arrayEvery          = createArrayMethod(4)
    , arrayFind           = createArrayMethod(5)
    , arrayFindIndex      = createArrayMethod(6)
    , arrayIncludes       = createArrayIncludes(true)
    , arrayIndexOf        = createArrayIncludes(false)
    , arrayValues         = ArrayIterators.values
    , arrayKeys           = ArrayIterators.keys
    , arrayEntries        = ArrayIterators.entries
    , arrayLastIndexOf    = ArrayProto.lastIndexOf
    , arrayReduce         = ArrayProto.reduce
    , arrayReduceRight    = ArrayProto.reduceRight
    , arrayJoin           = ArrayProto.join
    , arraySort           = ArrayProto.sort
    , arraySlice          = ArrayProto.slice
    , arrayToString       = ArrayProto.toString
    , arrayToLocaleString = ArrayProto.toLocaleString
    , ITERATOR            = wks('iterator')
    , TAG                 = wks('toStringTag')
    , TYPED_CONSTRUCTOR   = uid('typed_constructor')
    , DEF_CONSTRUCTOR     = uid('def_constructor')
    , ALL_CONSTRUCTORS    = $typed.CONSTR
    , TYPED_ARRAY         = $typed.TYPED
    , VIEW                = $typed.VIEW
    , WRONG_LENGTH        = 'Wrong length!';

  var $map = createArrayMethod(1, function(O, length){
    return allocate(speciesConstructor(O, O[DEF_CONSTRUCTOR]), length);
  });

  var LITTLE_ENDIAN = fails(function(){
    return new Uint8Array(new Uint16Array([1]).buffer)[0] === 1;
  });

  var FORCED_SET = !!Uint8Array && !!Uint8Array[PROTOTYPE].set && fails(function(){
    new Uint8Array(1).set({});
  });

  var strictToLength = function(it, SAME){
    if(it === undefined)throw TypeError(WRONG_LENGTH);
    var number = +it
      , length = toLength(it);
    if(SAME && !same(number, length))throw RangeError(WRONG_LENGTH);
    return length;
  };

  var toOffset = function(it, BYTES){
    var offset = toInteger(it);
    if(offset < 0 || offset % BYTES)throw RangeError('Wrong offset!');
    return offset;
  };

  var validate = function(it){
    if(isObject(it) && TYPED_ARRAY in it)return it;
    throw TypeError(it + ' is not a typed array!');
  };

  var allocate = function(C, length){
    if(!(isObject(C) && TYPED_CONSTRUCTOR in C)){
      throw TypeError('It is not a typed array constructor!');
    } return new C(length);
  };

  var speciesFromList = function(O, list){
    return fromList(speciesConstructor(O, O[DEF_CONSTRUCTOR]), list);
  };

  var fromList = function(C, list){
    var index  = 0
      , length = list.length
      , result = allocate(C, length);
    while(length > index)result[index] = list[index++];
    return result;
  };

  var addGetter = function(it, key, internal){
    dP(it, key, {get: function(){ return this._d[internal]; }});
  };

  var $from = function from(source /*, mapfn, thisArg */){
    var O       = toObject(source)
      , aLen    = arguments.length
      , mapfn   = aLen > 1 ? arguments[1] : undefined
      , mapping = mapfn !== undefined
      , iterFn  = getIterFn(O)
      , i, length, values, result, step, iterator;
    if(iterFn != undefined && !isArrayIter(iterFn)){
      for(iterator = iterFn.call(O), values = [], i = 0; !(step = iterator.next()).done; i++){
        values.push(step.value);
      } O = values;
    }
    if(mapping && aLen > 2)mapfn = ctx(mapfn, arguments[2], 2);
    for(i = 0, length = toLength(O.length), result = allocate(this, length); length > i; i++){
      result[i] = mapping ? mapfn(O[i], i) : O[i];
    }
    return result;
  };

  var $of = function of(/*...items*/){
    var index  = 0
      , length = arguments.length
      , result = allocate(this, length);
    while(length > index)result[index] = arguments[index++];
    return result;
  };

  // iOS Safari 6.x fails here
  var TO_LOCALE_BUG = !!Uint8Array && fails(function(){ arrayToLocaleString.call(new Uint8Array(1)); });

  var $toLocaleString = function toLocaleString(){
    return arrayToLocaleString.apply(TO_LOCALE_BUG ? arraySlice.call(validate(this)) : validate(this), arguments);
  };

  var proto = {
    copyWithin: function copyWithin(target, start /*, end */){
      return arrayCopyWithin.call(validate(this), target, start, arguments.length > 2 ? arguments[2] : undefined);
    },
    every: function every(callbackfn /*, thisArg */){
      return arrayEvery(validate(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);
    },
    fill: function fill(value /*, start, end */){ // eslint-disable-line no-unused-vars
      return arrayFill.apply(validate(this), arguments);
    },
    filter: function filter(callbackfn /*, thisArg */){
      return speciesFromList(this, arrayFilter(validate(this), callbackfn,
        arguments.length > 1 ? arguments[1] : undefined));
    },
    find: function find(predicate /*, thisArg */){
      return arrayFind(validate(this), predicate, arguments.length > 1 ? arguments[1] : undefined);
    },
    findIndex: function findIndex(predicate /*, thisArg */){
      return arrayFindIndex(validate(this), predicate, arguments.length > 1 ? arguments[1] : undefined);
    },
    forEach: function forEach(callbackfn /*, thisArg */){
      arrayForEach(validate(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);
    },
    indexOf: function indexOf(searchElement /*, fromIndex */){
      return arrayIndexOf(validate(this), searchElement, arguments.length > 1 ? arguments[1] : undefined);
    },
    includes: function includes(searchElement /*, fromIndex */){
      return arrayIncludes(validate(this), searchElement, arguments.length > 1 ? arguments[1] : undefined);
    },
    join: function join(separator){ // eslint-disable-line no-unused-vars
      return arrayJoin.apply(validate(this), arguments);
    },
    lastIndexOf: function lastIndexOf(searchElement /*, fromIndex */){ // eslint-disable-line no-unused-vars
      return arrayLastIndexOf.apply(validate(this), arguments);
    },
    map: function map(mapfn /*, thisArg */){
      return $map(validate(this), mapfn, arguments.length > 1 ? arguments[1] : undefined);
    },
    reduce: function reduce(callbackfn /*, initialValue */){ // eslint-disable-line no-unused-vars
      return arrayReduce.apply(validate(this), arguments);
    },
    reduceRight: function reduceRight(callbackfn /*, initialValue */){ // eslint-disable-line no-unused-vars
      return arrayReduceRight.apply(validate(this), arguments);
    },
    reverse: function reverse(){
      var that   = this
        , length = validate(that).length
        , middle = Math.floor(length / 2)
        , index  = 0
        , value;
      while(index < middle){
        value         = that[index];
        that[index++] = that[--length];
        that[length]  = value;
      } return that;
    },
    some: function some(callbackfn /*, thisArg */){
      return arraySome(validate(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);
    },
    sort: function sort(comparefn){
      return arraySort.call(validate(this), comparefn);
    },
    subarray: function subarray(begin, end){
      var O      = validate(this)
        , length = O.length
        , $begin = toIndex(begin, length);
      return new (speciesConstructor(O, O[DEF_CONSTRUCTOR]))(
        O.buffer,
        O.byteOffset + $begin * O.BYTES_PER_ELEMENT,
        toLength((end === undefined ? length : toIndex(end, length)) - $begin)
      );
    }
  };

  var $slice = function slice(start, end){
    return speciesFromList(this, arraySlice.call(validate(this), start, end));
  };

  var $set = function set(arrayLike /*, offset */){
    validate(this);
    var offset = toOffset(arguments[1], 1)
      , length = this.length
      , src    = toObject(arrayLike)
      , len    = toLength(src.length)
      , index  = 0;
    if(len + offset > length)throw RangeError(WRONG_LENGTH);
    while(index < len)this[offset + index] = src[index++];
  };

  var $iterators = {
    entries: function entries(){
      return arrayEntries.call(validate(this));
    },
    keys: function keys(){
      return arrayKeys.call(validate(this));
    },
    values: function values(){
      return arrayValues.call(validate(this));
    }
  };

  var isTAIndex = function(target, key){
    return isObject(target)
      && target[TYPED_ARRAY]
      && typeof key != 'symbol'
      && key in target
      && String(+key) == String(key);
  };
  var $getDesc = function getOwnPropertyDescriptor(target, key){
    return isTAIndex(target, key = toPrimitive(key, true))
      ? propertyDesc(2, target[key])
      : gOPD(target, key);
  };
  var $setDesc = function defineProperty(target, key, desc){
    if(isTAIndex(target, key = toPrimitive(key, true))
      && isObject(desc)
      && has(desc, 'value')
      && !has(desc, 'get')
      && !has(desc, 'set')
      // TODO: add validation descriptor w/o calling accessors
      && !desc.configurable
      && (!has(desc, 'writable') || desc.writable)
      && (!has(desc, 'enumerable') || desc.enumerable)
    ){
      target[key] = desc.value;
      return target;
    } else return dP(target, key, desc);
  };

  if(!ALL_CONSTRUCTORS){
    $GOPD.f = $getDesc;
    $DP.f   = $setDesc;
  }

  $export($export.S + $export.F * !ALL_CONSTRUCTORS, 'Object', {
    getOwnPropertyDescriptor: $getDesc,
    defineProperty:           $setDesc
  });

  if(fails(function(){ arrayToString.call({}); })){
    arrayToString = arrayToLocaleString = function toString(){
      return arrayJoin.call(this);
    }
  }

  var $TypedArrayPrototype$ = redefineAll({}, proto);
  redefineAll($TypedArrayPrototype$, $iterators);
  hide($TypedArrayPrototype$, ITERATOR, $iterators.values);
  redefineAll($TypedArrayPrototype$, {
    slice:          $slice,
    set:            $set,
    constructor:    function(){ /* noop */ },
    toString:       arrayToString,
    toLocaleString: $toLocaleString
  });
  addGetter($TypedArrayPrototype$, 'buffer', 'b');
  addGetter($TypedArrayPrototype$, 'byteOffset', 'o');
  addGetter($TypedArrayPrototype$, 'byteLength', 'l');
  addGetter($TypedArrayPrototype$, 'length', 'e');
  dP($TypedArrayPrototype$, TAG, {
    get: function(){ return this[TYPED_ARRAY]; }
  });

  module.exports = function(KEY, BYTES, wrapper, CLAMPED){
    CLAMPED = !!CLAMPED;
    var NAME       = KEY + (CLAMPED ? 'Clamped' : '') + 'Array'
      , ISNT_UINT8 = NAME != 'Uint8Array'
      , GETTER     = 'get' + KEY
      , SETTER     = 'set' + KEY
      , TypedArray = global[NAME]
      , Base       = TypedArray || {}
      , TAC        = TypedArray && getPrototypeOf(TypedArray)
      , FORCED     = !TypedArray || !$typed.ABV
      , O          = {}
      , TypedArrayPrototype = TypedArray && TypedArray[PROTOTYPE];
    var getter = function(that, index){
      var data = that._d;
      return data.v[GETTER](index * BYTES + data.o, LITTLE_ENDIAN);
    };
    var setter = function(that, index, value){
      var data = that._d;
      if(CLAMPED)value = (value = Math.round(value)) < 0 ? 0 : value > 0xff ? 0xff : value & 0xff;
      data.v[SETTER](index * BYTES + data.o, value, LITTLE_ENDIAN);
    };
    var addElement = function(that, index){
      dP(that, index, {
        get: function(){
          return getter(this, index);
        },
        set: function(value){
          return setter(this, index, value);
        },
        enumerable: true
      });
    };
    if(FORCED){
      TypedArray = wrapper(function(that, data, $offset, $length){
        anInstance(that, TypedArray, NAME, '_d');
        var index  = 0
          , offset = 0
          , buffer, byteLength, length, klass;
        if(!isObject(data)){
          length     = strictToLength(data, true)
          byteLength = length * BYTES;
          buffer     = new $ArrayBuffer(byteLength);
        } else if(data instanceof $ArrayBuffer || (klass = classof(data)) == ARRAY_BUFFER || klass == SHARED_BUFFER){
          buffer = data;
          offset = toOffset($offset, BYTES);
          var $len = data.byteLength;
          if($length === undefined){
            if($len % BYTES)throw RangeError(WRONG_LENGTH);
            byteLength = $len - offset;
            if(byteLength < 0)throw RangeError(WRONG_LENGTH);
          } else {
            byteLength = toLength($length) * BYTES;
            if(byteLength + offset > $len)throw RangeError(WRONG_LENGTH);
          }
          length = byteLength / BYTES;
        } else if(TYPED_ARRAY in data){
          return fromList(TypedArray, data);
        } else {
          return $from.call(TypedArray, data);
        }
        hide(that, '_d', {
          b: buffer,
          o: offset,
          l: byteLength,
          e: length,
          v: new $DataView(buffer)
        });
        while(index < length)addElement(that, index++);
      });
      TypedArrayPrototype = TypedArray[PROTOTYPE] = create($TypedArrayPrototype$);
      hide(TypedArrayPrototype, 'constructor', TypedArray);
    } else if(!$iterDetect(function(iter){
      // V8 works with iterators, but fails in many other cases
      // https://code.google.com/p/v8/issues/detail?id=4552
      new TypedArray(null); // eslint-disable-line no-new
      new TypedArray(iter); // eslint-disable-line no-new
    }, true)){
      TypedArray = wrapper(function(that, data, $offset, $length){
        anInstance(that, TypedArray, NAME);
        var klass;
        // `ws` module bug, temporarily remove validation length for Uint8Array
        // https://github.com/websockets/ws/pull/645
        if(!isObject(data))return new Base(strictToLength(data, ISNT_UINT8));
        if(data instanceof $ArrayBuffer || (klass = classof(data)) == ARRAY_BUFFER || klass == SHARED_BUFFER){
          return $length !== undefined
            ? new Base(data, toOffset($offset, BYTES), $length)
            : $offset !== undefined
              ? new Base(data, toOffset($offset, BYTES))
              : new Base(data);
        }
        if(TYPED_ARRAY in data)return fromList(TypedArray, data);
        return $from.call(TypedArray, data);
      });
      arrayForEach(TAC !== Function.prototype ? gOPN(Base).concat(gOPN(TAC)) : gOPN(Base), function(key){
        if(!(key in TypedArray))hide(TypedArray, key, Base[key]);
      });
      TypedArray[PROTOTYPE] = TypedArrayPrototype;
      if(!LIBRARY)TypedArrayPrototype.constructor = TypedArray;
    }
    var $nativeIterator   = TypedArrayPrototype[ITERATOR]
      , CORRECT_ITER_NAME = !!$nativeIterator && ($nativeIterator.name == 'values' || $nativeIterator.name == undefined)
      , $iterator         = $iterators.values;
    hide(TypedArray, TYPED_CONSTRUCTOR, true);
    hide(TypedArrayPrototype, TYPED_ARRAY, NAME);
    hide(TypedArrayPrototype, VIEW, true);
    hide(TypedArrayPrototype, DEF_CONSTRUCTOR, TypedArray);

    if(CLAMPED ? new TypedArray(1)[TAG] != NAME : !(TAG in TypedArrayPrototype)){
      dP(TypedArrayPrototype, TAG, {
        get: function(){ return NAME; }
      });
    }

    O[NAME] = TypedArray;

    $export($export.G + $export.W + $export.F * (TypedArray != Base), O);

    $export($export.S, NAME, {
      BYTES_PER_ELEMENT: BYTES,
      from: $from,
      of: $of
    });

    if(!(BYTES_PER_ELEMENT in TypedArrayPrototype))hide(TypedArrayPrototype, BYTES_PER_ELEMENT, BYTES);

    $export($export.P, NAME, proto);

    setSpecies(NAME);

    $export($export.P + $export.F * FORCED_SET, NAME, {set: $set});

    $export($export.P + $export.F * !CORRECT_ITER_NAME, NAME, $iterators);

    $export($export.P + $export.F * (TypedArrayPrototype.toString != arrayToString), NAME, {toString: arrayToString});

    $export($export.P + $export.F * fails(function(){
      new TypedArray(1).slice();
    }), NAME, {slice: $slice});

    $export($export.P + $export.F * (fails(function(){
      return [1, 2].toLocaleString() != new TypedArray([1, 2]).toLocaleString()
    }) || !fails(function(){
      TypedArrayPrototype.toLocaleString.call([1, 2]);
    })), NAME, {toLocaleString: $toLocaleString});

    Iterators[NAME] = CORRECT_ITER_NAME ? $nativeIterator : $iterator;
    if(!LIBRARY && !CORRECT_ITER_NAME)hide(TypedArrayPrototype, ITERATOR, $iterator);
  };
} else module.exports = function(){ /* empty */ };

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _iconset = __webpack_require__(10);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

var hidden = true;
var showNotes = false;
var _pin = false;
var left = 0;
var top = 0;
var hookName = null;
var newHookName = null;

var DataNotes = _component2.default.extend({

  init: function init(config, context) {
    var _this = this;

    this.name = 'gapminder-datanotes';

    this.model_expects = [{
      name: "marker",
      type: "model"
    }, {
      name: "locale",
      type: "locale"
    }];

    this.context = context;

    this.model_binds = {
      "translate:locale": function translateLocale(evt) {
        if (!_this._ready || !_this._readyOnce) return;
        _this.ready();
      }
    };

    //contructor is the same as any component
    this._super(config, context);

    this.close = this.close.bind(this);
  },

  ready: function ready() {
    this.setValues();
  },

  readyOnce: function readyOnce() {
    var _this = this;

    this.translator = this.model.locale.getTFunction();
    this.element = d3.select(this.placeholder);

    this.element.selectAll("div").remove();

    var container = this.element;

    container.append("div").html(_iconset.close).on("click", function () {
      d3.event.stopPropagation();
      _this.close();
    }).select("svg").attr("width", "0px").attr("height", "0px").attr("class", "vzb-data-notes-close").classed('vzb-hidden', true);

    container.append("div").attr("class", "vzb-data-notes-body vzb-dialog-scrollable");

    container.append("div").attr("class", "vzb-data-notes-link");
  },

  resize: function resize() {
    this.close();
  },

  close: function close() {
    if (!hidden) {
      this.pin(false).hide();
    }
  },

  setHook: function setHook(_hookName) {
    if (!this._readyOnce) return this;
    if (_pin) {
      newHookName = _hookName;
      return this;
    }
    if (hookName) this.model.marker[hookName].off('change:which', this.close);
    hookName = newHookName = _hookName;
    this.model.marker[hookName].on('change:which', this.close);

    this.setValues();

    return this;
  },

  setValues: function setValues() {
    if (!hookName) return;
    var hook = this.model.marker[hookName];
    var concept = hook.getConceptprops();

    this.element.select('.vzb-data-notes-body').classed('vzb-hidden', !concept.description).text(concept.description || "");

    this.element.select('.vzb-data-notes-link').classed('vzb-hidden', !concept.sourceLink);

    if (concept.sourceLink) {
      var _source = this.translator('hints/source');
      var sourceName = concept.sourceName || "";
      this.element.select('.vzb-data-notes-link').html('<span>' + (sourceName ? _source + ':' : '') + '<a href="' + concept.sourceLink + '" target="_blank">' + (sourceName ? sourceName : _source) + '</a></span>');
    }
    showNotes = concept.sourceLink || concept.description;
  },

  setPos: function setPos(_left, _top, force) {
    left = _left;
    top = _top;
    if (_pin && !force) return this;
    var parentHeight = this.parent.element.offsetHeight;
    var width = this.element.node().offsetWidth;
    var height = this.element.node().offsetHeight;
    var leftMove;
    var topMove;
    var leftPos = left - width;
    var topPos = top;
    if (leftPos < 10) {
      leftPos = 10;
      leftMove = true;
    }
    if (topPos + height + 10 > parentHeight) {
      topPos = parentHeight - height - 10;
      topMove = true;
    }

    if (leftMove && topMove) {
      topPos = top - height - 30;
    }

    this.element.style({ 'top': topPos + 'px', 'left': leftPos + 'px' });

    return this;
  },

  pin: function pin(arg) {
    if (hidden) return this;
    _pin = !_pin;
    if (arg != null) _pin = arg;
    this.element.select('.vzb-data-notes-close').classed('vzb-hidden', !_pin);
    this.element.classed('vzb-data-notes-pinned', _pin);
    if (hookName != newHookName) this.setHook(newHookName);
    this.element.select('.vzb-data-notes-body').node().scrollTop = 0;
    if (!showNotes) {
      return this.hide();
    } else {
      return this.setPos(left, top, true);
    }
  },

  toggle: function toggle(arg) {
    if (_pin || !hookName) return this;
    if (arg == null) arg = !hidden;
    hidden = arg;
    this.element.classed("vzb-hidden", hidden || !showNotes);
    return this;
  },

  show: function show() {
    return this.toggle(false);
  },

  hide: function hide() {
    return this.toggle(true);
  }

});

exports.default = DataNotes;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _iconset = __webpack_require__(10);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

var hidden = true;

var DataWarning = _component2.default.extend({

  init: function init(config, context) {
    var _this = this;

    this.name = 'gapminder-datawarning';

    this.model_expects = [{
      name: "locale",
      type: "locale"
    }];

    this.context = context;

    this.model_binds = {
      "translate:locale": function translateLocale(evt) {
        if (!_this._ready) return;
        _this.redraw();
      }
    };

    //contructor is the same as any component
    this._super(config, context);
  },

  ready: function ready() {
    this.redraw();
  },

  readyOnce: function readyOnce() {
    var _this = this;
    this.element = d3.select(this.placeholder);

    this.element.selectAll("div").remove();

    this.element.append("div").attr("class", "vzb-data-warning-background").on("click", function () {
      _this.toggle(true);
    });

    this.container = this.element.append("div").attr("class", "vzb-data-warning-box");

    this.container.append("div").html(_iconset.close).on("click", function () {
      _this.toggle();
    }).select("svg").attr("width", "0px").attr("height", "0px").attr("class", "vzb-data-warning-close");

    var icon = this.container.append("div").attr("class", "vzb-data-warning-link").html(_iconset.warn);

    icon.append("div");

    this.container.append("div").attr("class", "vzb-data-warning-title");

    this.container.append("div").attr("class", "vzb-data-warning-body vzb-dialog-scrollable");
  },

  redraw: function redraw() {
    this.translator = this.model.locale.getTFunction();

    this.container.select(".vzb-data-warning-link div").text(this.translator("hints/dataWarning"));

    var title = this.translator("datawarning/title/" + this.parent.name);
    this.container.select(".vzb-data-warning-title").html(title).classed("vzb-hidden", !title || title == "datawarning/title/" + this.parent.name);

    this.container.select(".vzb-data-warning-body").html(this.translator("datawarning/body/" + this.parent.name));
  },

  toggle: function toggle(arg) {
    if (arg == null) arg = !hidden;
    hidden = arg;
    this.element.classed("vzb-hidden", hidden);

    var _this = this;
    this.parent.components.forEach(function (c) {
      c.element.classed("vzb-blur", c != _this && !hidden);
    });
  }

});

exports.default = DataWarning;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = axisSmart;

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

//d3.svg.axisSmart

function axisSmart() {

  return function d3_axis_smart(_super) {

    var VERTICAL = 'vertical axis';
    var HORIZONTAL = 'horizontal axis';
    var X = 'labels stack side by side';
    var Y = 'labels stack top to bottom';

    var OPTIMISTIC = 'optimistic approximation: labels have different lengths';
    var PESSIMISTIC = 'pessimistic approximation: all labels have the largest length';
    var DEFAULT_LOGBASE = 10;

    function onlyUnique(value, index, self) {
      return self.indexOf(value) === index;
    }

    function axis(g) {
      var checkDmn = axis.scale().domain();
      var checkRng = axis.scale().range();
      if (!checkDmn[0] && checkDmn[0] !== 0 || !checkDmn[1] && checkDmn[1] !== 0 || !checkRng[0] && checkRng[0] !== 0 || !checkRng[1] && checkRng[1] !== 0) {
        return utils.warn("d3.svg.axisSmart() skips action because of invalid domain " + JSON.stringify(checkDmn) + " or range " + JSON.stringify(checkRng) + " of the attached scale");
      }

      if (highlightValue != null) {
        axis.highlightValueRun(g);
        return;
      }

      // measure the width and height of one digit
      var widthSampleG = g.append("g").attr("class", "tick widthSampling");
      var widthSampleT = widthSampleG.append('text').text('0');
      if (!options.cssMargin) options.cssMargin = {};
      options.cssMargin.top = widthSampleT.style("margin-top");
      options.cssMargin.bottom = widthSampleT.style("margin-bottom");
      options.cssMargin.left = widthSampleT.style("margin-left");
      options.cssMargin.right = widthSampleT.style("margin-right");
      options.widthOfOneDigit = widthSampleT[0][0].getBBox().width;
      options.heightOfOneDigit = widthSampleT[0][0].getBBox().height;
      widthSampleG.remove();

      // run label factory - it will store labels in tickValues property of axis
      axis.labelFactory(options);

      // construct the view (d3 constructor is used)
      if (options.transitionDuration > 0) {
        _super(g.transition().duration(options.transitionDuration));
      } else {
        _super(g);
      }

      //identify the orientation of axis and the direction of labels
      var orient = axis.orient() == "top" || axis.orient() == "bottom" ? HORIZONTAL : VERTICAL;
      var dimension = orient == HORIZONTAL && axis.pivot() || orient == VERTICAL && !axis.pivot() ? Y : X;

      //add an invisible element that would represent hovered value
      g.selectAll('.vzb-axis-value').data([null]).enter().append('g').attr("class", 'vzb-axis-value').classed("vzb-hidden", true).append("text");

      // patch the label positioning after the view is generated
      var padding = axis.tickPadding();
      g.selectAll("text").each(function (d, i) {
        if (axis.pivot() == null) return;

        var view = d3.select(this);
        view.attr("transform", "rotate(" + (axis.pivot() ? -90 : 0) + ")");
        view.style("text-anchor", dimension == X ? "middle" : "end");
        view.attr("x", dimension == X ? orient == VERTICAL ? -padding : 0 : -padding);
        view.attr("y", dimension == X ? orient == VERTICAL ? 0 : padding : 0);
        view.attr("dx", dimension == X ? orient == VERTICAL ? padding : 0 : 0);
        view.attr("dy", dimension == X ? orient == VERTICAL ? -padding : ".72em" : ".32em");
      });

      //apply label repositioning: first and last visible values would shift away from the borders
      if (axis.repositionLabels() != null) {
        g.selectAll(".tick").each(function (d) {
          var view = d3.select(this).select("text");
          var shift = axis.repositionLabels()[d] || { x: 0, y: 0 };
          view.attr("x", +view.attr("x") + shift.x);
          view.attr("y", +view.attr("y") + shift.y);
        });
      }

      //hide axis labels that are outside the available viewport
      var scale = axis.scale();
      if (options.viewportLength) {
        g.selectAll(".tick").classed("vzb-hidden", function (d) {
          return scale(d) < 0 || scale(d) > options.viewportLength;
        });
      }

      // add minor ticks. if none exist add an empty array
      if (axis.tickValuesMinor() == null) axis.tickValuesMinor([]);
      var minorTicks = g.selectAll(".tick-minor").data(tickValuesMinor);
      minorTicks.exit().remove();
      minorTicks.enter().append("line").attr("class", "tick-minor");

      var tickLengthOut = axis.tickSizeMinor().outbound;
      var tickLengthIn = axis.tickSizeMinor().inbound;
      minorTicks.classed("vzb-hidden", function (d) {
        return scale(d) < 0 || scale(d) > options.viewportLength;
      }).attr("y1", orient == HORIZONTAL ? (axis.orient() == "top" ? 1 : -1) * tickLengthIn : scale).attr("y2", orient == HORIZONTAL ? (axis.orient() == "top" ? -1 : 1) * tickLengthOut : scale).attr("x1", orient == VERTICAL ? (axis.orient() == "right" ? -1 : 1) * tickLengthIn : scale).attr("x2", orient == VERTICAL ? (axis.orient() == "right" ? 1 : -1) * tickLengthOut : scale);

      //adjust axis rake 
      g.selectAll("path").remove();
      var rake = g.selectAll(".vzb-axis-line").data([0]);
      rake.exit().remove();
      rake.enter().append("line").attr("class", "vzb-axis-line");

      if (options.viewportLength) {
        rake.attr("x1", orient == VERTICAL ? 0 : -1).attr("x2", orient == VERTICAL ? 0 : options.viewportLength).attr("y1", orient == HORIZONTAL ? 0 : 0).attr("y2", orient == HORIZONTAL ? 0 : options.viewportLength);
      } else {
        //TODO: this will not work for the "ordinal" scaleType
        rake.attr("x1", orient == VERTICAL ? 0 : d3.min(scale.range()) - (options.bump || 0) - 1).attr("x2", orient == VERTICAL ? 0 : d3.max(scale.range()) + (options.bump || 0)).attr("y1", orient == HORIZONTAL ? 0 : d3.min(scale.range()) - (options.bump || 0)).attr("y2", orient == HORIZONTAL ? 0 : d3.max(scale.range()) + (options.bump || 0));
      }
    };

    axis.highlightValueRun = function (g) {

      //if viewport is defined and HL value is outside then behave as reset HL
      if (options.viewportLength && highlightValue != "none" && (axis.scale()(highlightValue) > options.viewportLength || axis.scale()(highlightValue) < 0)) highlightValue = "none";

      //identify the orientation of axis and the direction of labels
      var orient = axis.orient() == "top" || axis.orient() == "bottom" ? HORIZONTAL : VERTICAL;
      var dimension = orient == HORIZONTAL && axis.pivot() || orient == VERTICAL && !axis.pivot() ? "y" : "x";
      var pivot = axis.pivot() ? -1 : 1;

      //set content and visibility of HL value
      g.select('.vzb-axis-value').classed("vzb-hidden", highlightValue == "none");

      var bbox;
      var o = {};

      if (highlightValue != "none") {
        // measure its width and height for collision resolving
        bbox = g.select('.vzb-axis-value').node().getBBox();

        // clone a known options object (because we don't want to overwrite widthOfOneDigit / heightOfOneDigit in the original one
        o.bump = options.bump;
        o.formatter = options.formatter;
        o.viewportLength = options.viewportLength;
        o.toolMargin = options.toolMargin;
        o.cssMargin = options.cssMargin;
        o.widthOfOneDigit = bbox[axis.pivot() ? "height" : "width"] / options.formatter(highlightValue).length;
        o.heightOfOneDigit = bbox[axis.pivot() ? "width" : "height"];
      }

      // this will give additive shifting for the hovered value in case it sticks out a little outside viewport
      var hlValueShift = (highlightValue == "none" ? { x: 0, y: 0 } : repositionLabelsThatStickOut([highlightValue], o, orient, axis.scale(), dimension)[highlightValue])[dimension];

      // this function will help to move the hovered value to the right place
      var getTransform = function getTransform(d) {
        return highlightValue == "none" ? "translate(0,0)" : "translate(" + (orient == HORIZONTAL ? axis.scale()(highlightValue) + hlValueShift * pivot : 0) + "," + (orient == VERTICAL ? axis.scale()(highlightValue) + hlValueShift * pivot : 0) + ")";
      };

      // this function will help to compute opacity for the axis labels that would overlap with the HL label
      var getOpacity = function getOpacity(d, t, view) {
        if (highlightValue == "none") return 1;

        var wh = orient == HORIZONTAL ? "width" : "height";
        var shift = (axis.repositionLabels()[d] || { x: 0, y: 0 })[dimension];

        // opacity depends on the collision between label's boundary boxes
        return axis.hlOpacityScale()(
        // this computes the distance between the box centers, this is a 1-d problem because all labels are along the axis
        // shifts of labels that stick out from the viewport are also taken into account
        Math.abs(axis.scale()(d) + shift * pivot - axis.scale()(highlightValue) - hlValueShift * pivot)
        // this computes the sides of boundary boxes, each has a half-size to reduce the distance between centers
        - view.getBBox()[wh] / 2 - bbox[wh] / 2);
      };

      // apply translation of the HL value and opacity of tick labels
      if (highlightTransDuration) {
        g.select('.vzb-axis-value').transition().duration(highlightTransDuration).ease("linear").attr("transform", getTransform);

        g.select('.vzb-axis-value').select("text").transition("text").delay(highlightTransDuration).text(highlightValue == "none" ? "" : options.formatter(highlightValue));

        g.selectAll(".tick:not(.vzb-hidden)").each(function (d, t) {
          d3.select(this).select("text").transition().duration(highlightTransDuration).ease("linear").style("opacity", getOpacity(d, t, this));
        });
      } else {
        g.select('.vzb-axis-value').interrupt().attr("transform", getTransform).transition();

        g.select('.vzb-axis-value').select("text").interrupt().text(highlightValue == "none" ? "" : options.formatter(highlightValue)).transition();

        g.selectAll(".tick:not(.vzb-hidden)").each(function (d, t) {
          d3.select(this).select("text").interrupt().style("opacity", getOpacity(d, t, this)).transition();
        });
      }

      highlightValue = null;
    };

    var hlOpacityScale = d3.scale.linear().domain([0, 5]).range([0, 1]).clamp(true);
    axis.hlOpacityScale = function (arg) {
      if (!arguments.length) return hlOpacityScale;
      hlOpacityScale = arg;
      return axis;
    };

    var highlightValue = null;
    axis.highlightValue = function (arg) {
      if (!arguments.length) return highlightValue;
      highlightValue = arg;
      return axis;
    };

    var highlightTransDuration = 0;
    axis.highlightTransDuration = function (arg) {
      if (!arguments.length) return highlightTransDuration;
      highlightTransDuration = arg;
      return axis;
    };

    var repositionLabels = null;
    axis.repositionLabels = function (arg) {
      if (!arguments.length) return repositionLabels;
      repositionLabels = arg;
      return axis;
    };

    var pivot = false;
    axis.pivot = function (arg) {
      if (!arguments.length) return pivot;
      pivot = !!arg;
      return axis;
    };

    var tickValuesMinor = [];
    axis.tickValuesMinor = function (arg) {
      if (!arguments.length) return tickValuesMinor;
      tickValuesMinor = arg;
      return axis;
    };

    var tickSizeMinor = {
      outbound: 0,
      inbound: 0
    };
    axis.tickSizeMinor = function (arg1, arg2) {
      if (!arguments.length) return tickSizeMinor;
      tickSizeMinor = {
        outbound: arg1,
        inbound: arg2 || 0
      };
      meow("setting", tickSizeMinor);
      return axis;
    };

    var options = {};
    axis.labelerOptions = function (arg) {
      if (!arguments.length) return options;
      options = arg;
      return axis;
    };

    axis.METHOD_REPEATING = 'repeating specified powers';
    axis.METHOD_DOUBLING = 'doubling the value';

    axis.labelFactory = function (options) {
      if (options == null) options = {};
      if (options.scaleType != "linear" && options.scaleType != "time" && options.scaleType != "genericLog" && options.scaleType != "log" && options.scaleType != "ordinal") {
        return axis.ticks(ticksNumber).tickFormat(null).tickValues(null).tickValuesMinor(null).pivot(null).repositionLabels(null);
      };
      if (options.scaleType == 'ordinal') return axis.tickValues(null);

      if (options.logBase == null) options.logBase = DEFAULT_LOGBASE;
      if (options.stops == null) options.stops = [1, 2, 5, 3, 7, 4, 6, 8, 9];

      if (options.removeAllLabels == null) options.removeAllLabels = false;

      if (options.formatter == null) options.formatter = axis.tickFormat() ? axis.tickFormat() : function (d) {
        return d + "";
      };
      options.cssLabelMarginLimit = 5; //px

      if (options.cssMargin == null) options.cssMargin = {};
      if (options.cssMargin.left == null || parseInt(options.cssMargin.left) < options.cssLabelMarginLimit) options.cssMargin.left = options.cssLabelMarginLimit + "px";
      if (options.cssMargin.right == null || parseInt(options.cssMargin.right) < options.cssLabelMarginLimit) options.cssMargin.right = options.cssLabelMarginLimit + "px";
      if (options.cssMargin.top == null || parseInt(options.cssMargin.top) < options.cssLabelMarginLimit) options.cssMargin.top = options.cssLabelMarginLimit + "px";
      if (options.cssMargin.bottom == null || parseInt(options.cssMargin.bottom) < options.cssLabelMarginLimit) options.cssMargin.bottom = options.cssLabelMarginLimit + "px";
      if (options.toolMargin == null) options.toolMargin = {
        left: 30,
        bottom: 30,
        right: 30,
        top: 30
      };
      if (options.bump == null) options.bump = 0;
      if (options.viewportLength == null) options.viewportLength = 0;

      if (options.pivotingLimit == null) options.pivotingLimit = options.toolMargin[this.orient()];

      if (options.showOuter == null) options.showOuter = false;
      if (options.limitMaxTickNumber == null) options.limitMaxTickNumber = 0; //0 is unlimited

      var orient = this.orient() == "top" || this.orient() == "bottom" ? HORIZONTAL : VERTICAL;

      if (options.isPivotAuto == null) options.isPivotAuto = orient == VERTICAL;

      if (options.cssFontSize == null) options.cssFontSize = "13px";
      if (options.widthToFontsizeRatio == null) options.widthToFontsizeRatio = .75;
      if (options.heightToFontsizeRatio == null) options.heightToFontsizeRatio = 1.20;
      if (options.widthOfOneDigit == null) options.widthOfOneDigit = parseInt(options.cssFontSize) * options.widthToFontsizeRatio;
      if (options.heightOfOneDigit == null) options.heightOfOneDigit = parseInt(options.cssFontSize) * options.heightToFontsizeRatio;
      if (options.fitIntoScale == null || options.fitIntoScale == 'pessimistic') options.fitIntoScale = PESSIMISTIC;
      if (options.fitIntoScale == 'optimistic') options.fitIntoScale = OPTIMISTIC;

      meow("********** " + orient + " **********");

      var domain = axis.scale().domain();
      var range = axis.scale().range();
      var lengthDomain = Math.abs(domain[domain.length - 1] - domain[0]);
      var lengthRange = Math.abs(range[range.length - 1] - range[0]);

      var min = d3.min([domain[0], domain[domain.length - 1]]);
      var max = d3.max([domain[0], domain[domain.length - 1]]);
      var bothSidesUsed = min <= 0 && max >= 0 && options.scaleType != "time";

      var tickValues = options.showOuter ? [min, max] : [];
      var tickValuesMinor = []; //[min, max];
      var ticksNumber = 5;

      function getBaseLog(x, base) {
        if (x == 0 || base == 0) {
          return 0;
        }
        if (base == null) base = options.logBase;
        return Math.log(x) / Math.log(base);
      };

      // estimate the longest formatted label in pixels
      var estLongestLabelLength =
      //take 17 sample values and measure the longest formatted label
      d3.max(d3.range(min, max, (max - min) / 17).concat(max).map(function (d) {
        return options.formatter(d).length;
      })) * options.widthOfOneDigit + parseInt(options.cssMargin.left);

      var pivot = options.isPivotAuto && (estLongestLabelLength + axis.tickPadding() > options.pivotingLimit && orient == VERTICAL || !(estLongestLabelLength + axis.tickPadding() > options.pivotingLimit) && !(orient == VERTICAL));

      var labelsStackOnTop = orient == HORIZONTAL && pivot || orient == VERTICAL && !pivot;

      // conditions to remove labels altogether
      var labelsJustDontFit = !labelsStackOnTop && options.heightOfOneDigit > options.pivotingLimit;
      if (options.removeAllLabels) return axis.tickValues([]);

      // return a single tick if have only one point in the domain
      if (min == max) return axis.tickValues([min]).ticks(1).tickFormat(options.formatter);

      // LABELS FIT INTO SCALE
      // measure if all labels in array tickValues can fit into the allotted lengthRange
      // approximationStyle can be OPTIMISTIC or PESSIMISTIC
      // in optimistic style the length of every label is added up and then we check if the total pack of symbols fit
      // in pessimistic style we assume all labels have the length of the longest label from tickValues
      // returns TRUE if labels fit and FALSE otherwise
      var labelsFitIntoScale = function labelsFitIntoScale(tickValues, lengthRange, approximationStyle, rescalingLabels) {
        if (tickValues == null || tickValues.length <= 1) return true;
        if (approximationStyle == null) approximationStyle = PESSIMISTIC;
        if (rescalingLabels == null) scaleType = "none";

        if (labelsStackOnTop) {
          //labels stack on top of each other. digit height matters
          return lengthRange > tickValues.length * (options.heightOfOneDigit + parseInt(options.cssMargin.top) + parseInt(options.cssMargin.bottom));
        } else {
          //labels stack side by side. label width matters
          var marginsLR = parseInt(options.cssMargin.left) + parseInt(options.cssMargin.right);
          var maxLength = d3.max(tickValues.map(function (d) {
            return options.formatter(d).length;
          }));

          // log scales need to rescale labels, so that 9 takes more space than 2
          if (rescalingLabels == "log") {
            // sometimes only a fragment of axis is used. in this case we want to limit the scope to that fragment
            // yes, this is hacky and experimental
            lengthRange = Math.abs(axis.scale()(d3.max(tickValues)) - axis.scale()(d3.min(tickValues)));

            return lengthRange > d3.sum(tickValues.map(function (d) {
              return (options.widthOfOneDigit * (approximationStyle == PESSIMISTIC ? maxLength : options.formatter(d).length) + marginsLR) * (
              // this is a logarithmic rescaling of labels
              1 + Math.log(d.toString().replace(/([0\.])/g, "")[0]) / Math.LN10);
            }));
          } else {
            return lengthRange + options.toolMargin.left + options.toolMargin.right > tickValues.length * marginsLR + (approximationStyle == PESSIMISTIC ? options.widthOfOneDigit * tickValues.length * maxLength : 0) + (approximationStyle == OPTIMISTIC ? options.widthOfOneDigit * tickValues.map(function (d) {
              return options.formatter(d);
            }).join("").length : 0);
          }
        }
      };

      // COLLISION BETWEEN
      // Check is there is a collision between labels ONE and TWO
      // ONE is a value, TWO can be a value or an array
      // returns TRUE if collision takes place and FALSE otherwise
      var collisionBetween = function collisionBetween(one, two) {
        if (two == null || two.length == 0) return false;
        if (!(two instanceof Array)) two = [two];

        for (var i = 0; i < two.length; i++) {
          if (one != two[i] && one != 0 && Math.abs(axis.scale()(one) - axis.scale()(two[i])) < (labelsStackOnTop ? options.heightOfOneDigit : (options.formatter(one).length + options.formatter(two[i]).length) * options.widthOfOneDigit / 2)) return true;
        }
        return false;
      };

      if (options.scaleType == "genericLog" || options.scaleType == "log") {
        var eps = axis.scale().eps ? axis.scale().eps() : 0;

        var spawnZero = bothSidesUsed ? [0] : [];

        // check if spawn positive is needed. if yes then spawn!
        var spawnPos = max < eps ? [] : d3.range(Math.floor(getBaseLog(Math.max(eps, min))), Math.ceil(getBaseLog(max)), 1).concat(Math.ceil(getBaseLog(max))).map(function (d) {
          return Math.pow(options.logBase, d);
        });

        // check if spawn negative is needed. if yes then spawn!
        var spawnNeg = min > -eps ? [] : d3.range(Math.floor(getBaseLog(Math.max(eps, -max))), Math.ceil(getBaseLog(-min)), 1).concat(Math.ceil(getBaseLog(-min))).map(function (d) {
          return -Math.pow(options.logBase, d);
        });

        // automatic chosing of method if it's not explicitly defined
        if (options.method == null) {
          var coverage = bothSidesUsed ? Math.max(Math.abs(max), Math.abs(min)) / eps : Math.max(Math.abs(max), Math.abs(min)) / Math.min(Math.abs(max), Math.abs(min));
          options.method = 10 <= coverage && coverage <= 1024 ? this.METHOD_DOUBLING : this.METHOD_REPEATING;
        };

        //meow('spawn pos/neg: ', spawnPos, spawnNeg);


        if (options.method == this.METHOD_DOUBLING) {
          var doublingLabels = [];
          if (bothSidesUsed) tickValues.push(0);
          var avoidCollidingWith = [].concat(tickValues);

          // start with the smallest abs number on the scale, rounded to nearest nice power
          //var startPos = max<eps? null : Math.pow(options.logBase, Math.floor(getBaseLog(Math.max(eps,min))));
          //var startNeg = min>-eps? null : -Math.pow(options.logBase, Math.floor(getBaseLog(Math.max(eps,-max))));

          var startPos = max < eps ? null : 4 * spawnPos[Math.floor(spawnPos.length / 2) - 1];
          var startNeg = min > -eps ? null : 4 * spawnNeg[Math.floor(spawnNeg.length / 2) - 1];

          //meow('starter pos/neg: ', startPos, startNeg);

          if (startPos) {
            for (var l = startPos; l <= max; l *= 2) {
              doublingLabels.push(l);
            }
          }
          if (startPos) {
            for (var l = startPos / 2; l >= Math.max(min, eps); l /= 2) {
              doublingLabels.push(l);
            }
          }
          if (startNeg) {
            for (var l = startNeg; l >= min; l *= 2) {
              doublingLabels.push(l);
            }
          }
          if (startNeg) {
            for (var l = startNeg / 2; l <= Math.min(max, -eps); l /= 2) {
              doublingLabels.push(l);
            }
          }

          doublingLabels = doublingLabels.sort(d3.ascending).filter(function (d) {
            return min <= d && d <= max;
          });

          tickValuesMinor = tickValuesMinor.concat(doublingLabels);

          doublingLabels = groupByPriorities(doublingLabels, false); // don't skip taken values

          var tickValues_1 = tickValues;
          for (var j = 0; j < doublingLabels.length; j++) {

            // compose an attempt to add more axis labels
            var trytofit = tickValues_1.concat(doublingLabels[j]).filter(function (d) {
              return !collisionBetween(d, avoidCollidingWith);
            }).filter(onlyUnique);

            // stop populating if labels don't fit
            if (!labelsFitIntoScale(trytofit, lengthRange, PESSIMISTIC, "none")) break;

            // apply changes if no blocking instructions
            tickValues = trytofit;
          }
        }

        if (options.method == this.METHOD_REPEATING) {

          var spawn = spawnZero.concat(spawnPos).concat(spawnNeg).sort(d3.ascending);

          options.stops.forEach(function (stop, i) {
            tickValuesMinor = tickValuesMinor.concat(spawn.map(function (d) {
              return d * stop;
            }));
          });

          spawn = groupByPriorities(spawn);
          var avoidCollidingWith = spawnZero.concat(tickValues);

          var stopTrying = false;

          options.stops.forEach(function (stop, i) {
            if (i == 0) {
              for (var j = 0; j < spawn.length; j++) {

                // compose an attempt to add more axis labels
                var trytofit = tickValues.concat(spawn[j].map(function (d) {
                  return d * stop;
                }))
                // throw away labels that collide with "special" labels 0, min, max
                .filter(function (d) {
                  return !collisionBetween(d, avoidCollidingWith);
                }).filter(function (d) {
                  return min <= d && d <= max;
                }).filter(onlyUnique);

                // stop populating if labels don't fit
                if (!labelsFitIntoScale(trytofit, lengthRange, PESSIMISTIC, "none")) break;

                // apply changes if no blocking instructions
                tickValues = trytofit;
              }

              //flatten the spawn array
              spawn = [].concat.apply([], spawn);
            } else {
              if (stopTrying) return;

              // compose an attempt to add more axis labels
              var trytofit = tickValues.concat(spawn.map(function (d) {
                return d * stop;
              })).filter(function (d) {
                return min <= d && d <= max;
              }).filter(onlyUnique);

              // stop populating if the new composition doesn't fit
              if (!labelsFitIntoScale(trytofit, lengthRange, PESSIMISTIC, "log")) {
                stopTrying = true;
                return;
              }
              // stop populating if the number of labels is limited in options
              if (tickValues.length > options.limitMaxTickNumber && options.limitMaxTickNumber != 0) {
                stopTrying = true;
                return;
              }

              // apply changes if no blocking instructions
              tickValues = trytofit;
            }
          });
        } //method

      } //logarithmic


      if (options.scaleType == "linear" || options.scaleType == "time") {
        if (bothSidesUsed) tickValues.push(0);
        var avoidCollidingWith = [].concat(tickValues);

        if (labelsStackOnTop) {
          ticksNumber = Math.max(Math.floor(lengthRange / (options.heightOfOneDigit + parseInt(options.cssMargin.top))), 2);
        } else {
          ticksNumber = Math.max(Math.floor(lengthRange / estLongestLabelLength), 2);
        }

        // limit maximum ticks number
        if (options.limitMaxTickNumber != 0 && ticksNumber > options.limitMaxTickNumber) ticksNumber = options.limitMaxTickNumber;

        var addLabels = axis.scale().ticks.apply(axis.scale(), [ticksNumber]).sort(d3.ascending).filter(function (d) {
          return min <= d && d <= max;
        });

        tickValuesMinor = tickValuesMinor.concat(addLabels);

        addLabels = groupByPriorities(addLabels, false);

        var tickValues_1 = tickValues;
        for (var j = 0; j < addLabels.length; j++) {

          // compose an attempt to add more axis labels
          var trytofit = tickValues_1.concat(addLabels[j]).filter(function (d) {
            return !collisionBetween(d, avoidCollidingWith);
          }).filter(onlyUnique);

          // stop populating if labels don't fit
          if (!labelsFitIntoScale(trytofit, lengthRange, options.fitIntoScale, "none")) break;

          // apply changes if no blocking instructions
          tickValues = trytofit;
        }

        tickValues = tickValues //.concat(addLabels)
        .filter(function (d) {
          return !collisionBetween(d, avoidCollidingWith);
        }).filter(onlyUnique);
      }

      if (tickValues != null && tickValues.length <= 2 && !bothSidesUsed) tickValues = [min, max];

      if (tickValues != null && tickValues.length <= 3 && bothSidesUsed) {
        if (!collisionBetween(0, [min, max])) {
          tickValues = [min, 0, max];
        } else {
          tickValues = [min, max];
        }
      }

      if (tickValues != null) tickValues.sort(function (a, b) {
        return (orient == HORIZONTAL ? -1 : 1) * (axis.scale()(b) - axis.scale()(a));
      });

      if (labelsJustDontFit) tickValues = [];
      tickValuesMinor = tickValuesMinor.filter(function (d) {
        return tickValues.indexOf(d) == -1 && min <= d && d <= max;
      });

      meow("final result", tickValues);

      return axis.ticks(ticksNumber).tickFormat(options.formatter).tickValues(tickValues).tickValuesMinor(tickValuesMinor).pivot(pivot).repositionLabels(repositionLabelsThatStickOut(tickValues, options, orient, axis.scale(), labelsStackOnTop ? "y" : "x"));
    };

    // GROUP ELEMENTS OF AN ARRAY, SO THAT...
    // less-prio elements are between the high-prio elements
    // Purpose: enable adding axis labels incrementally, like this for 9 labels:
    // PRIO 1: +--------, concat result: +-------- first we show only 1 label
    // PRIO 2: ----+---+, concat result: +---+---+ then we add 2 more, that are maximally spaced
    // PRIO 3: --+---+--, concat result: +-+-+-+-+ then we fill spaces with 2 more labels
    // PRIO 4: -+-+-+-+-, concat result: +++++++++ then we fill the remaing spaces and show all labels
    // exception: zero jumps to the front, if it's on the list
    // example1: [1 2 3 4 5 6 7] --> [[1][4 7][2 3 5 6]]
    // example2: [1 2 3 4 5 6 7 8 9] --> [[1][5 9][3 7][2 4 6 8]]
    // example3: [-4 -3 -2 -1 0 1 2 3 4 5 6 7] --> [[0][-4][2][-1 5][-3 -2 1 3 4 6 7]]
    // inputs:
    // array - the source array to be processed. Only makes sense if sorted
    // removeDuplicates - return incremental groups (true, default), or return concatinated result (false)
    // returns:
    // the nested array
    function groupByPriorities(array, removeDuplicates) {
      if (removeDuplicates == null) removeDuplicates = true;

      var result = [];
      var taken = [];

      //zero is an exception, if it's present we manually take it to the front
      if (array.indexOf(0) != -1) {
        result.push([0]);
        taken.push(array.indexOf(0));
      }

      for (var k = array.length; k >= 1; k = k < 4 ? k - 1 : k / 2) {
        // push the next group of elements to the result
        result.push(array.filter(function (d, i) {
          if (i % Math.floor(k) == 0 && (taken.indexOf(i) == -1 || !removeDuplicates)) {
            taken.push(i);
            return true;
          }
          return false;
        }));
      }

      return result;
    }

    // REPOSITION LABELS THAT STICK OUT
    // Purpose: the outer labels can easily be so large, they stick out of the allotted area
    // Example:
    // Label is fine:    Label sticks out:    Label sticks out more:    Solution - label is shifted:
    //      12345 |           1234|                123|5                   12345|
    // _______.   |      _______. |           _______.|                 _______.|
    //
    // this is what the function does on the first step (only outer labels)
    // on the second step it shifts the inner labels that start to overlap with the shifted outer labels
    //
    // requires tickValues array to be sorted from tail-first
    // tail means left or bottom, head means top or right
    //
    // dimension - which dimension requires shifting
    // X if labels stack side by side, Y if labels stack on top of one another
    //
    // returns the array of recommended {x,y} shifts

    function repositionLabelsThatStickOut(tickValues, options, orient, scale, dimension) {
      if (!tickValues) return null;
      var result = {};

      // make an abstraction layer for margin sizes
      // tail means left or bottom, head means top or right
      var margin = orient == VERTICAL ? {
        head: options.toolMargin.top,
        tail: options.toolMargin.bottom
      } : {
        head: options.toolMargin.right,
        tail: options.toolMargin.left
      };

      var range = scale.range();
      var bump = options.bump;

      //when a viewportLength is given: adjust outer VISIBLE tick values
      //this is helpful when the scaled is zoomed, so labels don't get truncated by a viewport svg
      if (options.viewportLength) {
        //remove invisible ticks from the array
        tickValues = tickValues.filter(function (d) {
          return scale(d) >= 0 && scale(d) <= options.viewportLength;
        });
        //overwrite the available range with viewport limits. direction doesn't matter because we take min-max later anyway
        range = [0, options.viewportLength];
        //reset the bump because zoomed axis has no bump
        bump = 0;
      }

      // STEP 1:
      // for outer labels: avoid sticking out from the tool margin
      tickValues.forEach(function (d, i) {
        if (i != 0 && i != tickValues.length - 1) return;

        // compute the influence of the axis head
        var repositionHead = Math.min(margin.head, options.widthOfOneDigit * 0.5) + bump + (orient == HORIZONTAL ? 1 : 0) * d3.max(range) - (orient == HORIZONTAL ? 0 : 1) * d3.min(range) + (orient == HORIZONTAL ? -1 : 1) * scale(d) - (dimension == "x") * options.formatter(d).length * options.widthOfOneDigit / 2 - (dimension == "y") * options.heightOfOneDigit / 2
        // we may consider or not the label margins to give them a bit of spacing from the edges
        - (dimension == "x") * parseInt(options.cssMargin.right) - (dimension == "y") * parseInt(options.cssMargin.top);

        // compute the influence of the axis tail
        var repositionTail = Math.min(margin.tail, options.widthOfOneDigit * 0.5) + bump + (orient == VERTICAL ? 1 : 0) * d3.max(range) - (orient == VERTICAL ? 0 : 1) * d3.min(range) + (orient == VERTICAL ? -1 : 1) * scale(d) - (dimension == "x") * options.formatter(d).length * options.widthOfOneDigit / 2 - (dimension == "y") * options.heightOfOneDigit / 2
        // we may consider or not the label margins to give them a bit of spacing from the edges
        - (dimension == "x") * parseInt(options.cssMargin.left) - (dimension == "y") * parseInt(options.cssMargin.bottom);

        // apply limits in order to cancel repositioning of labels that are good
        if (repositionHead > 0) repositionHead = 0;
        if (repositionTail > 0) repositionTail = 0;

        // add them up with appropriate signs, save to the axis
        result[d] = { x: 0, y: 0 };
        result[d][dimension] = (dimension == "y" && orient == VERTICAL ? -1 : 1) * (repositionHead - repositionTail);
      });

      // STEP 2:
      // for inner labels: avoid collision with outer labels
      tickValues.forEach(function (d, i) {
        if (i == 0 || i == tickValues.length - 1) return;

        // compute the influence of the head-side outer label
        var repositionHead =
        // take the distance between head and the tick at hand
        Math.abs(scale(d) - scale(tickValues[tickValues.length - 1]))

        // substract the shift of the head TODO: THE SIGN CHOICE HERE MIGHT BE WRONG. NEED TO TEST ALL CASES
        - (dimension == "y") * (orient == HORIZONTAL ? -1 : 1) * result[tickValues[tickValues.length - 1]][dimension] - (dimension == "x") * (orient == HORIZONTAL ? 1 : -1) * result[tickValues[tickValues.length - 1]][dimension]

        // substract half-length of the overlapping labels
        - (dimension == "x") * options.widthOfOneDigit / 2 * options.formatter(d).length - (dimension == "x") * options.widthOfOneDigit / 2 * options.formatter(tickValues[tickValues.length - 1]).length - (dimension == "y") * options.heightOfOneDigit * .7 //TODO remove magic constant - relation of actual font height to BBox-measured height

        // we may consider or not the label margins to give them a bit of spacing from the edges
        - (dimension == "x") * parseInt(options.cssMargin.left) - (dimension == "y") * parseInt(options.cssMargin.bottom);

        // compute the influence of the tail-side outer label
        var repositionTail =
        // take the distance between tail and the tick at hand
        Math.abs(scale(d) - scale(tickValues[0]))

        // substract the shift of the tail TODO: THE SIGN CHOICE HERE MIGHT BE WRONG. NEED TO TEST ALL CASES
        - (dimension == "y") * (orient == VERTICAL ? -1 : 1) * result[tickValues[0]][dimension] - (dimension == "x") * (orient == VERTICAL ? 1 : -1) * result[tickValues[0]][dimension]

        // substract half-length of the overlapping labels
        - (dimension == "x") * options.widthOfOneDigit / 2 * options.formatter(d).length - (dimension == "x") * options.widthOfOneDigit / 2 * options.formatter(tickValues[0]).length - (dimension == "y") * options.heightOfOneDigit * .7 //TODO remove magic constant - relation of actual font height to BBox-measured height

        // we may consider or not the label margins to give them a bit of spacing from the edges
        - (dimension == "x") * parseInt(options.cssMargin.left) - (dimension == "y") * parseInt(options.cssMargin.bottom);

        // apply limits in order to cancel repositioning of labels that are good
        if (repositionHead > 0) repositionHead = 0;
        if (repositionTail > 0) repositionTail = 0;

        // add them up with appropriate signs, save to the axis
        result[d] = { x: 0, y: 0 };
        result[d][dimension] = (dimension == "y" && orient == VERTICAL ? -1 : 1) * (repositionHead - repositionTail);
      });

      return result;
    } // function repositionLabelsThatStickOut()


    axis.copy = function () {
      return d3_axis_smart(d3.svg.axis());
    };

    return d3.rebind(axis, _super, "scale", "orient", "ticks", "tickValues", "tickFormat", "tickSize", "innerTickSize", "outerTickSize", "tickPadding", "tickSubdivide");

    function meow(l1, l2, l3, l4, l5) {
      if (!axis.labelerOptions().isDevMode) return;
      if (l5 != null) {
        console.log(l1, l2, l3, l4, l5);
        return;
      }
      if (l4 != null) {
        console.log(l1, l2, l3, l4);
        return;
      }
      if (l3 != null) {
        console.log(l1, l2, l3);
        return;
      }
      if (l2 != null) {
        console.log(l1, l2);
        return;
      }
      if (l1 != null) {
        console.log(l1);
        return;
      }
    }
  }(d3.svg.axis());
};

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

var META     = __webpack_require__(57)('meta')
  , isObject = __webpack_require__(6)
  , has      = __webpack_require__(15)
  , setDesc  = __webpack_require__(9).f
  , id       = 0;
var isExtensible = Object.isExtensible || function(){
  return true;
};
var FREEZE = !__webpack_require__(5)(function(){
  return isExtensible(Object.preventExtensions({}));
});
var setMeta = function(it){
  setDesc(it, META, {value: {
    i: 'O' + ++id, // object ID
    w: {}          // weak collections IDs
  }});
};
var fastKey = function(it, create){
  // return primitive with prefix
  if(!isObject(it))return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;
  if(!has(it, META)){
    // can't set metadata to uncaught frozen object
    if(!isExtensible(it))return 'F';
    // not necessary to add metadata
    if(!create)return 'E';
    // add missing metadata
    setMeta(it);
  // return object ID
  } return it[META].i;
};
var getWeak = function(it, create){
  if(!has(it, META)){
    // can't set metadata to uncaught frozen object
    if(!isExtensible(it))return true;
    // not necessary to add metadata
    if(!create)return false;
    // add missing metadata
    setMeta(it);
  // return hash weak collections IDs
  } return it[META].w;
};
// add metadata on freeze-family methods calling
var onFreeze = function(it){
  if(FREEZE && meta.NEED && isExtensible(it) && !has(it, META))setMeta(it);
  return it;
};
var meta = module.exports = {
  KEY:      META,
  NEED:     false,
  fastKey:  fastKey,
  getWeak:  getWeak,
  onFreeze: onFreeze
};

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

module.exports = function(bitmap, value){
  return {
    enumerable  : !(bitmap & 1),
    configurable: !(bitmap & 2),
    writable    : !(bitmap & 4),
    value       : value
  };
};

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

// 7.1.4 ToInteger
var ceil  = Math.ceil
  , floor = Math.floor;
module.exports = function(it){
  return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);
};

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

"use strict";
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = {
  ext_resources: {},
  build: 1484465741145,
  version: "0.18.3-1"
};

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.ChangeEvent = exports.DefaultEvent = undefined;

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _class = __webpack_require__(21);

var _class2 = _interopRequireDefault(_class);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

var _freezeAllEvents = false;
var _frozenEventInstances = [];
var _freezeAllExceptions = {};

var DefaultEvent = exports.DefaultEvent = _class2.default.extend({

  source: '',
  type: 'default',

  init: function init(source, type) {
    this.source = source;
    if (type) this.type = type;
  }

});

var ChangeEvent = exports.ChangeEvent = DefaultEvent.extend('change', {

  type: 'change',

  init: function init(source) {
    this._super(source);
  }

});

var EventSource = _class2.default.extend({

  /**
   * Initializes the event class
   */
  init: function init() {
    this._id = this._id || utils.uniqueId('e');
    this._events = {};
    //freezing events
    this._freeze = false;
    this._freezer = [];
    this._freezeExceptions = {};
  },

  /**
   * Binds a callback function to an event: part 1: split grouped parameters in seperate calls
   * @param {String} type type of event
   * @param {String|Array} target path to object the event should be bound to or array of target paths
   * @param {Function|Array} func function to be bound with event or array with functions
   */
  on: function on(type, path, func) {

    // if parameters had to be split up in seperate calls, don't continue with this call
    if (this.splitEventParameters(type, path, func, this.on)) return;

    // get the target model
    var target = this.traversePath(path);
    if (!target) return;

    // register the event to this object
    target._events[type] = target._events[type] || [];
    if (typeof func === 'function') {
      target._events[type].push(func);
    } else {
      utils.warn('Can\'t bind event \'' + type + '\'. It must be a function.');
    }
  },

  /**
   * Unbinds all events associated with a name or a specific one
   * @param {String|Array} name name of event or array with names
   */
  off: function off(type, path, func) {

    // if no arguments, unbind all
    if (arguments.length == 0) {
      this._events = {};
      return;
    }

    // if parameters had to be split up in seperate calls, don't continue with this call
    if (this.splitEventParameters(type, path, func, this.off)) return;

    // get target model
    var target = this.traversePath(path);
    if (!target) return;

    // unbind events
    if (target._events.hasOwnProperty(type)) {
      // if function not given, remove all events of type
      if (typeof func === 'undefined') {
        target._events[type] = [];
        return;
      }
      var index = target._events[type].indexOf(func);
      if (index > -1) {
        target._events[type].splice(index, 1);
      } else {
        utils.warn('Could not unbind function ' + func.name + '. Function not in bound function list.');
      }
    }
  },

  /**
   * Split grouped event parameters to seperate calls to given funtion
   * @param {String|Object|Array} type type of event
   * @param {String|Array} target path to object the event should be bound to or array of target paths
   * @param {Function|Array} func function to be bound with event or array with functions
   * @param {Function} eventFunc function to further process the split up parameters
   * @return {Boolean} true if the parameters where split up, false if nothing was split up
   * eventFunc is mostly arguments.callee but this is deprecated in ECMAscript 5: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/callee
   */
  splitEventParameters: function splitEventParameters(type, path, func, eventFunc) {
    var i;
    var calls = [];

    // multiple at a time, array format: [{type: function}, {'type:path': function}, ... ]
    // seems redundant but used so that binding-sets won't be turned into models (which happens when it's a pure object). Used e.g. in Tool.init();
    if (utils.isArray(type)) {
      for (i = 0; i < type.length; i += 1) {
        eventFunc.call(this, type[i], func);
      }
      return true;
    }

    //multiple at a time, object format: {type: function, 'type:path': function, ... }
    if (utils.isObject(type)) {
      for (i in type) {
        eventFunc.call(this, i, type[i]);
      }
      return true;
    }

    // type and path are both in type: on('type:path', function)
    // or
    // path undefined: on('type', function)
    if (typeof path === 'function') {
      func = path; // put callback function in func variable
      // on('type:path', func)
      if (type.indexOf(':') !== -1) {
        var split = type.split(':');
        type = split[0];
        path = split[1];
      }
      // on(type, func)
      else {
          path = undefined;
        }
      eventFunc.call(this, type, path, func);
      return true;
    }

    // bind multiple paths at a time to one function: on(type, [path1, path2], function)
    if (utils.isArray(path)) {
      for (i = 0; i < path.length; i += 1) {
        eventFunc.call(this, type, path[i], func);
      }
      return true;
    }

    //bind multiple functions at the same time to one path: on(type, path, [function1, function2])
    if (func && utils.isArray(func)) {
      for (i = 0; i < func.length; i += 1) {
        eventFunc.call(this, type, path, func[i]);
      }
      return true;
    }
    return false;
  },

  /**
   * // TODO: if events will not be strictly model-bound, this might have to move to model.
   * Traverse path down the model tree
   * @param {String|Array} target path to object that should be returned. Either in string or array form
   */
  traversePath: function traversePath(path) {

    // if there's no path to traverse
    if (typeof path === 'undefined' || utils.isArray(path) && path.length == 0) {
      return this;
    }

    // prepare path to array
    if (typeof path === 'string') {
      path = path.split('.');
    }

    // check if path is an array
    if (!utils.isArray(path)) {
      utils.error('Path is wrong type. Path should be a string or array but is ' + (typeof path === 'undefined' ? 'undefined' : _typeof(path)) + '.');
      return null;
    }

    // descent to next child to find target object
    var currentTarget = path.shift();
    if (this[currentTarget] === undefined) utils.warn('Can\'t find child "' + currentTarget + '" of the model ' + this._name + '.');else return this.getModelObject(currentTarget).traversePath(path);
  },

  createEventFromType: function createEventFromType(evtType) {
    if (evtType instanceof DefaultEvent) {
      return evtType;
    }

    var eventClass = DefaultEvent.get(evtType, true); // silent
    if (eventClass) {
      return new eventClass(this);
    }

    return new DefaultEvent(this, evtType);
  },

  /**
   * Triggers an event, adding it to the buffer
   * @param {String|Array} name name of event or array with names
   * @param args Optional arguments (values to be passed)
   */
  trigger: function trigger(evtType, args) {
    var _this2 = this;

    var i;
    var size;

    // split up eventType-paremeter for multiple event-triggers
    if (utils.isArray(evtType)) {
      for (i = 0, size = evtType.length; i < size; i += 1) {
        this.trigger(evtType[i], args);
      }
      return;
    }

    // create an event-object if necessary
    var evt = this.createEventFromType(evtType);

    // if this eventType has no events registered
    if (!this._events.hasOwnProperty(evt.type)) {
      return;
    }

    // for each function registered to this eventType on this object
    var _this = this;
    utils.forEach(this._events[evt.type], function (func) {

      // prepare execution
      var execute = function execute() {
        var msg = 'Vizabi Event: ' + evt.type; // + ' - ' + eventPath;
        utils.timeStamp(msg);
        func.apply(_this, [evt, args]);
      };

      //TODO: improve readability of freezer code
      //only execute if not frozen and exception doesnt exist
      if (_this2.allowExecution(evt)) {
        execute();
      } else {
        _this2._freezer.push(execute);
        if (_freezeAllEvents && !_frozenEventInstances[_this2._id]) {
          _this2.freeze();
          _frozenEventInstances[_this2._id] = _this2;
        }
      }
    });
  },

  allowExecution: function allowExecution(evt) {
    return !this._freeze && !_freezeAllEvents || // nothing frozen
    _freezeAllEvents && _freezeAllExceptions.hasOwnProperty(evt.type) || // freeze all but exception
    !_freezeAllEvents && this._freeze && this._freezeExceptions.hasOwnProperty(evt.type); // freeze but exception
  },

  /**
   * Prevents all events from being triggered, buffering them
   */
  freeze: function freeze(exceptions) {
    this._freeze = true;
    if (!exceptions) {
      return;
    }
    if (!utils.isArray(exceptions)) {
      exceptions = [exceptions];
    }
    for (var i = 0; i < exceptions.length; i += 1) {
      this._freezeExceptions[exceptions[i]] = true;
    }
  },

  /**
   * triggers all frozen events
   */
  unfreeze: function unfreeze() {
    this._freeze = false;
    this._freezeExceptions = {};
    //execute old frozen events
    while (this._freezer.length) {
      var execute = this._freezer.shift();
      execute();
    }
  },

  /**
   * clears all frozen events
   */
  clearFrozen: function clearFrozen() {
    this._freeze = false;
    this._freezeExceptions = {};
    this._freezer = [];
  }
});

EventSource.freezeAll = freezeAll;
EventSource.unfreezeAll = unfreezeAll;

//generic event functions
/**
 * freezes all events
 */
function freezeAll(exceptions) {
  _freezeAllEvents = true;
  if (!exceptions) {
    return;
  }
  if (!utils.isArray(exceptions)) {
    exceptions = [exceptions];
  }
  utils.forEach(exceptions, function (e) {
    _freezeAllExceptions[e] = true;
  });
};

/**
 * triggers all frozen events form all instances
 */
function unfreezeAll() {
  _freezeAllEvents = false;
  _freezeAllExceptions = {};
  //unfreeze all instances
  var keys = Object.keys(_frozenEventInstances);
  for (var i = 0; i < keys.length; i++) {
    var instance = _frozenEventInstances[keys[i]];
    if (!instance) {
      continue;
    }
    instance.unfreeze();
  }
  _frozenEventInstances = {};
};

exports.default = EventSource;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _events = __webpack_require__(45);

var _events2 = _interopRequireDefault(_events);

var _intervals = __webpack_require__(207);

var _intervals2 = _interopRequireDefault(_intervals);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

var ModelLeaf = _events2.default.extend({

  _name: '',
  _parent: null,
  _persistent: true,

  init: function init(name, value, parent, binds, persistent) {

    // getter and setter for the value
    Object.defineProperty(this, 'value', {
      get: this.get,
      set: this.set
    });
    Object.defineProperty(this, 'persistent', {
      get: function get() {
        return this._persistent;
      }
    });

    this._super();

    this._name = name;
    this._parent = parent;
    this._root = parent._root;
    this.set(value, false, persistent);
    this.on(binds); // after super so there is an .events object
  },

  // if they want a persistent value and the current value is not persistent, return the last persistent value
  get: function get(persistent) {
    return persistent && !this._persistent ? this._persistentVal : this._val;
  },

  set: function set(val, force, persistent) {
    if (this.isSetAllowed(val, force)) {
      // persistent defaults to true
      persistent = typeof persistent !== 'undefined' ? persistent : true;

      // set leaf properties
      if (persistent) this._persistentVal = val; // set persistent value if change is persistent.
      this._previousVal = utils.deepClone(this._val);
      this._val = val;
      this._persistent = persistent;

      // trigger change event
      this.trigger(new _events.ChangeEvent(this), this._name);

      return true;
    }
    return false;
  },

  isSetAllowed: function isSetAllowed(val, force) {
    return force || this._val !== val && JSON.stringify(this._val) !== JSON.stringify(val);
  },

  // duplicate from Model. Should be in a shared parent class.
  setTreeFreezer: function setTreeFreezer(freezerStatus) {
    if (freezerStatus) {
      this.freeze(['hook_change']);
    } else {
      this.unfreeze();
    }
  }

});

var Model = _events2.default.extend({

  getClassDefaults: function getClassDefaults() {
    return {};
  },

  /**
   * A leaf model which has an object as value.
   * Needed when parsing plain JS objects. Enables distinction between models and leafs with object values.
   **/
  objectLeafs: [],

  /**
   * Initializes the model.
   * @param {Object} values The initial values of this model
   * @param {Object} parent reference to parent
   * @param {Object} bind Initial events to bind
   * @param {Boolean} freeze block events from being dispatched
   */
  init: function init(name, values, parent, bind) {
    this._type = this._type || 'model';
    this._id = this._id || utils.uniqueId('m');
    this._data = {};
    //holds attributes of this model
    this._parent = parent;
    this._root = parent ? parent._root : this;
    this._name = name;
    this._ready = false;
    this._readyOnce = false;
    //has this model ever been ready?
    this._loadedOnce = false;
    //array of processes that are loading
    this._intervals = getIntervals(this);

    //will the model be hooked to data?
    this._space = {};

    this._dataId = false;
    this._limits = {};
    //stores limit values
    this._super();

    // initial values
    // add defaults to initialValues
    var initialValues = utils.deepExtend({}, this.getClassDefaults(), values);
    this.set(initialValues);

    // bind initial events
    // bind after setting, so no events are fired by setting initial values
    if (bind) {
      this.on(bind);
    }
  },

  /* ==========================
   * Getters and Setters
   * ==========================
   */

  /**
   * Gets an attribute from this model or all fields.
   * @param attr Optional attribute
   * @returns attr value or all values if attr is undefined
   */
  get: function get(attr) {
    if (!attr) {
      return this._data;
    }
    if (Model.isModel(this._data[attr])) return this._data[attr];else return this._data[attr].value; // return leaf value
  },

  /**
   * Sets an attribute or multiple for this model (inspired by Backbone)
   * @param attr property name
   * @param val property value (object or value)
   * @param {Boolean} force force setting of property to value and triggers set event
   * @param {Boolean} persistent true if the change is a persistent change
   * @returns defer defer that will be resolved when set is done
   */
  set: function set(attr, val, force, persistent) {
    var setting = this._setting;
    var attrs;
    var freezeCall = false; // boolean, indicates if this .set()-call froze the modelTree

    //expect object as default
    if (!utils.isPlainObject(attr)) {
      (attrs = {})[attr] = val;
    } else {
      // move all arguments one place
      attrs = attr;
      persistent = force;
      force = val;
    }

    //do nothing if setting an empty object
    if (Object.keys(attrs).length === 0) return;

    //we are currently setting the model
    this._setting = true;

    // Freeze the whole model tree if not frozen yet, so no events are fired while setting
    if (!this._freeze) {
      freezeCall = true;
      this.setTreeFreezer(true);
    }

    // init/set all given values
    var changes = [];
    for (var attribute in attrs) {
      val = attrs[attribute];

      var bothModel = utils.isPlainObject(val) && this._data[attribute] instanceof Model;
      var bothModelLeaf = (!utils.isPlainObject(val) || this.isObjectLeaf(attribute)) && this._data[attribute] instanceof ModelLeaf;

      if (this._data[attribute] && (bothModel || bothModelLeaf)) {
        // data type does not change (model or leaf and can be set through set-function)
        var setSuccess = this._data[attribute].set(val, force, persistent);
        if (bothModelLeaf && setSuccess) {
          changes.push(attribute);
        }
      } else {
        // data type has changed or is new, so initializing the model/leaf
        this._data[attribute] = initSubmodel(attribute, val, this, persistent);
        bindSetterGetter(this, attribute);
      }
    }

    if (!setting) {
      this.checkDataChanges(changes);
      if (this.validate) {
        this.validate();
      }
    }

    if (!setting || force) {
      this._setting = false;
      if (freezeCall && (!this.isHook() || !this.isLoading())) {
        this.setTreeFreezer(false);
      }
      if (!this.isHook() && !this.isLoading()) {
        this.setReady();
      }
    }

    // if this set()-call was the one freezing the tree, now the tree can be unfrozen (i.e. all setting is done)
  },

  // standard model doesn't do anything with data
  // overloaded by hook/entities
  checkDataChanges: function checkDataChanges() {},

  setTreeFreezer: function setTreeFreezer(freezerStatus) {
    // first traverse down
    // this ensures deepest events are triggered first
    utils.forEach(this._data, function (submodel) {
      submodel.setTreeFreezer(freezerStatus);
    });

    // then freeze/unfreeze
    if (freezerStatus) {
      this.freeze(['hook_change']);
    } else {
      this.unfreeze();
    }
  },

  /**
   * Gets the type of this model
   * @returns {String} type of the model
   */
  getType: function getType() {
    return this._type;
  },

  /**
   * Gets all submodels of the current model
   * @param {Object} object [object=false] Should it return an object?
   * @param {Function} validationFunction Validation function
   * @returns {Array} submodels
   */
  getSubmodels: function getSubmodels() {
    var object = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
    var validationFunction = arguments[1];

    var submodels = object ? {} : [];
    var validationFunction = validationFunction || function () {
      return true;
    };
    var _this = this;
    utils.forEach(this._data, function (subModel, name) {
      if (subModel && typeof subModel._id !== 'undefined' && Model.isModel(subModel) && validationFunction(subModel)) {
        if (object) {
          submodels[name] = subModel;
        } else {
          submodels.push(subModel);
        }
      }
    });
    return submodels;
  },

  /**
   * Gets the current model and submodel values as a JS object
   * @returns {Object} All model as JS object, leafs will return their values
   */
  getPlainObject: function getPlainObject(persistent) {
    var obj = {};
    var _this = this;
    utils.forEach(this._data, function (dataItem, i) {
      // if it's a submodel
      if (dataItem instanceof Model) {
        obj[i] = dataItem.getPlainObject(persistent);
      }
      // if it's a modelLeaf
      else {
          //if asked for persistent then add value to result only if modelLeaf state is
          //persistent
          if (!persistent || dataItem.persistent) {
            var leafValue = dataItem.get(persistent);
            if (utils.isDate(leafValue)) leafValue = _this.formatDate(leafValue);
            obj[i] = leafValue;
          }
        }
    });
    return obj;
  },

  formatDate: function formatDate(dateObject) {
    return dateObject.toString();
  },

  /**
   * Gets the requested object, including the leaf-object, not the value
   * @returns {Object} Model or ModelLeaf object.
   */
  getModelObject: function getModelObject(name) {
    if (name) return this._data[name];else return this;
  },

  /**
   * Clears this model, submodels, data and events
   */
  clear: function clear() {
    var submodels = this.getSubmodels();
    for (var i in submodels) {
      submodels[i].clear();
    }
    this.setReady(false);
    this.off();
    this._intervals.clearAllIntervals();
    this._data = {};
  },

  /**
   * Validates data.
   * Interface for the validation function implemented by a model
   * @returns Promise or nothing
   */
  validate: function validate() {},

  /* ==========================
   * Model loading
   * ==========================
   */

  // normal model is never loading
  _isLoading: function _isLoading() {
    return false;
  },

  /**
   * checks whether this model is loading anything
   * @param {String} optional process id (to check only one)
   * @returns {Boolean} is it loading?
   */
  isLoading: function isLoading() {
    if (this._isLoading()) return true;

    //if not loading anything, check submodels
    var submodels = this.getSubmodels();
    var i;
    for (i = 0; i < submodels.length; i += 1) {
      if (submodels[i].isLoading()) {
        return true;
      }
    }

    return false;
  },

  /**
   * Sets the model as ready or not depending on its loading status
   */
  setReady: function setReady(value) {
    if (value === false) {
      this._ready = false;
      if (this._parent && this._parent.setReady) {
        this._parent.setReady(false);
      }
      return;
    }
    //only ready if nothing is loading at all
    var prev_ready = this._ready;
    this._ready = !this.isLoading() && !this._setting;
    // if now ready and wasn't ready yet
    if (this._ready && prev_ready !== this._ready) {
      if (!this._readyOnce) {
        this._readyOnce = true;
        this.trigger('readyOnce');
      }
      this.trigger('ready');
    }
  },

  setInterModelListeners: function setInterModelListeners() {
    utils.forEach(this.getSubmodels(), function (subModel) {
      return subModel.setInterModelListeners();
    });
  },

  startPreload: function startPreload() {

    var promises = [];
    promises.push(this.preloadData());

    utils.forEach(this.getSubmodels(), function (subModel) {
      return promises.push(subModel.startPreload());
    });

    return Promise.all(promises);
  },

  preloadData: function preloadData() {
    return Promise.resolve();
  },

  /**
   * loads data (if hook)
   * Hooks loads data, models ask children to load data
   * Basically, this method:
   * loads is theres something to be loaded:
   * does not load if there's nothing to be loaded
   * @param {Object} options (includes splashScreen)
   * @returns defer
   */
  startLoading: function startLoading(opts) {

    var promises = [];
    promises.push(this.loadData(opts));

    utils.forEach(this.getSubmodels(), function (subModel) {
      return promises.push(subModel.startLoading(opts));
    });

    return Promise.all(promises).then(this.onSuccessfullLoad.bind(this));
  },

  loadData: function loadData(opts) {
    if (this.isHook()) utils.warn('Hook ' + this._name + ' is not loading because it\'s not extending Hook prototype.');
    return Promise.resolve();
  },

  loadSubmodels: function loadSubmodels(options) {
    var promises = [];
    var subModels = this.getSubmodels();
    utils.forEach(subModels, function (subModel) {
      promises.push(subModel.startLoading(options));
    });
    return promises.length > 0 ? Promise.all(promises) : Promise.resolve();
  },

  onSuccessfullLoad: function onSuccessfullLoad() {
    var _this2 = this;

    this.validate();
    utils.timeStamp('Vizabi Model: Model loaded: ' + this._name + '(' + this._id + ')');
    //end this load call
    this._loadedOnce = true;

    this._loadCall = false;
    this.setTreeFreezer(false);

    //we need to defer to make sure all other submodels
    //have a chance to call loading for the second time
    utils.defer(function () {
      return _this2.setReady();
    });
  },

  triggerLoadError: function triggerLoadError(error) {
    utils.error(error);
    this.trigger('load_error', error);
  },


  /**
   * executes after preloading processing is done
   */
  afterPreload: function afterPreload() {
    var submodels = this.getSubmodels();
    utils.forEach(submodels, function (s) {
      s.afterPreload();
    });
  },

  /* ===============================
   * Hooking model to external data
   * ===============================
   */

  /**
   * is this model hooked to data?
   */
  isHook: function isHook() {
    return this.use ? true : false;
  },

  /**
   * Gets all submodels of the current model that are hooks
   * @param object [object=false] Should it return an object?
   * @returns {Array|Object} hooks array or object
   */
  getSubhooks: function getSubhooks(object) {
    return this.getSubmodels(object, function (s) {
      return s.isHook();
    });
  },

  /**
   * gets all sub values for a certain hook
   * only hooks have the "hook" attribute.
   * @param {String} type specific type to lookup
   * @returns {Array} all unique values with specific hook use
   */
  getHookWhich: function getHookWhich(type) {
    var values = [];
    if (this.use && this.use === type) {
      values.push(this.which);
    }
    //repeat for each submodel
    utils.forEach(this.getSubmodels(), function (s) {
      values = utils.unique(values.concat(s.getHookWhich(type)));
    });
    //now we have an array with all values in a type of hook for hooks.
    return values;
  },

  /**
   * gets all sub values for indicators in this model
   * @returns {Array} all unique values of indicator hooks
   */
  getIndicators: function getIndicators() {
    return this.getHookWhich('indicator');
  },

  /**
   * gets all sub values for indicators in this model
   * @returns {Array} all unique values of property hooks
   */
  getProperties: function getProperties() {
    return this.getHookWhich('property');
  },

  /**
   * Gets the dimension of this model if it has one
   * @returns {String|Boolean} dimension
   */
  getDimension: function getDimension() {
    return this.dim || false; //defaults to dim if it exists
  },

  /**
   * Gets the dimension (if entity) or which (if hook) of this model
   * @returns {String|Boolean} dimension
   */
  getDimensionOrWhich: function getDimensionOrWhich() {
    return this.dim || (this.use != 'constant' ? this.which : false); //defaults to dim or which if it exists
  },

  /**
   * Gets the filter for this model if it has one
   * @returns {Object} filters
   */
  getFilter: function getFilter() {
    return {}; //defaults to no filter
  },

  /**
   * maps the value to this hook's specifications
   * @param value Original value
   * @returns hooked value
   */
  mapValue: function mapValue(value) {
    return value;
  },

  /**
   * Gets formatter for this model
   * @returns {Function|Boolean} formatter function
   */
  getParser: function getParser() {
    //TODO: default formatter is moved to utils. need to return it to hook prototype class, but retest #1212 #1230 #1253
    return null;
  },

  /**
   * @return {Object} defaults of this model, and when available overwritten by submodel defaults
   */
  getDefaults: function getDefaults() {
    return utils.deepExtend({}, this.getClassDefaults(), this.getSubmodelDefaults());
  },

  /**
   * @return {Object} All defaults coming from submodels
   */
  getSubmodelDefaults: function getSubmodelDefaults() {
    var d = {};
    utils.forEach(this.getSubmodels(true), function (model, name) {
      d[name] = model.getDefaults();
    });
    return d;
  },

  /**
   * @param  {name} name of the child to check
   * @return {Boolean} if the child is a leaf with a plain object as value
   */
  isObjectLeaf: function isObjectLeaf(name) {
    return this.objectLeafs.indexOf(name) !== -1;
  },

  /**
   * gets closest prefix model moving up the model tree
   * @param {String} prefix
   * @returns {Object} submodel
   */
  getClosestModel: function getClosestModel(name) {
    var model = this.findSubmodel(name);
    if (model) {
      return model;
    } else if (this._parent) {
      return this._parent.getClosestModel(name);
    }
    return null;
  },

  /**
   * find submodel with name that starts with prefix
   * @param {String} prefix
   * @returns {Object} submodel or false if nothing is found
   */
  findSubmodel: function findSubmodel(name) {
    for (var i in this._data) {
      //found submodel
      if (i === name && Model.isModel(this._data[i])) {
        return this._data[i];
      }
    }
    return null;
  }

});

/* ===============================
 * Private Helper Functions
 * ===============================
 */

/**
 * Checks whether an object is a model or not
 * if includeLeaf is true, a leaf is also seen as a model
 */
Model.isModel = function (model, includeLeaf) {
  return model && (model.hasOwnProperty('_data') || includeLeaf && model.hasOwnProperty('_val'));
};

function bindSetterGetter(model, prop) {
  Object.defineProperty(model, prop, {
    configurable: true,
    //allow reconfiguration
    get: function (p) {
      return function () {
        return model.get(p);
      };
    }(prop),
    set: function (p) {
      return function (value) {
        return model.set(p, value);
      };
    }(prop)
  });
}

/**
 * Loads a submodel, when necessaary
 * @param {String} attr Name of submodel
 * @param {Object} val Initial values
 * @param {Object} ctx context / parent model
 * @param {Boolean} persistent true if the change is a persistent change
 * @returns {Object} model new submodel
 */
function initSubmodel(attr, val, ctx, persistent) {

  var submodel;

  // if value is a value -> leaf
  if (!utils.isPlainObject(val) || utils.isArray(val) || ctx.isObjectLeaf(attr)) {

    var binds = {
      //the submodel has changed (multiple times)
      'change': onChange
    };
    submodel = new ModelLeaf(attr, val, ctx, binds, persistent);
  }

  // if value is an object -> model
  else {

      var binds = {
        //the submodel has changed (multiple times)
        'change': onChange,
        //loading has started in this submodel (multiple times)
        'hook_change': onHookChange,
        // error triggered in loading
        'load_error': function load_error() {
          return ctx.trigger.apply(ctx, arguments);
        },
        //loading has ended in this submodel (multiple times)
        'ready': onReady
      };

      // if the value is an already instantiated submodel (Model or ModelLeaf)
      // this is the case for example when a new componentmodel is made (in Component._modelMapping)
      // it takes the submodels from the toolmodel and creates a new model for the component which refers
      // to the instantiated submodels (by passing them as model values, and thus they reach here)
      if (Model.isModel(val, true)) {
        submodel = val;
        submodel.on(binds);
      }
      // if it's just a plain object, create a new model
      else {
          // construct model
          var modelType = attr.split('_')[0];

          var Modl = Model.get(modelType, true);
          if (!Modl) {
            try {
              Modl = __webpack_require__(457)("./" + modelType).default;
            } catch (err) {
              Modl = Model;
            }
          }

          submodel = new Modl(attr, val, ctx, binds);
          // model is still frozen but will be unfrozen at end of original .set()
        }
    }

  return submodel;

  // Default event handlers for models
  function onChange(evt, path) {
    if (!ctx._ready) return; //block change propagation if model isnt ready
    path = ctx._name + '.' + path;
    ctx.trigger(evt, path);
  }
  function onHookChange(evt, vals) {
    ctx.trigger(evt, vals);
  }
  function onReady(evt, vals) {
    //trigger only for submodel
    ctx.setReady(false);
    //wait to make sure it's not set false again in the next execution loop
    utils.defer(function () {
      ctx.setReady();
    });
    //ctx.trigger(evt, vals);
  }
}

/**
 * gets closest interval from this model or parent
 * @returns {Object} Intervals object
 */
function getIntervals(ctx) {
  if (ctx._intervals) {
    return ctx._intervals;
  } else if (ctx._parent) {
    return getIntervals(ctx._parent);
  } else {
    return new _intervals2.default();
  }
}

exports.default = Model;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
    value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _iconset = __webpack_require__(10);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*!
 * VIZABI INDICATOR PICKER
 * Reusable indicator picker component
 */

var IndPicker = _component2.default.extend({

    /**
     * Initializes the Indicator Picker.
     * Executed once before any template is rendered.
     * @param config The options passed to the component
     * @param context The component's parent
     */
    init: function init(config, context) {

        this.name = 'gapminder-indicatorpicker';
        this.template = '<span class="vzb-ip-holder"><span class="vzb-ip-select"></span><span class="vzb-ip-info"></span></span>';

        var _this = this;

        this.model_expects = [{
            name: "time",
            type: "time"
        }, {
            name: "entities",
            type: "entities"
        }, {
            name: "marker",
            type: "model"
        }, {
            name: "locale",
            type: "locale"
        }];

        this.markerID = config.markerID;
        this.showHoverValues = config.showHoverValues || false;
        if (!config.markerID) utils.warn("indicatorpicker.js complains on 'markerID' property: " + config.markerID);

        this.model_binds = {
            "translate:locale": function translateLocale(evt) {
                _this.updateView();
            },
            "ready": function ready(evt) {
                _this.updateView();
            }
        };

        if (this.markerID) {
            this.model_binds["change:marker." + this.markerID + ".which"] = function (evt) {
                _this.updateView();
            };
        }

        if (this.showHoverValues) {
            this.model_binds["change:marker.highlight"] = function (evt, values) {
                var mdl = _this.model.marker[_this.markerID];
                if (!_this.showHoverValues || mdl.use == "constant") return;
                var _highlightedEntity = _this.model.marker.getHighlighted();
                if (_highlightedEntity.length > 1) return;

                if (_highlightedEntity.length) {
                    _this.model.marker.getFrame(_this.model.time.value, function (frame) {
                        if (_this._highlighted || !frame) return;

                        // should be replaced by dimension of entity set for this hook (if use == property)
                        var dimension = _this.model.entities.getDimension();
                        var _highlightedEntity = _this.model.marker.getHighlighted(dimension);
                        if (_highlightedEntity.length) {

                            var value = frame[_this.markerID][_highlightedEntity[0]];

                            // resolve strings via the color legend model
                            if (value && mdl._type === "color" && mdl.isDiscrete()) {
                                var clModel = mdl.getColorlegendMarker();
                                if (clModel.label.getItems()[value]) value = clModel.label.getItems()[value];
                            }

                            _this._highlightedValue = value;

                            _this._highlighted = !_this._highlightedValue && _this._highlightedValue !== 0 || mdl.use !== "constant";
                            _this.updateView();
                        }
                    });
                } else {
                    if (values !== null && values !== "highlight") {
                        if (values) {
                            _this._highlightedValue = values[_this.markerID];
                            _this._highlighted = !_this._highlightedValue && _this._highlightedValue !== 0 || mdl.use !== "constant";
                        }
                    } else {
                        _this._highlighted = false;
                    }
                    _this.updateView();
                }
            };
        }

        //contructor is the same as any component
        this._super(config, context);
    },

    ready: function ready() {
        this.updateView();
    },

    readyOnce: function readyOnce() {
        var _this = this;

        this.el_select = d3.select(this.element).select('.vzb-ip-select');

        this.el_select.on("click", function () {
            var rect = _this.el_select.node().getBoundingClientRect();
            var rootEl = _this.root.element instanceof Array ? _this.root.element : d3.select(_this.root.element);
            var rootRect = rootEl.node().getBoundingClientRect();
            var treemenuComp = _this.root.findChildByName("gapminder-treemenu");
            var treemenuColWidth = treemenuComp.activeProfile.col_width;
            var treemenuPaddLeft = parseInt(treemenuComp.wrapper.style('padding-left'), 10) || 0;
            var treemenuPaddRight = parseInt(treemenuComp.wrapper.style('padding-right'), 10) || 0;
            var topPos = rect.bottom - rootRect.top;
            var leftPos = rect.left - rootRect.left - (treemenuPaddLeft + treemenuPaddRight + treemenuColWidth - rect.width) * .5;

            treemenuComp.markerID(_this.markerID).alignX("left").alignY("top").top(topPos).left(leftPos).updateView().toggle();
        });

        this.infoEl = d3.select(this.element).select('.vzb-ip-info');
        utils.setIcon(this.infoEl, _iconset.question).select("svg").attr("width", "0px").attr("height", "0px");

        this.infoEl.on("click", function () {
            _this.root.findChildByName("gapminder-datanotes").pin();
        });
        this.infoEl.on("mouseover", function () {
            var rect = _this.el_select.node().getBoundingClientRect();
            var rootRect = _this.root.element.getBoundingClientRect();
            var topPos = rect.bottom - rootRect.top;
            var leftPos = rect.left - rootRect.left + rect.width;

            _this.root.findChildByName("gapminder-datanotes").setHook(_this.markerID).show().setPos(leftPos, topPos);
        });
        this.infoEl.on("mouseout", function () {
            _this.root.findChildByName("gapminder-datanotes").hide();
        });
    },

    updateView: function updateView() {
        if (!this._readyOnce) return;

        var _this = this;
        var translator = this.model.locale.getTFunction();

        var which = this.model.marker[this.markerID].which;
        var type = this.model.marker[this.markerID]._type;
        var concept = this.model.marker[this.markerID].getConceptprops();

        var selectText;

        if (this.showHoverValues && this._highlighted) {
            var unit = !concept.unit ? "" : " " + concept.unit;
            var formatter = _this.model.marker[this.markerID].getTickFormatter();

            selectText = this._highlightedValue || this._highlightedValue === 0 ? formatter(this._highlightedValue) + unit : translator("hints/nodata");
        } else {
            //Let the indicator "_default" in tree menu be translated differnetly for every hook type
            selectText = which === "_default" ? translator("indicator/_default/" + type) : concept.name;
        }

        this.el_select.text(selectText);

        // hide info el if no data is available for it to make sense
        var hideInfoEl = !concept.description && !concept.sourceName && !concept.sourceLink;
        this.infoEl.classed("vzb-hidden", hideInfoEl);
    }

});

exports.default = IndPicker;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _dataconnected = __webpack_require__(59);

var _dataconnected2 = _interopRequireDefault(_dataconnected);

var _events = __webpack_require__(45);

var _events2 = _interopRequireDefault(_events);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*!
 * HOOK MODEL
 */

var Hook = _dataconnected2.default.extend({

  //some hooks can be important. like axis x and y
  //that means, if X or Y doesn't have data at some point, we can't show markers
  _important: false,

  objectLeafs: ['autogenerate'],
  dataConnectedChildren: ['use', 'which'],

  getClassDefaults: function getClassDefaults() {
    var defaults = {
      data: 'data',
      which: null
    };
    return utils.deepExtend(this._super(), defaults);
  },

  buildScale: function buildScale() {
    //overloaded by specific hook models, like axis and color
  },

  /**
   * After complete model tree is created, this allows models to listen to eachother. 
   */
  setInterModelListeners: function setInterModelListeners() {
    var _this2 = this;

    var spaceRefs = this._parent.getSpace(this);

    //check what we want to hook this model to
    utils.forEach(spaceRefs, function (name) {
      //hook with the closest prefix to this model
      _this2._space[name] = _this2.getClosestModel(name);
      //if hooks change, this should load again
      _this2._space[name].on('dataConnectedChange', _this2.handleDataConnectedChange.bind(_this2));
    });
    this.getClosestModel('locale').on('dataConnectedChange', this.handleDataConnectedChange.bind(this));
  },

  onSuccessfullLoad: function onSuccessfullLoad() {
    this.buildScale();
    this._super();
  },

  setWhich: function setWhich(newValue) {

    var obj = { which: newValue.concept };

    if (newValue.dataSource) obj.data = newValue.dataSource;
    var newDataSource = this.getClosestModel(obj.data || this.data);
    var conceptProps = newDataSource.getConceptprops(newValue.concept);

    if (newValue.which === "_default") {
      obj.use = "constant";
    } else {
      if (conceptProps.use) obj.use = conceptProps.use;
    }

    if (conceptProps.scales) {
      obj.scaleType = conceptProps.scales[0];
    }

    if (this.getType() === 'axis' || this.getType() === 'size') {
      obj.domainMin = null;
      obj.domainMax = null;
      obj.zoomedMin = null;
      obj.zoomedMax = null;
    }

    this.set(obj);
  },

  setScaleType: function setScaleType(newValue) {
    this.buildScale(newValue);
  },

  preloadData: function preloadData() {
    this.dataSource = this.getClosestModel(this.data);
    return this._super();
  },

  afterPreload: function afterPreload() {
    if (this.which == null && this.autogenerate) {
      this.which = this.dataSource.getConceptByIndex(this.autogenerate.conceptIndex, this.autogenerate.conceptType).concept;
    }
  },

  /**
   * Hooks loads data, models ask children to load data
   * Basically, this method:
   * loads is theres something to be loaded:
   * does not load if there's nothing to be loaded
   * @param {Object} options (includes splashScreen)
   * @returns defer
   */
  loadData: function loadData() {
    var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};


    // then start loading data

    if (!this.which) return Promise.resolve();

    this.trigger('hook_change');

    // TODO: should be set on data source switch, but load happens before change events
    this.dataSource = this.getClosestModel(this.data);

    var query = this.getQuery(opts.splashScreen);

    if (query === true) return Promise.resolve();

    //useful to check if in the middle of a load call
    this._loadCall = true;

    this.setReady(false);

    utils.timeStamp('Vizabi Model: Loading Data: ' + this._id);

    var parsers = this._getAllParsers();
    var dataPromise = this.dataSource.load(query, parsers);

    dataPromise.then(this.afterLoad.bind(this), function (err) {
      return utils.warn('Problem with query: ', err, JSON.stringify(query));
    });

    return dataPromise;
  },

  handleDataConnectedChange: function handleDataConnectedChange(evt) {
    var _this3 = this;

    //defer is necessary because other events might be queued.
    //load right after such events
    utils.defer(function () {
      _this3.startLoading().catch(utils.warn);
    });
  },

  _isLoading: function _isLoading() {
    return !this._loadedOnce || this._loadCall;
  },

  /**
   * executes after data has actually been loaded
   */
  afterLoad: function afterLoad(dataId) {
    this._dataId = dataId;
    utils.timeStamp('Vizabi Model: Data loaded: ' + this._id);
  },

  /**
   * gets query that this model/hook needs to get data
   * @returns {Array} query
   */
  getQuery: function getQuery(splashScreen) {
    var _this = this;

    var dimensions, filters, select, from, order_by, q, animatable;

    //error if there's nothing to hook to
    if (Object.keys(this._space).length < 1) {
      utils.error('Error:', this._id, 'can\'t find the space');
      return true;
    }

    var prop = this.use === "property" || this.use === "constant";
    var exceptions = prop ? { exceptType: 'time' } : {};

    // select
    // we remove this.which from values if it duplicates a dimension
    var allDimensions = this._getAllDimensions(exceptions);
    var dimensions = prop && allDimensions.length > 1 ? [this.spaceRef ? this._space[this.spaceRef].dim : this.which] : allDimensions;

    dimensions = dimensions.filter(function (f) {
      return f !== "_default";
    });
    if (!dimensions || !dimensions.length) {
      utils.warn('getQuery() produced no query because no keys are available');
      return true;
    }

    select = {
      key: dimensions,
      value: dimensions.indexOf(this.which) != -1 || this.use === "constant" ? [] : [this.which]
    };

    // animatable
    animatable = this._getFirstDimension({ type: "time" });

    // from
    from = prop ? "entities" : "datapoints";

    // where
    filters = this._getAllFilters(exceptions, splashScreen);
    if (prop && allDimensions.length > 1) {
      var f = {};
      if (filters[dimensions]) f[dimensions] = filters[dimensions];
      filters = f;
    }

    // make root $and explicit
    var explicitAndFilters = {};
    if (Object.keys(filters).length > 0) {
      explicitAndFilters['$and'] = [];
      for (var filterKey in filters) {
        var filter = {};
        filter[filterKey] = filters[filterKey];
        explicitAndFilters['$and'].push(filter);
      }
    }

    // join
    var join = this._getAllJoins(exceptions, splashScreen);
    if (prop && allDimensions.length > 1) {
      var j = {};
      if (join["$" + dimensions]) j["$" + dimensions] = join["$" + dimensions];
      join = j;
    }

    //return query
    return {
      'language': this.getClosestModel('locale').id,
      'from': from,
      'animatable': animatable,
      'select': select,
      'where': explicitAndFilters,
      'join': join,
      'order_by': prop ? ["rank"] : [this._space.time.dim]
    };
  },

  /**
   * gets all hook dimensions
   * @param {Object} opts options with exceptType or onlyType
   * @returns {Array} all unique dimensions
   */
  _getAllDimensions: function _getAllDimensions(opts) {

    // hook dimensions = marker dimensions. Later, hooks might have extra dimensions : )
    return this._parent._getAllDimensions(opts);
  },

  /**
   * gets first dimension that matches type
   * @param {Object} options
   * @returns {Array} all unique dimensions
   */
  _getFirstDimension: function _getFirstDimension(opts) {

    // hook dimensions = marker dimensions. Later, hooks might have extra dimensions : )
    return this._parent._getFirstDimension(opts);
  },

  /**
   * gets all hook filters
   * @param {Boolean} splashScreen get filters for first screen only
   * @returns {Object} filters
   */
  _getAllFilters: function _getAllFilters(opts, splashScreen) {
    opts = opts || {};
    var filters = {};
    var _this = this;
    utils.forEach(this._space, function (h) {
      if (opts.exceptType && h.getType() === opts.exceptType) {
        return true;
      }
      if (opts.onlyType && h.getType() !== opts.onlyType) {
        return true;
      }
      // if query's dimensions are the same as the hook's, no join
      if (utils.arrayEquals(_this._getAllDimensions(opts), [h.getDimension()])) {
        filters = utils.extend(filters, h.getFilter(splashScreen));
      } else {
        var joinFilter = h.getFilter(splashScreen);
        if (joinFilter != null && !utils.isEmpty(joinFilter)) {
          var filter = {};
          filter[h.getDimension()] = "$" + h.getDimension();
          filters = utils.extend(filters, filter);
        }
      }
    });
    return filters;
  },

  _getAllJoins: function _getAllJoins(opts, splashScreen) {
    var joins = {};
    var _this = this;
    utils.forEach(this._space, function (h) {
      if (opts.exceptType && h.getType() === opts.exceptType) {
        return true;
      }
      if (opts.onlyType && h.getType() !== opts.onlyType) {
        return true;
      }
      if (utils.arrayEquals(_this._getAllDimensions(opts), [h.getDimension()])) {
        return true;
      }
      var filter = h.getFilter(splashScreen);
      if (filter != null && !utils.isEmpty(filter)) {
        joins["$" + h.getDimension()] = {
          key: h.getDimension(),
          where: h.getFilter(splashScreen)
        };
      }
    });
    return joins;
  },

  /**
   * gets all hook filters
   * @returns {Object} filters
   */
  _getAllParsers: function _getAllParsers() {

    var parsers = {};

    function addParser(model) {
      // get parsers from model
      var parser = model.getParser();
      var column = model.getDimensionOrWhich();
      if (parser && column) {
        parsers[column] = parser;
      }
    }

    // loop through all models which can have filters
    utils.forEach(this._space, function (h) {
      addParser(h);
    });
    addParser(this);

    return parsers;
  },

  /**
   * Gets tick values for this hook
   * @returns {Number|String} value The value for this tick
   */
  getTickFormatter: function getTickFormatter() {

    var _this = this;
    var SHARE = "share";
    var PERCENT = "percent";

    // percentageMode works like rounded if set to SHARE, but multiplies by 100 and suffixes with "%"
    // percentageMode works like rounded if set to PERCENT, but suffixes with "%"

    return function format(x, index, removePrefix, percentageMode) {

      percentageMode = _this.getConceptprops().format;
      if (percentageMode === SHARE) x *= 100;

      // Format time values
      // Assumption: a hook has always time in its space
      if (utils.isDate(x)) return _this._space.time.formatDate(x);

      // Dealing with values that are supposed to be time
      if (_this.scaleType === "time" && !utils.isDate(x)) {
        return _this._space.time.formatDate(new Date(x));
      }

      // Strings, null, NaN and undefined are bypassing any formatter
      if (utils.isString(x) || !x && x !== 0) return x;

      if (Math.abs(x) < 0.00000000000001) return "0";

      var format = "r"; //rounded format. use "f" for fixed
      var prec = 3; //round to so many significant digits

      var prefix = "";
      if (removePrefix) return d3.format("." + prec + format)(x);

      //---------------------
      // BEAUTIFIERS GO HOME!
      // don't break formatting please
      //---------------------
      // the tiny constant compensates epsilon-error when doing logsrithms
      switch (Math.floor(Math.log(Math.abs(x)) / Math.LN10 + 0.00000000000001)) {
        case -13:
          x = x * 1000000000000;prefix = "p";break; //0.1p
        case -10:
          x = x * 1000000000;prefix = "n";break; //0.1n
        case -7:
          x = x * 1000000;prefix = "µ";break; //0.1µ
        case -6:
          x = x * 1000000;prefix = "µ";break; //1µ
        case -5:
          x = x * 1000000;prefix = "µ";break; //10µ
        case -4:
          break; //0.0001
        case -3:
          break; //0.001
        case -2:
          break; //0.01
        case -1:
          break; //0.1
        case 0:
          break; //1
        case 1:
          break; //10
        case 2:
          break; //100
        case 3:
          break; //1000
        case 4:
          x = x / 1000;prefix = "k";break; //10k
        case 5:
          x = x / 1000;prefix = "k";break; //100k
        case 6:
          x = x / 1000000;prefix = "M";break; //1M
        case 7:
          x = x / 1000000;prefix = "M";break; //10M
        case 8:
          x = x / 1000000;prefix = "M";break; //100M
        case 9:
          x = x / 1000000000;prefix = "B";break; //1B
        case 10:
          x = x / 1000000000;prefix = "B";break; //10B
        case 11:
          x = x / 1000000000;prefix = "B";break; //100B
        case 12:
          x = x / 1000000000000;prefix = "TR";break; //1TR
        case 13:
          x = x / 1000000000000;prefix = "TR";break; //10TR
        case 14:
          x = x / 1000000000000;prefix = "TR";break; //100TR
        //use the D3 SI formatting for the extreme cases
        default:
          return d3.format("." + prec + "s")(x).replace("G", "B");
      }

      var formatted = d3.format("." + prec + format)(x);
      //remove trailing zeros if dot exists to avoid numbers like 1.0M, 3.0B, 1.500, 0.9700, 0.0
      if (formatted.indexOf(".") > -1) formatted = formatted.replace(/0+$/, "").replace(/\.$/, "");

      // use manual formatting for the cases above
      return formatted + prefix + (percentageMode === PERCENT || percentageMode === SHARE ? "%" : "");
    };
  },

  /**
   * Gets the d3 scale for this hook. if no scale then builds it
   * @returns {Array} domain
   */
  getScale: function getScale() {
    if (this.scale == null) console.warn('scale is null');
    return this.scale;
  },

  /**
  * Gets unique values in a column
  * @param {String|Array} attr parameter
  * @returns {Array} unique values
  */
  getUnique: function getUnique(attr) {
    if (!this.isHook()) return;
    if (!attr) attr = this._getFirstDimension({ type: "time" });
    return this.dataSource.getData(this._dataId, 'unique', attr);
  },

  getData: function getData() {
    return this.dataSource.getData(this._dataId);
  },

  /**
  * gets dataset without null or nan values with respect to this hook's which
  * @returns {Object} filtered items object
  */
  getValidItems: function getValidItems() {
    return this.dataSource.getData(this._dataId, 'valid', this.which);
  },

  /**
   * gets nested dataset
   * @param {Array} keys define how to nest the set
   * @returns {Object} hash-map of key-value pairs
   */
  getNestedItems: function getNestedItems(keys) {
    if (!keys) return utils.warn("No keys provided to getNestedItems(<keys>)");
    return this.dataSource.getData(this._dataId, 'nested', keys);
  },

  getHaveNoDataPointsPerKey: function getHaveNoDataPointsPerKey() {
    return this.dataSource.getData(this._dataId, 'haveNoDataPointsPerKey', this.which);
  },

  /**
   * Gets limits
   * @param {String} attr parameter
   * @returns {Object} limits (min and max)
   */
  getLimits: function getLimits(attr) {
    return this.dataSource.getData(this._dataId, 'limits', attr);
  },

  getFrame: function getFrame(steps, forceFrame, selected) {
    return this.dataSource.getFrame(this._dataId, steps, forceFrame, selected);
  },

  getFrames: function getFrames(steps, selected) {
    return this.dataSource.getFrames(this._dataId, steps, selected);
  },

  /**
   * gets hook values according dimension values
   */
  getItems: function getItems() {
    var _this = this;
    var dim = this.spaceRef && this._space[this.spaceRef] ? this._space[this.spaceRef].dim : _this._getFirstDimension({ exceptType: "time" });
    var items = {};
    this.getValidItems().forEach(function (d) {
      items[d[dim]] = d[_this.which];
    });
    return items;
  },

  getLimitsByDimensions: function getLimitsByDimensions(dims) {
    var filtered = this.dataSource.getData(this._dataId, 'nested', dims);
    var values = {};
    var limitsDim = {};
    var attr = this.which;

    var countLimits = function countLimits(items, limitsDim, id) {

      var filtered = items.reduce(function (filtered, d) {

        // check for dates
        var f = utils.isDate(d[attr]) ? d[attr] : parseFloat(d[attr]);

        // if it is a number
        if (!isNaN(f)) {
          filtered.push(f);
        }

        //filter
        return filtered;
      }, []);

      // get min/max for the filtered rows
      var min;
      var max;
      var limits = {};
      for (var i = 0; i < filtered.length; i += 1) {
        var c = filtered[i];
        if (typeof min === 'undefined' || c < min) {
          min = c;
        }
        if (typeof max === 'undefined' || c > max) {
          max = c;
        }
      }
      limits.min = min || 0;
      limits.max = max || 100;
      limitsDim[id] = limits;
    };

    var iterateGroupKeys = function iterateGroupKeys(data, deep, result, cb) {
      deep--;
      utils.forEach(data, function (d, id) {
        if (deep) {
          result[id] = {};
          iterateGroupKeys(d, deep, result[id], cb);
        } else {
          cb(d, result, id);
        }
      });
    };

    iterateGroupKeys(filtered, dims.length, limitsDim, countLimits);

    return limitsDim;
  },

  /**
   * Gets the concept properties of the hook's "which"
   * @returns {Object} concept properties
   */
  getConceptprops: function getConceptprops() {
    return this.use !== 'constant' && this.dataSource ? this.dataSource.getConceptprops(this.which) : {};
  },

  /**
   * Find if a current model is discrete
   * @returns {boolean} true if it's a discrete model, false if continious
   */
  isDiscrete: function isDiscrete() {
    return this.scaleType === "ordinal";
  },

  validate: function validate() {
    this._super();

    var allowedScales = this.getConceptprops().scales;
    if (allowedScales && allowedScales.length > 0 && !allowedScales.includes(this.scaleType)) {
      this.set({ scaleType: allowedScales[0] === "nominal" ? "ordinal" : allowedScales[0] }, null, false);
    }
  },

  getEntity: function getEntity() {
    return this._space[this.spaceRef ? this.spaceRef : this._parent.getSpace()[0]];
  }
});

exports.default = Hook;

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

module.exports = function(it, Constructor, name, forbiddenField){
  if(!(it instanceof Constructor) || (forbiddenField !== undefined && forbiddenField in it)){
    throw TypeError(name + ': incorrect invocation!');
  } return it;
};

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

module.exports = false;

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

// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])
var anObject    = __webpack_require__(3)
  , dPs         = __webpack_require__(165)
  , enumBugKeys = __webpack_require__(92)
  , IE_PROTO    = __webpack_require__(104)('IE_PROTO')
  , Empty       = function(){ /* empty */ }
  , PROTOTYPE   = 'prototype';

// Create object with fake `null` prototype: use iframe Object with cleared prototype
var createDict = function(){
  // Thrash, waste and sodomy: IE GC bug
  var iframe = __webpack_require__(91)('iframe')
    , i      = enumBugKeys.length
    , lt     = '<'
    , gt     = '>'
    , iframeDocument;
  iframe.style.display = 'none';
  __webpack_require__(94).appendChild(iframe);
  iframe.src = 'javascript:'; // eslint-disable-line no-script-url
  // createDict = iframe.contentWindow.Object;
  // html.removeChild(iframe);
  iframeDocument = iframe.contentWindow.document;
  iframeDocument.open();
  iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt);
  iframeDocument.close();
  createDict = iframeDocument.F;
  while(i--)delete createDict[PROTOTYPE][enumBugKeys[i]];
  return createDict();
};

module.exports = Object.create || function create(O, Properties){
  var result;
  if(O !== null){
    Empty[PROTOTYPE] = anObject(O);
    result = new Empty;
    Empty[PROTOTYPE] = null;
    // add "__proto__" for Object.getPrototypeOf polyfill
    result[IE_PROTO] = O;
  } else result = createDict();
  return Properties === undefined ? result : dPs(result, Properties);
};


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

// 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O)
var $keys      = __webpack_require__(167)
  , hiddenKeys = __webpack_require__(92).concat('length', 'prototype');

exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O){
  return $keys(O, hiddenKeys);
};

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

// 19.1.2.14 / 15.2.3.14 Object.keys(O)
var $keys       = __webpack_require__(167)
  , enumBugKeys = __webpack_require__(92);

module.exports = Object.keys || function keys(O){
  return $keys(O, enumBugKeys);
};

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

var redefine = __webpack_require__(18);
module.exports = function(target, src, safe){
  for(var key in src)redefine(target, key, src[key], safe);
  return target;
};

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

"use strict";
'use strict';
var global      = __webpack_require__(4)
  , dP          = __webpack_require__(9)
  , DESCRIPTORS = __webpack_require__(8)
  , SPECIES     = __webpack_require__(7)('species');

module.exports = function(KEY){
  var C = global[KEY];
  if(DESCRIPTORS && C && !C[SPECIES])dP.f(C, SPECIES, {
    configurable: true,
    get: function(){ return this; }
  });
};

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

var toInteger = __webpack_require__(43)
  , max       = Math.max
  , min       = Math.min;
module.exports = function(index, length){
  index = toInteger(index);
  return index < 0 ? max(index + length, 0) : min(index, length);
};

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

var id = 0
  , px = Math.random();
module.exports = function(key){
  return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));
};

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

exports.default = _component2.default.extend({

  init: function init(config, context) {
    this.template = '<span class="vzb-sc-holder vzb-dialog-checkbox"><input type="checkbox"><label></label></span>';
    var _this = this;
    this.name = 'gapminder-simplecheckbox';

    this.checkbox = config.checkbox;
    this.submodel = config.submodel;

    this.model_expects = [{
      name: "mdl"
      //TODO: learn how to expect model "axis" or "size" or "color"
    }, {
      name: "locale",
      type: "locale"
    }];

    this.model_binds = {
      "change:mdl": function changeMdl(evt) {
        _this.updateView();
      },
      "translate:locale": function translateLocale(evt) {
        _this.updateView();
      }
    };

    var submodel = this.submodel ? this.submodel + ':' : '';
    this.model_binds["change:mdl." + submodel + this.checkbox] = function () {
      _this.updateView();
    };

    //contructor is the same as any component
    this._super(config, context);
  },

  ready: function ready() {
    this.parentModel = this.submodel ? this.model.mdl[this.submodel] : this.model.mdl;
    this.updateView();
  },

  readyOnce: function readyOnce() {
    var _this = this;
    this.element = d3.select(this.element);
    var id = "-check-" + _this._id;
    this.labelEl = this.element.select('label').attr("for", id);
    this.checkEl = this.element.select('input').attr("id", id).on("change", function () {
      _this._setModel(d3.select(this).property("checked"));
    });
  },

  updateView: function updateView() {
    this.translator = this.model.locale.getTFunction();
    this.labelEl.text(this.translator("check/" + this.checkbox));
    this.checkEl.property("checked", !!this.parentModel[this.checkbox]);
  },

  _setModel: function _setModel(value) {
    this.parentModel[this.checkbox] = value;
  }

});

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _model = __webpack_require__(46);

var _model2 = _interopRequireDefault(_model);

var _events = __webpack_require__(45);

var _events2 = _interopRequireDefault(_events);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*!
 * DATACONNECTED MODEL
 *
 * Any model which may trigger a reload of data is here. Dimensions, Time, Hooks and Locales are DataConnected
 */

var DataConnected = _model2.default.extend({

  dataConnectedChildren: [],

  checkDataChanges: function checkDataChanges(changedChildren) {
    var _this = this;

    if (!changedChildren || !this.dataConnectedChildren) return;

    if (!utils.isArray(changedChildren) && utils.isObject(changedChildren)) changedChildren = Object.keys(changedChildren);

    if (changedChildren.length == 0 || this.dataConnectedChildren.length == 0) return;

    var dataConnectedChangedChildren = changedChildren.filter(function (child) {
      return _this.dataConnectedChildren.indexOf(child) !== -1;
    });

    if (dataConnectedChangedChildren.length > 0) {
      this.trigger('dataConnectedChange');
      this.startLoading();
    }
  }

});

exports.default = DataConnected;

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

// 22.1.3.31 Array.prototype[@@unscopables]
var UNSCOPABLES = __webpack_require__(7)('unscopables')
  , ArrayProto  = Array.prototype;
if(ArrayProto[UNSCOPABLES] == undefined)__webpack_require__(17)(ArrayProto, UNSCOPABLES, {});
module.exports = function(key){
  ArrayProto[UNSCOPABLES][key] = true;
};

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

var ctx         = __webpack_require__(35)
  , call        = __webpack_require__(161)
  , isArrayIter = __webpack_require__(96)
  , anObject    = __webpack_require__(3)
  , toLength    = __webpack_require__(12)
  , getIterFn   = __webpack_require__(113)
  , BREAK       = {}
  , RETURN      = {};
var exports = module.exports = function(iterable, entries, fn, that, ITERATOR){
  var iterFn = ITERATOR ? function(){ return iterable; } : getIterFn(iterable)
    , f      = ctx(fn, that, entries ? 2 : 1)
    , index  = 0
    , length, step, iterator, result;
  if(typeof iterFn != 'function')throw TypeError(iterable + ' is not iterable!');
  // fast case for arrays with default iterator
  if(isArrayIter(iterFn))for(length = toLength(iterable.length); length > index; index++){
    result = entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]);
    if(result === BREAK || result === RETURN)return result;
  } else for(iterator = iterFn.call(iterable); !(step = iterator.next()).done; ){
    result = call(iterator, f, step.value, entries);
    if(result === BREAK || result === RETURN)return result;
  }
};
exports.BREAK  = BREAK;
exports.RETURN = RETURN;

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

module.exports = {};

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

var def = __webpack_require__(9).f
  , has = __webpack_require__(15)
  , TAG = __webpack_require__(7)('toStringTag');

module.exports = function(it, tag, stat){
  if(it && !has(it = stat ? it : it.prototype, TAG))def(it, TAG, {configurable: true, value: tag});
};

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

var $export = __webpack_require__(0)
  , defined = __webpack_require__(29)
  , fails   = __webpack_require__(5)
  , spaces  = __webpack_require__(109)
  , space   = '[' + spaces + ']'
  , non     = '\u200b\u0085'
  , ltrim   = RegExp('^' + space + space + '*')
  , rtrim   = RegExp(space + space + '*$');

var exporter = function(KEY, exec, ALIAS){
  var exp   = {};
  var FORCE = fails(function(){
    return !!spaces[KEY]() || non[KEY]() != non;
  });
  var fn = exp[KEY] = FORCE ? exec(trim) : spaces[KEY];
  if(ALIAS)exp[ALIAS] = fn;
  $export($export.P + $export.F * FORCE, 'String', exp);
};

// 1 -> String#trimLeft
// 2 -> String#trimRight
// 3 -> String#trim
var trim = exporter.trim = function(string, TYPE){
  string = String(defined(string));
  if(TYPE & 1)string = string.replace(ltrim, '');
  if(TYPE & 2)string = string.replace(rtrim, '');
  return string;
};

module.exports = exporter;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/*!
 * VIZABI GENERIC SLIDER CONTROL
 * Reusable SLIDER
 */

var SimpleSlider = _component2.default.extend({

  init: function init(config, context) {
    this.template = '<div class="vzb-ss-holder"><input type="range" class="vzb-ss-slider vzb-ss-slider-normal" step="1"></div>';

    this.model_expects = [{
      name: "submodel"
    }];

    var _this = this;
    this.name = 'gapminder-simpleSlider';

    this.arg = config.arg;
    this.thumb_size = config.thumb_size;
    this.slider_properties = config.properties;

    this.model_binds = {};
    this.model_binds["change:submodel." + this.arg] = function (evt) {
      _this.updateView();
    };

    //contructor is the same as any component
    this._super(config, context);

    this._setModel = utils.throttle(this._setModel, 50);
  },

  /**
   * Executes after the template is loaded and rendered.
   * Ideally, it contains HTML instantiations related to template
   * At this point, this.element and this.placeholder are available as a d3 object
   */
  readyOnce: function readyOnce() {

    //default values
    var min = 0;
    var max = 1;
    var step = 0.1;
    var value = min;

    //selecting elements
    var _this = this;
    this.element = d3.select(this.element);
    this.slider = this.element.selectAll('.vzb-ss-slider');

    this.elementSize = this.element.node().getBoundingClientRect();
    this.sliderSize = this.slider.node().getBoundingClientRect();
    this.slider.style('left', this.elementSize.left - this.sliderSize.left + 'px');

    //TODO: replace this with utils.extend
    if (this.slider_properties) {
      if (this.slider_properties.min != null) min = this.slider_properties.min;
      if (this.slider_properties.max != null) max = this.slider_properties.max;
      if (this.slider_properties.step != null) step = this.slider_properties.step;

      if (this.slider_properties.scale) {
        value = this.slider_properties.scale(min);
      }
    }

    //step also defines the rounding of values that willbe sent to model: 0.1 --> 1 digit, 0.01 --> 2, 1 and up --> 0
    this.roundTo = step > 1 ? 0 : Math.round(Math.abs(Math.log(step) / Math.LN10));

    //check and change the slider's thumb size
    if (this.thumb_size) {
      this.slider.classed('vzb-ss-slider-normal', false);
      this.slider.classed('vzb-ss-slider-' + this.thumb_size, true);
    }

    this.slider.attr('min', min).attr('max', max).attr('step', step).attr('value', value).on('input', function () {
      var value = +d3.event.target.value;
      _this._setModel(value, false, false); // on drag - non-persistent changes while dragging
    }).on('change', function () {
      var value = +d3.event.target.value;
      _this._setModel(value, true); // on drag end - value is probably same as last 'input'-event, so force change
    });

    this.updateView();
  },

  updateView: function updateView() {
    var value = this.model.submodel[this.arg];
    var slider_properties = this.slider_properties;
    var scale;

    if (slider_properties) {
      scale = slider_properties.scale;
    }
    if (scale) {
      value = scale.invert(value);
    }

    //this.slider.attr('value', value);
    this.slider.node().value = value;
  },

  _setModel: function _setModel(value, force, persistent) {
    // rescale value if scale is supplied in slider_properties
    if (this.slider_properties && this.slider_properties.scale) value = this.slider_properties.scale(value);

    this.model.submodel.getModelObject(this.arg).set(value.toFixed(this.roundTo), force, persistent);
  }

});

exports.default = SimpleSlider;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); //d3.svg.dynamicBackground


var _class = __webpack_require__(21);

var _class2 = _interopRequireDefault(_class);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

exports.default = _class2.default.extend({

  init: function init(context, conditions) {
    this.context = context;
    this.width = 0;
    this.height = 0;
    this.topOffset = 0;
    this.leftOffset = 0;
    this.bottomOffset = 0;
    this.rightOffset = 0;
    this.textWidth = 0;
    this.textHeight = 0;
    this.widthRatio = 0.9;
    this.heightRatio = 0.9;
    this.xAlign = 'center';
    this.yAlign = 'center';
    this.element = this.context.append('text').style("font-size", '20px');

    this.element.text('0');
    this.letterBBox = this.element.node().getBBox();
    this.element.text('');

    if (conditions) {
      this.setConditions(conditions);
    }
  },

  setConditions: function setConditions(conditions) {
    if (!isNaN(parseFloat(conditions.rightOffset)) && isFinite(conditions.rightOffset)) {
      this.rightOffset = conditions.rightOffset;
    }
    if (!isNaN(parseFloat(conditions.leftOffset)) && isFinite(conditions.leftOffset)) {
      this.leftOffset = conditions.leftOffset;
    }
    if (!isNaN(parseFloat(conditions.topOffset)) && isFinite(conditions.topOffset)) {
      this.topOffset = conditions.topOffset;
    }
    if (!isNaN(parseFloat(conditions.bottomOffset)) && isFinite(conditions.bottomOffset)) {
      this.bottomOffset = conditions.bottomOffset;
    }
    if (conditions.xAlign) {
      this.xAlign = conditions.xAlign;
    }
    if (conditions.yAlign) {
      this.yAlign = conditions.yAlign;
    }
    if (!isNaN(parseFloat(conditions.widthRatio)) && conditions.widthRatio > 0 && conditions.widthRatio <= 1) {
      this.widthRatio = conditions.widthRatio;
    }
    if (!isNaN(parseFloat(conditions.heightRatio)) && conditions.heightRatio > 0 && conditions.heightRatio <= 1) {
      this.heightRatio = conditions.heightRatio;
    }
    return this;
  },

  resize: function resize(width, height, topOffset, leftOffset) {
    var _map = [width, height].map(function (v) {
      return Number(String(v).replace('px', ''));
    });

    var _map2 = _slicedToArray(_map, 2);

    this.width = _map2[0];
    this.height = _map2[1];


    if (topOffset) {
      this.topOffset = topOffset;
    }
    if (leftOffset) {
      this.leftOffset = leftOffset;
    }

    this._resizeText();
  },

  setText: function setText(text, delay) {
    var _this = this;

    setTimeout(function () {
      _this.element.selectAll('tspan').remove();
      text.split('').forEach(function (char, index) {
        _this.element.append('tspan').text(char).attr('x', (index - text.length / 2) * _this.letterBBox.width + _this.letterBBox.width / 2);
      });

      _this._resizeText();
    }, delay);

    return this;
  },

  _resizeText: function _resizeText() {

    var bbox = Object.assign(this.element.node().getBBox(), {
      width: this.letterBBox.width * this.element.text().length
    });

    if (!bbox.width || !bbox.height || !this.width || !this.height) return this;

    // method from http://stackoverflow.com/a/22580176
    var widthTransform = this.width * this.widthRatio / bbox.width;
    var heightTransform = this.height * this.heightRatio / bbox.height;
    this.scalar = widthTransform < heightTransform ? widthTransform : heightTransform;
    this.element.attr("transform", "scale(" + this.scalar + ")");

    this.textHeight = bbox.height * this.scalar;
    this.textWidth = bbox.width * this.scalar;

    switch (this.yAlign) {
      case 'bottom':
        this.context.style('dominant-baseline', 'central');break;
      case 'center':
        this.context.style('dominant-baseline', 'central');break;
      case 'top':
        this.context.style('dominant-baseline', 'initial');break;
    }

    this.context.attr("transform", "translate(" + this._getLeftOffset() + "," + this._getTopOffset() + ")");

    return this;
  },

  _getLeftOffset: function _getLeftOffset() {
    switch (this.xAlign) {
      case 'right':
        return this.width - this.textWidth / 2 - this.rightOffset;
        break;
      case 'left':
        return this.textWidth / 2 + this.leftOffset;
        break;
      default:
        return this.width / 2;
    }
  },

  _getTopOffset: function _getTopOffset() {
    switch (this.yAlign) {
      case 'top':
        return this.textHeight / 2 + this.topOffset;
        break;
      case 'bottom':
        return this.height - this.textHeight / 2 - this.bottomOffset;
        break;
      default:
        return this.height / 2;
    }
  }

});

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

// getting tag from 19.1.3.6 Object.prototype.toString()
var cof = __webpack_require__(28)
  , TAG = __webpack_require__(7)('toStringTag')
  // ES3 wrong here
  , ARG = cof(function(){ return arguments; }()) == 'Arguments';

// fallback for IE11 Script Access Denied error
var tryGet = function(it, key){
  try {
    return it[key];
  } catch(e){ /* empty */ }
};

module.exports = function(it){
  var O, T, B;
  return it === undefined ? 'Undefined' : it === null ? 'Null'
    // @@toStringTag case
    : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T
    // builtinTag case
    : ARG ? cof(O)
    // ES3 arguments fallback
    : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;
};

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

// fallback for non-array-like ES3 and non-enumerable old V8 strings
var cof = __webpack_require__(28);
module.exports = Object('z').propertyIsEnumerable(0) ? Object : function(it){
  return cof(it) == 'String' ? it.split('') : Object(it);
};

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

exports.f = {}.propertyIsEnumerable;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
var getDepth = function getDepth(key) {
  return key.match(/\//g).length;
};

var requireAll = function requireAll(_require, depth) {
  var keys = _require.keys();

  if (depth) {
    keys = keys.filter(typeof depth === 'function' ? function (key) {
      return depth(getDepth(key));
    } : function (key) {
      return getDepth(key) === depth + 1;
    });
  }

  return keys.reduce(function (result, key) {
    var name = /([^/]+)\..+$/.exec(key)[1];

    try {
      var required = _require(key);
      result[name] = required.default || required;
    } catch (err) {
      console.warn('Import error', key, err);
    }

    return result;
  }, {});
};

exports.default = requireAll;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _class = __webpack_require__(21);

var _class2 = _interopRequireDefault(_class);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/**
 * Initializes the reader.
 * @param {Object} reader_info Information about the reader
 */
var Reader = _class2.default.extend({
  init: function init(reader_info) {
    this._name = this._name || reader_info.reader;
    this._data = reader_info.data || [];
    this._basepath = this._basepath || reader_info.path || null;
  },

  /**
   * Reads from source
   * @param {Array} queries Queries to be performed
   * @param {Object} parsers object
   * @returns a promise that will be resolved when data is read
   */
  read: function read(query, parsers) {
    if (this._parsers) {
      this._data = utils.mapRows(this._data, this._parsers);
    }
    return Promise.resolve(this._data);
  }
});

exports.default = Reader;

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

// false -> Array#indexOf
// true  -> Array#includes
var toIObject = __webpack_require__(20)
  , toLength  = __webpack_require__(12)
  , toIndex   = __webpack_require__(56);
module.exports = function(IS_INCLUDES){
  return function($this, el, fromIndex){
    var O      = toIObject($this)
      , length = toLength(O.length)
      , index  = toIndex(fromIndex, length)
      , value;
    // Array#includes uses SameValueZero equality algorithm
    if(IS_INCLUDES && el != el)while(length > index){
      value = O[index++];
      if(value != value)return true;
    // Array#toIndex ignores holes, Array#includes - not
    } else for(;length > index; index++)if(IS_INCLUDES || index in O){
      if(O[index] === el)return IS_INCLUDES || index || 0;
    } return !IS_INCLUDES && -1;
  };
};

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

"use strict";
'use strict';
var global            = __webpack_require__(4)
  , $export           = __webpack_require__(0)
  , redefine          = __webpack_require__(18)
  , redefineAll       = __webpack_require__(54)
  , meta              = __webpack_require__(41)
  , forOf             = __webpack_require__(61)
  , anInstance        = __webpack_require__(49)
  , isObject          = __webpack_require__(6)
  , fails             = __webpack_require__(5)
  , $iterDetect       = __webpack_require__(78)
  , setToStringTag    = __webpack_require__(63)
  , inheritIfRequired = __webpack_require__(95);

module.exports = function(NAME, wrapper, methods, common, IS_MAP, IS_WEAK){
  var Base  = global[NAME]
    , C     = Base
    , ADDER = IS_MAP ? 'set' : 'add'
    , proto = C && C.prototype
    , O     = {};
  var fixMethod = function(KEY){
    var fn = proto[KEY];
    redefine(proto, KEY,
      KEY == 'delete' ? function(a){
        return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a);
      } : KEY == 'has' ? function has(a){
        return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a);
      } : KEY == 'get' ? function get(a){
        return IS_WEAK && !isObject(a) ? undefined : fn.call(this, a === 0 ? 0 : a);
      } : KEY == 'add' ? function add(a){ fn.call(this, a === 0 ? 0 : a); return this; }
        : function set(a, b){ fn.call(this, a === 0 ? 0 : a, b); return this; }
    );
  };
  if(typeof C != 'function' || !(IS_WEAK || proto.forEach && !fails(function(){
    new C().entries().next();
  }))){
    // create collection constructor
    C = common.getConstructor(wrapper, NAME, IS_MAP, ADDER);
    redefineAll(C.prototype, methods);
    meta.NEED = true;
  } else {
    var instance             = new C
      // early implementations not supports chaining
      , HASNT_CHAINING       = instance[ADDER](IS_WEAK ? {} : -0, 1) != instance
      // V8 ~  Chromium 40- weak-collections throws on primitives, but should return false
      , THROWS_ON_PRIMITIVES = fails(function(){ instance.has(1); })
      // most early implementations doesn't supports iterables, most modern - not close it correctly
      , ACCEPT_ITERABLES     = $iterDetect(function(iter){ new C(iter); }) // eslint-disable-line no-new
      // for early implementations -0 and +0 not the same
      , BUGGY_ZERO = !IS_WEAK && fails(function(){
        // V8 ~ Chromium 42- fails only with 5+ elements
        var $instance = new C()
          , index     = 5;
        while(index--)$instance[ADDER](index, index);
        return !$instance.has(-0);
      });
    if(!ACCEPT_ITERABLES){ 
      C = wrapper(function(target, iterable){
        anInstance(target, C, NAME);
        var that = inheritIfRequired(new Base, target, C);
        if(iterable != undefined)forOf(iterable, IS_MAP, that[ADDER], that);
        return that;
      });
      C.prototype = proto;
      proto.constructor = C;
    }
    if(THROWS_ON_PRIMITIVES || BUGGY_ZERO){
      fixMethod('delete');
      fixMethod('has');
      IS_MAP && fixMethod('get');
    }
    if(BUGGY_ZERO || HASNT_CHAINING)fixMethod(ADDER);
    // weak collections should not contains .clear method
    if(IS_WEAK && proto.clear)delete proto.clear;
  }

  setToStringTag(C, NAME);

  O[NAME] = C;
  $export($export.G + $export.W + $export.F * (C != Base), O);

  if(!IS_WEAK)common.setStrong(C, NAME, IS_MAP);

  return C;
};

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

"use strict";
'use strict';
var hide     = __webpack_require__(17)
  , redefine = __webpack_require__(18)
  , fails    = __webpack_require__(5)
  , defined  = __webpack_require__(29)
  , wks      = __webpack_require__(7);

module.exports = function(KEY, length, exec){
  var SYMBOL   = wks(KEY)
    , fns      = exec(defined, SYMBOL, ''[KEY])
    , strfn    = fns[0]
    , rxfn     = fns[1];
  if(fails(function(){
    var O = {};
    O[SYMBOL] = function(){ return 7; };
    return ''[KEY](O) != 7;
  })){
    redefine(String.prototype, KEY, strfn);
    hide(RegExp.prototype, SYMBOL, length == 2
      // 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue)
      // 21.2.5.11 RegExp.prototype[@@split](string, limit)
      ? function(string, arg){ return rxfn.call(string, this, arg); }
      // 21.2.5.6 RegExp.prototype[@@match](string)
      // 21.2.5.9 RegExp.prototype[@@search](string)
      : function(string){ return rxfn.call(string, this); }
    );
  }
};

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

"use strict";
'use strict';
// 21.2.5.3 get RegExp.prototype.flags
var anObject = __webpack_require__(3);
module.exports = function(){
  var that   = anObject(this)
    , result = '';
  if(that.global)     result += 'g';
  if(that.ignoreCase) result += 'i';
  if(that.multiline)  result += 'm';
  if(that.unicode)    result += 'u';
  if(that.sticky)     result += 'y';
  return result;
};

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

// fast apply, http://jsperf.lnkit.com/fast-apply/5
module.exports = function(fn, args, that){
  var un = that === undefined;
  switch(args.length){
    case 0: return un ? fn()
                      : fn.call(that);
    case 1: return un ? fn(args[0])
                      : fn.call(that, args[0]);
    case 2: return un ? fn(args[0], args[1])
                      : fn.call(that, args[0], args[1]);
    case 3: return un ? fn(args[0], args[1], args[2])
                      : fn.call(that, args[0], args[1], args[2]);
    case 4: return un ? fn(args[0], args[1], args[2], args[3])
                      : fn.call(that, args[0], args[1], args[2], args[3]);
  } return              fn.apply(that, args);
};

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

// 7.2.8 IsRegExp(argument)
var isObject = __webpack_require__(6)
  , cof      = __webpack_require__(28)
  , MATCH    = __webpack_require__(7)('match');
module.exports = function(it){
  var isRegExp;
  return isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : cof(it) == 'RegExp');
};

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

var ITERATOR     = __webpack_require__(7)('iterator')
  , SAFE_CLOSING = false;

try {
  var riter = [7][ITERATOR]();
  riter['return'] = function(){ SAFE_CLOSING = true; };
  Array.from(riter, function(){ throw 2; });
} catch(e){ /* empty */ }

module.exports = function(exec, skipClosing){
  if(!skipClosing && !SAFE_CLOSING)return false;
  var safe = false;
  try {
    var arr  = [7]
      , iter = arr[ITERATOR]();
    iter.next = function(){ return {done: safe = true}; };
    arr[ITERATOR] = function(){ return iter; };
    exec(arr);
  } catch(e){ /* empty */ }
  return safe;
};

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

// Forced replacement prototype accessors methods
module.exports = __webpack_require__(50)|| !__webpack_require__(5)(function(){
  var K = Math.random();
  // In FF throws only define methods
  __defineSetter__.call(null, K, function(){ /* empty */});
  delete __webpack_require__(4)[K];
});

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

exports.f = Object.getOwnPropertySymbols;

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

var global = __webpack_require__(4)
  , SHARED = '__core-js_shared__'
  , store  = global[SHARED] || (global[SHARED] = {});
module.exports = function(key){
  return store[key] || (store[key] = {});
};

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

var global = __webpack_require__(4)
  , hide   = __webpack_require__(17)
  , uid    = __webpack_require__(57)
  , TYPED  = uid('typed_array')
  , VIEW   = uid('view')
  , ABV    = !!(global.ArrayBuffer && global.DataView)
  , CONSTR = ABV
  , i = 0, l = 9, Typed;

var TypedArrayConstructors = (
  'Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array'
).split(',');

while(i < l){
  if(Typed = global[TypedArrayConstructors[i++]]){
    hide(Typed.prototype, TYPED, true);
    hide(Typed.prototype, VIEW, true);
  } else CONSTR = false;
}

module.exports = {
  ABV:    ABV,
  CONSTR: CONSTR,
  TYPED:  TYPED,
  VIEW:   VIEW
};

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*!
 * VIZABI BUBBLE SIZE slider
 * Reusable bubble size slider
 */

var OPTIONS = {
  EXTENT_MIN: 0,
  EXTENT_MAX: 1,
  TEXT_PARAMS: { TOP: 11, LEFT: 10, MAX_WIDTH: 42, MAX_HEIGHT: 16 },
  BAR_WIDTH: 6,
  THUMB_RADIUS: 10,
  THUMB_STROKE_WIDTH: 4,
  INTRO_DURATION: 250
};

var profiles = {
  "small": {
    minRadius: 0.5,
    maxRadius: 40
  },
  "medium": {
    minRadius: 1,
    maxRadius: 55
  },
  "large": {
    minRadius: 1,
    maxRadius: 65
  }
};

var BubbleSize = _component2.default.extend({

  /**
   * Initializes the timeslider.
   * Executed once before any template is rendered.
   * @param config The options passed to the component
   * @param context The component's parent
   */
  init: function init(config, context) {

    this.name = 'bubblesize';

    this.template = this.template || __webpack_require__(422);

    this.model_expects = [{
      name: "size",
      type: "size"
    }];

    var _this = this;
    this.model_binds = {
      'change:size.domainMin': changeMinMaxHandler,
      'change:size.domainMax': changeMinMaxHandler,
      'change:size.extent': changeMinMaxHandler,
      'ready': readyHandler
    };
    function changeMinMaxHandler(evt, path) {
      var size = _this.model.size.extent || [OPTIONS.EXTENT_MIN, OPTIONS.EXTENT_MAX];
      _this._updateLabels(size);
      _this.sliderEl.call(_this.brush.extent(size));
      if (size[0] == size[1]) {
        _this.sliderEl.selectAll(".resize").style("display", "block");
      }
    }
    function readyHandler(evt) {
      _this.sizeScaleMinMax = _this.model.size.getScale().domain();
      _this._setLabelsText();
    }

    this._setModel = utils.throttle(this._setModel, 50);
    //contructor is the same as any component
    this._super(config, context);
  },

  /**
   * Executes after the template is loaded and rendered.
   * Ideally, it contains HTML instantiations related to template
   * At this point, this.element and this.placeholder are available as a d3 object
   */
  readyOnce: function readyOnce() {
    var _this = this;
    var values = _this.model.size.extent || [OPTIONS.EXTENT_MIN, OPTIONS.EXTENT_MAX];
    this.showArcs = _this.model.size.showArcs !== false;

    this.element = d3.select(this.element);
    this.sliderSvg = this.element.select(".vzb-bs-svg");
    this.sliderWrap = this.sliderSvg.select(".vzb-bs-slider-wrap");
    this.sliderEl = this.sliderWrap.select(".vzb-bs-slider");

    var textMargin = { v: OPTIONS.TEXT_PARAMS.TOP, h: OPTIONS.TEXT_PARAMS.LEFT },
        textMaxWidth = OPTIONS.TEXT_PARAMS.MAX_WIDTH,
        textMaxHeight = OPTIONS.TEXT_PARAMS.MAX_HEIGHT,
        barWidth = OPTIONS.BAR_WIDTH,
        thumbRadius = OPTIONS.THUMB_RADIUS,
        thumbStrokeWidth = OPTIONS.THUMB_STROKE_WIDTH,
        padding = {
      top: thumbStrokeWidth,
      left: textMargin.h + textMaxWidth,
      right: textMargin.h + textMaxWidth,
      bottom: barWidth + textMaxHeight
    };

    this.padding = padding;

    var minMaxBubbleRadius = this.getMinMaxBubbleRadius();

    this.xScale = d3.scale.linear().domain([OPTIONS.EXTENT_MIN, OPTIONS.EXTENT_MAX]).range([minMaxBubbleRadius.min * 2, minMaxBubbleRadius.max * 2]).clamp(true);

    this.brush = d3.svg.brush().x(this.xScale).extent([OPTIONS.EXTENT_MIN, OPTIONS.EXTENT_MIN]).on("brush", function () {
      _this._setFromExtent(true, false, false); // non persistent change
    }).on("brushend", function () {
      _this.sliderEl.selectAll(".resize").style("display", null);

      _this._setFromExtent(true, true); // force a persistent change
    });

    this.sliderEl.call(_this.brush);

    this.sliderEl.selectAll('.background').attr('style', '');

    //For return to round thumbs
    //var thumbArc = d3.svg.arc()
    //  .outerRadius(thumbRadius)
    //  .startAngle(0)
    //  .endAngle(2 * Math.PI)

    this.sliderThumbs = this.sliderEl.selectAll(".resize").sort(d3.descending).classed("vzb-bs-slider-thumb", true);

    this.sliderThumbs.append("g").attr("class", "vzb-bs-slider-thumb-badge").append("path").attr("d", "M0 " + barWidth * .5 + "l" + -thumbRadius + " " + thumbRadius * 1.5 + "h" + thumbRadius * 2 + "Z");

    //For return to circles
    //.attr("d", "M0 0 l" + (thumbRadius * 2) + " " + (-thumbRadius) + "v" + (thumbRadius * 2) + "Z")

    //For return to round thumbs
    //.attr("d", thumbArc)

    if (_this.showArcs) {
      this.sliderThumbs.append("path").attr("class", "vzb-bs-slider-thumb-arc");
    }
    this.sliderEl.selectAll("text").data([0, 0]).enter().append("text").attr("class", "vzb-bs-slider-thumb-label").attr("text-anchor", function (d, i) {
      return i ? "start" : "end";
    }).attr("dy", function (d, i) {
      return i ? "-0.7em" : "1.4em";
    });

    this.sliderLabelsEl = this.sliderEl.selectAll("text.vzb-bs-slider-thumb-label");

    this.sliderEl.selectAll("rect").attr("height", barWidth).attr("rx", barWidth * 0.25).attr("ry", barWidth * 0.25).attr("transform", "translate(0," + -barWidth * 0.5 + ")");
    this.sliderEl.select(".extent").classed("vzb-bs-slider-extent", true);

    //For return to circles
    // var circleLabelTransform = function(d, i) {
    //    var dX = i ? textMargin.h + _this.xScale(d) : -textMargin.h,
    //        dY = -textMargin.v;
    //    return "translate(" + (dX) + "," + (dY) + ")";
    // }

    this.on("resize", function () {
      //console.log("EVENT: resize");

      _this.xScale.range([_this.getMinMaxBubbleRadius().min * 2, _this.getMinMaxBubbleRadius().max * 2]);
      _this._updateSize();

      _this.sliderEl.call(_this.brush.extent(_this.brush.extent()));
      _this._setFromExtent(false, false, false); // non persistent change
    });

    this._updateSize();
    this.sliderEl.call(this.brush.extent(values));
    _this._setFromExtent(false, false, false); // non persistent change

    _this.sizeScaleMinMax = _this.model.size.getScale().domain();

    if (_this.sizeScaleMinMax) {
      _this._setLabelsText();
    }
  },

  getMinMaxBubbleRadius: function getMinMaxBubbleRadius() {
    return { min: profiles[this.getLayoutProfile()].minRadius, max: profiles[this.getLayoutProfile()].maxRadius };
  },

  /*
   * RESIZE:
   * Executed whenever the container is resized
   */
  _updateSize: function _updateSize() {
    var maxBubbleRadius = this.showArcs ? this.getMinMaxBubbleRadius().max : OPTIONS.TEXT_PARAMS.TOP * 2;
    this.sliderSvg.attr("height", maxBubbleRadius + this.padding.top + this.padding.bottom).attr("width", this.getMinMaxBubbleRadius().max * 2 + this.padding.left + this.padding.right);
    this.sliderWrap.attr("transform", "translate(" + this.padding.left + "," + (maxBubbleRadius + this.padding.top) + ")");
  },

  _updateArcs: function _updateArcs(s) {
    if (!this.showArcs) return;
    var _this = this;
    var valueArc = d3.svg.arc().outerRadius(function (d) {
      return _this.xScale(d) * 0.5;
    }).innerRadius(function (d) {
      return _this.xScale(d) * 0.5;
    }).startAngle(-Math.PI * 0.5).endAngle(Math.PI * 0.5);
    this.sliderThumbs.select('.vzb-bs-slider-thumb-arc').data(s).attr("d", valueArc).attr("transform", function (d) {
      return "translate(" + -_this.xScale(d) * 0.5 + ",0)";
    });
  },

  _updateLabels: function _updateLabels(s) {
    var _this = this;
    var arcLabelTransform = function arcLabelTransform(d, i) {
      var textMargin = { v: OPTIONS.TEXT_PARAMS.TOP, h: OPTIONS.TEXT_PARAMS.LEFT },
          dX = textMargin.h * (i ? .5 : -1.0) + _this.xScale(d),
          dY = 0;
      return "translate(" + dX + "," + dY + ")";
    };
    this.sliderLabelsEl.data(s).attr("transform", arcLabelTransform);
  },

  _setLabelsText: function _setLabelsText() {
    var _this = this;
    _this.sliderLabelsEl.data([_this.model.size.getTickFormatter()(_this.sizeScaleMinMax[0]), _this.model.size.getTickFormatter()(_this.sizeScaleMinMax[1])]).text(function (d) {
      return d;
    });
  },

  /**
   * Prepares setting of the current model with the values from extent.
   * @param {boolean} set model
   * @param {boolean} force force firing the change event
   * @param {boolean} persistent sets the persistency of the change event
   */
  _setFromExtent: function _setFromExtent(setModel, force, persistent) {
    var s = this.brush.extent();
    this._updateArcs(s);
    this._updateLabels(s);
    if (setModel) this._setModel(s, force, persistent);
  },

  /**
   * Sets the current value in model. avoid updating more than once in framerate
   * @param {number} value
   * @param {boolean} force force firing the change event
   * @param {boolean} persistent sets the persistency of the change event
   */
  _setModel: function _setModel(value, force, persistent) {
    value = [+value[0].toFixed(2), +value[1].toFixed(2)];
    this.model.size.set({ "extent": value }, force, persistent);
  }

});

exports.default = BubbleSize;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _d = __webpack_require__(209);

var _d2 = _interopRequireDefault(_d);

var _d3 = __webpack_require__(40);

var _d4 = _interopRequireDefault(_d3);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*!
 * VIZABI BUBBLE COLOR LEGEND COMPONENT
 */

var ColorLegend = _component2.default.extend({

  init: function init(config, context) {
    var _this = this;
    this.template = '<div class="vzb-cl-outer"></div>';
    this.name = 'colorlegend';

    this.model_expects = [{
      name: "time",
      type: "time"
    }, {
      name: "entities",
      type: "entities"
    }, {
      name: "marker",
      type: "model"
    }, {
      name: "locale",
      type: "locale"
    }];

    this.model_binds = {
      "change:marker.color.scaleType": function changeMarkerColorScaleType(evt, path) {
        if (!_this._readyOnce || _this.colorModel.isDiscrete()) return;
        _this.updateView();
      },
      "change:marker.color.palette": function changeMarkerColorPalette(evt, path) {
        if (!_this._readyOnce || !_this.frame) return;
        _this.updateView();
      },
      "change:marker.highlight": function changeMarkerHighlight(evt, values) {
        if (!_this.colorModel.isDiscrete()) return;

        _this.model.marker.getFrame(_this.model.time.value, function (frame) {
          if (frame) {
            var _hlEntities = _this.model.marker.getHighlighted(_this.KEY);
            _this.updateGroupsOpacity(_hlEntities.map(function (d) {
              return frame[_this.colorModel._name][d];
            }));
          } else {
            _this.updateGroupsOpacity();
          }
        });
      },
      "translate:locale": function translateLocale() {
        _this.colorPicker.translate(_this.model.locale.getTFunction());
      }
    };

    //contructor is the same as any component
    this._super(config, context);
  },

  readyOnce: function readyOnce() {
    var _this = this;
    this.element = d3.select(this.element);

    //make color in options scrollable
    d3.select(this.placeholder.parentNode).classed("vzb-dialog-scrollable", true);

    this.colorModel = this.model.marker.color;
    this.colorlegendMarker = this.colorModel.getColorlegendMarker();
    if (this.colorlegendMarker) {
      this.colorlegendMarker.on('ready', function () {
        _this.ready();
      });
    }
    this.listColorsEl = this.element.append("div").attr("class", "vzb-cl-holder").append("div").attr("class", "vzb-cl-colorlist");

    this.rainbowEl = this.listColorsEl.append("div").attr("class", "vzb-cl-rainbow");
    this.minimapEl = this.listColorsEl.append("div").attr("class", "vzb-cl-minimap");
    this.rainbowLegendEl = this.listColorsEl.append("div").attr("class", "vzb-cl-rainbow-legend");
    this.rainbowLegendSVG = this.rainbowLegendEl.append("svg");
    this.rainbowLegendG = this.rainbowLegendSVG.append("g");
    this.rainbowLegend = null;

    this.labelScaleEl = this.listColorsEl.append("div").attr("class", "vzb-cl-labelscale");
    this.labelScaleSVG = this.labelScaleEl.append("svg");
    this.labelScaleG = this.labelScaleSVG.append("g");
    this.unitDiv = this.listColorsEl.append("div").attr("class", "vzb-cl-unit");
    this.unitText = this.unitDiv.append("span").attr("class", "vzb-cl-unit-text");

    this.minimapSVG = this.minimapEl.append("svg");
    this.minimapG = this.minimapSVG.append("g");

    this.colorPicker = (0, _d2.default)();

    // append color picker to the tool DOM. need to check if element is already a d3 selection to not do it twice
    this.root.element instanceof Array ? this.root.element : d3.select(this.root.element).call(this.colorPicker);
    this.colorPicker.translate(this.model.locale.getTFunction());
  },

  ready: function ready() {
    var _this = this;

    this.KEY = this.model.entities.getDimension();
    this.colorlegendDim = this.KEY;
    this.canShowMap = false;

    if (this.colorModel.isDiscrete() && this.colorModel.use !== "constant" && this.colorlegendMarker) {
      if (!this.colorlegendMarker._ready) return;

      this.colorlegendDim = this.colorModel.getColorlegendEntities().getDimension();

      this.colorlegendMarker.getFrame(this.model.time.value, function (frame) {
        _this.frame = frame;
        _this.canShowMap = utils.keys((_this.frame || {}).hook_geoshape || {}).length;

        _this.colorlegendKeys = _this.colorlegendMarker.getKeys(_this.colorlegendDim);

        _this.colorlegendKeys.forEach(function (d) {
          if (!((_this.frame || {}).hook_geoshape || {})[d[_this.colorlegendDim]]) _this.canShowMap = false;
        });
        _this.updateView();
        _this.updateGroupsOpacity();
      });
      return;
    }

    _this.updateView();
    _this.updateGroupsOpacity();
  },

  updateView: function updateView() {
    var _this = this;
    var KEY = this.KEY;

    var palette = this.colorModel.getPalette();
    var canShowMap = this.canShowMap;

    var colorlegendKeys = this.colorlegendKeys || [];

    var colorOptions = this.listColorsEl.selectAll(".vzb-cl-option");

    //Hide and show elements of the color legend
    //Hide color legend entries if showing minimap or if color hook is a constant
    //or if using a discrete palette that would map to all entities on the chart and therefore will be too long
    //in the latter case we should show colors in the "find" list instead
    var hideColorOptions = canShowMap || this.colorModel.which == "_default" || this.colorlegendMarker && this.colorlegendDim == this.KEY && utils.comparePlainObjects(this.colorModel.getColorlegendEntities().getFilter(), this.model.entities.getFilter());

    colorOptions.classed("vzb-hidden", hideColorOptions);

    //Hide rainbow element if showing minimap or if color is discrete
    this.rainbowEl.classed("vzb-hidden", this.colorModel.isDiscrete());
    this.labelScaleEl.classed("vzb-hidden", this.colorModel.isDiscrete());
    this.rainbowLegendEl.classed("vzb-hidden", this.colorModel.isDiscrete());
    //Hide minimap if no data to draw it
    this.minimapEl.classed("vzb-hidden", !canShowMap || !this.colorModel.isDiscrete());

    this.unitDiv.classed("vzb-hidden", true);
    var cScale = this.colorModel.getScale();

    if (!this.colorModel.isDiscrete()) {

      var gradientWidth = this.rainbowEl.node().getBoundingClientRect().width;
      var paletteKeys = Object.keys(palette).map(parseFloat);

      var domain;
      var range;
      var labelScale;
      var formatter = this.colorModel.getTickFormatter();
      var fitIntoScale = null;

      var paletteLabels = this.colorModel.paletteLabels;

      if (paletteLabels) {

        fitIntoScale = "optimistic";

        domain = paletteLabels.map(function (val) {
          return parseFloat(val);
        });
        var paletteMax = d3.max(domain);
        range = domain.map(function (val) {
          return val / paletteMax * gradientWidth;
        });
      } else {

        domain = cScale.domain();
        var paletteMax = d3.max(paletteKeys);
        range = paletteKeys.map(function (val) {
          return val / paletteMax * gradientWidth;
        });
      }

      var labelScaletype = d3.min(domain) <= 0 && d3.max(domain) >= 0 && this.colorModel.scaleType === "log" ? "genericLog" : this.colorModel.scaleType;

      labelScale = d3.scale[labelScaletype == "time" ? "linear" : labelScaletype]().domain(domain).range(range);

      var marginLeft = parseInt(this.rainbowEl.style('left'), 10) || 0;
      var marginRight = parseInt(this.rainbowEl.style('right'), 10) || marginLeft;

      this.labelScaleSVG.style("width", marginLeft + gradientWidth + marginRight + "px");
      this.labelScaleG.attr("transform", "translate(" + marginLeft + ",0)");
      this.rainbowLegendSVG.style("width", marginLeft + gradientWidth + marginRight + "px");
      this.rainbowLegendG.attr("transform", "translate(" + marginLeft + ", " + 7 + ")");
      var labelsAxis = (0, _d4.default)();
      labelsAxis.scale(labelScale).orient("bottom")
      //.tickFormat(formatter)
      .tickSize(6, 0).tickPadding(6).tickSizeMinor(3, 0).labelerOptions({
        scaleType: this.colorModel.scaleType,
        toolMargin: {
          right: marginRight,
          left: marginLeft
        },
        showOuter: true,
        //bump: this.activeProfile.maxRadius/2,
        //viewportLength: gradientWidth,
        formatter: formatter,
        bump: marginLeft,
        cssFontSize: "11px",
        fitIntoScale: fitIntoScale
      });

      this.labelScaleG.call(labelsAxis);

      var colorRange = cScale.range();

      var gIndicators = range.map(function (val, i) {
        return { val: val, color: colorRange[i], paletteKey: paletteKeys[i] };
      });
      this.rainbowLegend = this.rainbowLegendG.selectAll('circle').data(gIndicators);
      this.rainbowLegend.exit().remove();
      this.rainbowLegend.enter().append("circle").attr('r', "6px").attr('stroke', '#000').on("click", _this._interact().clickToChangeColor);

      this.rainbowLegend.each(function (d, i) {
        d3.select(this).attr('fill', d.color);
        d3.select(this).attr('cx', d.val);
      });

      var gColors = paletteKeys.map(function (val, i) {
        return colorRange[i] + " " + d3.format("%")(val * .01);
      }).join(", ");

      this.rainbowEl.style("background", "linear-gradient(90deg," + gColors + ")");

      var unit = this.colorModel.getConceptprops().unit || "";

      this.unitDiv.classed("vzb-hidden", unit == "");
      this.unitText.text(unit);

      colorOptions.classed("vzb-hidden", true);
    } else {

      //Check if geoshape is provided
      if (!canShowMap) {

        if (this.colorModel.which == "_default") {
          colorOptions = colorOptions.data([]);
        } else {
          colorOptions = colorOptions.data(hideColorOptions ? [] : colorlegendKeys.length ? colorlegendKeys : Object.keys(this.colorModel.getPalette()).map(function (value) {
            var result = {};
            result[_this.colorlegendDim] = value;
            return result;
          }), function (d) {
            return d[_this.colorlegendDim];
          });
        }

        colorOptions.exit().remove();

        colorOptions.enter().append("div").attr("class", "vzb-cl-option").each(function () {
          d3.select(this).append("div").attr("class", "vzb-cl-color-sample").on("click", _this._interact().clickToShow);
          d3.select(this).append("div").attr("class", "vzb-cl-color-legend");
        }).on("mouseover", _this._interact().mouseover).on("mouseout", _this._interact().mouseout).on("click", _this._interact().clickToSelect);

        colorOptions.each(function (d, index) {
          d3.select(this).select(".vzb-cl-color-sample").style("background-color", cScale(d[_this.colorlegendDim])).style("border", "1px solid " + cScale(d[_this.colorlegendDim]));
          //Apply names to color legend entries if color is a property
          var label = _this.colorlegendMarker ? _this.frame.label[d[_this.colorlegendDim]] : null;
          if (!label && label !== 0) label = d[_this.colorlegendDim];
          d3.select(this).select(".vzb-cl-color-legend").text(label);
        });
      } else {

        //Drawing a minimap from the hook data

        var tempdivEl = this.minimapEl.append("div").attr("class", "vzb-temp");

        this.minimapSVG.attr("viewBox", null);
        this.minimapSVG.selectAll("g").remove();
        this.minimapG = this.minimapSVG.append("g");
        this.minimapG.selectAll("path").data(colorlegendKeys, function (d) {
          return d[_this.colorlegendDim];
        }).enter().append("path").on("mouseover", _this._interact().mouseover).on("mouseout", _this._interact().mouseout).on("click", _this._interact().clickToSelect).on("dblclick", _this._interact().clickToShow).each(function (d) {
          var shapeString = _this.frame.hook_geoshape[d[_this.colorlegendDim]].trim();

          //check if shape string starts with svg tag -- then it's a complete svg
          if (shapeString.slice(0, 4) == "<svg") {
            //append svg element from string to the temporary div
            tempdivEl.html(shapeString);
            //replace the shape string with just the path data from svg
            //TODO: this is not very resilient. potentially only the first path will be taken!
            shapeString = tempdivEl.select("svg").select("path").attr("d");
          }

          d3.select(this).attr("d", shapeString).style("fill", cScale(d[_this.colorlegendDim])).append("title").html(_this.frame.label[d[_this.colorlegendDim]]);

          tempdivEl.html("");
        });

        var gbbox = this.minimapG.node().getBBox();
        this.minimapSVG.attr("viewBox", "0 0 " + gbbox.width * 1.05 + " " + gbbox.height * 1.05);
        tempdivEl.remove();
      }
    }
  },

  _interact: function _interact() {
    var _this = this;
    var KEY = this.KEY;
    var colorlegendDim = this.colorlegendDim;

    return {
      mouseover: function mouseover(d, i) {
        //disable interaction if so stated in concept properties
        if (!_this.colorModel.isDiscrete()) return;

        var view = d3.select(this);
        var target = d[colorlegendDim];

        var highlight = _this.colorModel.getValidItems()
        //filter so that only countries of the correct target remain
        .filter(function (f) {
          return f[_this.colorModel.which] == target;
        })
        //fish out the "key" field, leave the rest behind
        .map(function (d) {
          return utils.clone(d, [KEY]);
        });

        _this.model.marker.setHighlight(highlight);
      },

      mouseout: function mouseout(d, i) {
        //disable interaction if so stated in concept properties
        if (!_this.colorModel.isDiscrete()) return;
        _this.model.marker.clearHighlighted();
      },
      clickToChangeColor: function clickToChangeColor(d, i) {
        //disable interaction if so stated in concept properties
        if (!_this.colorModel.isUserSelectable()) return;
        var palette = _this.colorModel.getPalette();
        var defaultPalette = _this.colorModel.getDefaultPalette();
        var view = d3.select(this);
        var target = !_this.colorModel.isDiscrete() ? d.paletteKey : d[colorlegendDim];
        _this.colorPicker.colorOld(palette[target]).colorDef(defaultPalette[target]).callback(function (value, permanent) {
          _this.colorModel.setColor(value, target);
        }).fitToScreen([d3.event.pageX, d3.event.pageY]).show(true);
      },
      clickToShow: function clickToShow(d, i) {
        //disable interaction if so stated in concept properties
        if (!_this.colorModel.isDiscrete()) return;

        var view = d3.select(this);
        var target = d[colorlegendDim];

        if (_this.model.entities.show[colorlegendDim] && _this.model.entities.show[colorlegendDim]["$in"]) var oldShow = utils.clone(_this.model.entities.show[colorlegendDim]["$in"]);else var oldShow = [];

        var entityIndex = oldShow.indexOf(d[colorlegendDim]);
        if (entityIndex !== -1) {
          oldShow.splice(entityIndex, 1);
        } else {
          oldShow.push(d[colorlegendDim]);
        }

        var show = {};
        if (oldShow.length > 0) show[colorlegendDim] = { "$in": oldShow };

        _this.model.entities.set({ show: show });
      },
      clickToSelect: function clickToSelect(d, i) {
        //disable interaction if so stated in concept properties
        if (!_this.colorModel.isDiscrete()) return;

        var view = d3.select(this);
        var target = d[colorlegendDim];

        var select = _this.colorModel.getValidItems()
        //filter so that only countries of the correct target remain
        .filter(function (f) {
          return f[_this.colorModel.which] == target;
        })
        //fish out the "key" field, leave the rest behind
        .map(function (d) {
          return utils.clone(d, [KEY]);
        });

        if (select.filter(function (d) {
          return _this.model.marker.isSelected(d);
        }).length == select.length) {
          _this.model.marker.clearSelected();
        } else {
          _this.model.marker.setSelect(select);
        }
      }
    };
  },

  resize: function resize() {
    if (!this.colorModel.isDiscrete()) {
      this.updateView();
    }
    this.colorPicker.resize(d3.select('.vzb-colorpicker-svg'));
  },

  /**
   * Function updates the opacity of color legend elements
   * @param   {Array} value = [] array of highlighted elements
   */
  updateGroupsOpacity: function updateGroupsOpacity() {
    var highlight = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];

    var _this = this;

    var clMarker = this.colorModel.getColorlegendMarker() || {};
    var OPACITY_REGULAR = clMarker.opacityRegular || 0.8;
    var OPACITY_DIM = clMarker.opacityHighlightDim || 0.5;
    var OPACITY_HIGHLIGHT = 1;

    var selection = _this.canShowMap ? ".vzb-cl-minimap path" : ".vzb-cl-option .vzb-cl-color-sample";

    this.listColorsEl.selectAll(selection).style("opacity", function (d) {
      if (!highlight.length) return OPACITY_REGULAR;
      return highlight.indexOf(d[_this.colorlegendDim]) > -1 ? OPACITY_HIGHLIGHT : OPACITY_DIM;
    });
  }

});

exports.default = ColorLegend;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
    value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*!
 * VIZABI MIN MAX INPUT FIELDS
 */

var DOMAINMIN = "domainMin";
var DOMAINMAX = "domainMax";
var ZOOMEDMIN = "zoomedMin";
var ZOOMEDMAX = "zoomedMax";

var MinMaxInputs = _component2.default.extend({

    /**
     * Initializes the Component.
     * Executed once before any template is rendered.
     * @param config The options passed to the component
     * @param context The component's parent
     */
    init: function init(config, context) {

        this.name = 'gapminder-minmaxinputs';
        this.template = __webpack_require__(439);

        var _this = this;

        this.model_expects = [{
            name: "marker",
            type: "model"
        }, {
            name: "time",
            type: "time"
        }, {
            name: "locale",
            type: "locale"
        }];

        this.markerID = config.markerID;
        if (!config.markerID) utils.warn("minmaxinputs.js complains on 'markerID' property: " + config.markerID);

        this.model_binds = {};
        this.model_binds["translate:locale"] = function (evt) {
            _this.updateView();
        };
        this.model_binds["change:marker." + this.markerID] = function (evt) {
            _this.updateView();
        };
        this.model_binds["ready"] = function (evt) {
            _this.updateView();
        };

        //contructor is the same as any component
        this._super(config, context);

        // SPECIFIC COMPONENT UI! NOT TOOLMODEL UI!
        this.ui = utils.extend({
            selectDomainMinMax: false,
            selectZoomedMinMax: false
        }, this.ui.getPlainObject());
    },

    ready: function ready() {
        this.updateView();
    },

    readyOnce: function readyOnce() {
        var _this = this;

        this.element = d3.select(this.element);

        this.el_domain_labelMin = this.element.select('.vzb-mmi-domainmin-label');
        this.el_domain_labelMax = this.element.select('.vzb-mmi-domainmax-label');
        this.el_domain_fieldMin = this.element.select('.vzb-mmi-domainmin');
        this.el_domain_fieldMax = this.element.select('.vzb-mmi-domainmax');

        this.el_break = this.element.select('.vzb-mmi-break');

        this.el_zoomed_labelMin = this.element.select('.vzb-mmi-zoomedmin-label');
        this.el_zoomed_labelMax = this.element.select('.vzb-mmi-zoomedmax-label');
        this.el_zoomed_fieldMin = this.element.select('.vzb-mmi-zoomedmin');
        this.el_zoomed_fieldMax = this.element.select('.vzb-mmi-zoomedmax');

        _this.el_domain_fieldMin.on("change", function () {
            _this._setModel(DOMAINMIN, this.value);
        });
        _this.el_domain_fieldMax.on("change", function () {
            _this._setModel(DOMAINMAX, this.value);
        });

        _this.el_zoomed_fieldMin.on("change", function () {
            _this._setModel(ZOOMEDMIN, this.value);
        });
        _this.el_zoomed_fieldMax.on("change", function () {
            _this._setModel(ZOOMEDMAX, this.value);
        });

        this.element.selectAll("input").on("keypress", function (e) {
            if (d3.event.which == 13) document.activeElement.blur();
        });
    },

    updateView: function updateView() {
        var _this = this;
        this.translator = this.model.locale.getTFunction();

        this.el_domain_labelMin.text(this.translator("hints/min") + ":");
        this.el_domain_labelMax.text(this.translator("hints/max") + ":");
        this.el_zoomed_labelMin.text(this.translator("hints/min") + ":");
        this.el_zoomed_labelMax.text(this.translator("hints/max") + ":");

        this.el_domain_labelMin.classed('vzb-hidden', !this.ui.selectDomainMinMax);
        this.el_domain_labelMax.classed('vzb-hidden', !this.ui.selectDomainMinMax);
        this.el_domain_fieldMin.classed('vzb-hidden', !this.ui.selectDomainMinMax);
        this.el_domain_fieldMax.classed('vzb-hidden', !this.ui.selectDomainMinMax);

        this.el_break.classed('vzb-hidden', !(this.ui.selectDomainMinMax && this.ui.selectZoomedMinMax));

        this.el_zoomed_labelMin.classed('vzb-hidden', !this.ui.selectZoomedMinMax);
        this.el_zoomed_labelMax.classed('vzb-hidden', !this.ui.selectZoomedMinMax);
        this.el_zoomed_fieldMin.classed('vzb-hidden', !this.ui.selectZoomedMinMax);
        this.el_zoomed_fieldMax.classed('vzb-hidden', !this.ui.selectZoomedMinMax);

        var formatter = function formatter(n) {
            if (!n && n !== 0) return n;
            if (utils.isDate(n)) return _this.model.time.formatDate(n);
            return d3.format(".2r")(n);
        };

        this.el_domain_fieldMin.property("value", formatter(this.model.marker[this.markerID].getScale().domain()[0]));
        this.el_domain_fieldMax.property("value", formatter(this.model.marker[this.markerID].getScale().domain()[1]));
        this.el_zoomed_fieldMin.property("value", formatter(this.model.marker[this.markerID].zoomedMin));
        this.el_zoomed_fieldMax.property("value", formatter(this.model.marker[this.markerID].zoomedMax));
    },

    _setModel: function _setModel(what, value) {
        this.model.marker[this.markerID][what] = utils.strToFloat(value);
    }

});

exports.default = MinMaxInputs;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _class = __webpack_require__(21);

var _class2 = _interopRequireDefault(_class);

var _iconset = __webpack_require__(10);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

var label = function label(context) {

  return function d3_label() {

    var _this = context;

    var _cssPrefix;
    label.setCssPrefix = function (cssPrefix) {
      _cssPrefix = cssPrefix;
      return label;
    };

    var labelDragger = d3.behavior.drag().on("dragstart", function (d, i) {
      d3.event.sourceEvent.stopPropagation();
      var KEY = _this.KEY;
    }).on("drag", function (d, i) {
      var KEY = _this.KEY;
      if (!_this.model.ui.chart.labels.dragging) return;
      if (!this.druging) _this.druging = d[KEY];
      var cache = _this.cached[d[KEY]];
      cache.labelFixed = true;

      var viewWidth = _this.context.width;
      var viewHeight = _this.context.height;

      cache.labelX_ += d3.event.dx / viewWidth;
      cache.labelY_ += d3.event.dy / viewHeight;

      var resolvedX = _this.xScale(cache.labelX0) + cache.labelX_ * viewWidth;
      var resolvedY = _this.yScale(cache.labelY0) + cache.labelY_ * viewHeight;

      var resolvedX0 = _this.xScale(cache.labelX0);
      var resolvedY0 = _this.yScale(cache.labelY0);

      var lineGroup = _this.entityLines.filter(function (f) {
        return f[KEY] == d[KEY];
      });

      label._repositionLabels(d, i, this, resolvedX, resolvedY, resolvedX0, resolvedY0, 0, null, lineGroup);
    }).on("dragend", function (d, i) {
      var KEY = _this.KEY;
      if (_this.druging) {
        var cache = _this.cached[d[KEY]];
        _this.druging = null;
        cache.labelOffset[0] = cache.labelX_;
        cache.labelOffset[1] = cache.labelY_;
        _this.model.marker.setLabelOffset(d, [cache.labelX_, cache.labelY_]);
      }
    });

    function label(container) {
      container.call(labelDragger).each(function (d, index) {
        var view = d3.select(this);

        // Ola: Clicking bubble label should not zoom to countries boundary #811
        // It's too easy to accidentally zoom
        // This feature will be activated later, by making the label into a "context menu" where users can click Split, or zoom,.. hide others etc....

        view.append("rect").attr("class", "vzb-label-glow").attr("filter", "url(" + location.pathname + "#vzb-glow-filter)");
        view.append("rect").attr("class", "vzb-label-fill vzb-tooltip-border");
        //          .on("click", function(d, i) {
        //            //default prevented is needed to distinguish click from drag
        //            if(d3.event.defaultPrevented) return;
        //
        //            var maxmin = _this.cached[d[KEY]].maxMinValues;
        //            var radius = utils.areaToRadius(_this.sScale(maxmin.valueSmax));
        //            _this._panZoom._zoomOnRectangle(_this.element,
        //              _this.xScale(maxmin.valueXmin) - radius,
        //              _this.yScale(maxmin.valueYmin) + radius,
        //              _this.xScale(maxmin.valueXmax) + radius,
        //              _this.yScale(maxmin.valueYmax) - radius,
        //              false, 500);
        //          });

        view.append("text").attr("class", _cssPrefix + "-label-content " + _cssPrefix + "-label-shadow vzb-noexport");

        view.append("text").attr("class", _cssPrefix + "-label-content");

        var cross = view.append("g").attr("class", _cssPrefix + "-label-x vzb-transparent");
        utils.setIcon(cross, _iconset.close);

        cross.insert("circle", "svg");

        cross.select("svg").attr("class", _cssPrefix + "-label-x-icon").attr("width", "0px").attr("height", "0px");

        cross.on("click", function () {
          //default prevented is needed to distinguish click from drag
          if (d3.event.defaultPrevented) return;
          _this.model.marker.clearHighlighted();
          _this.model.marker.selectMarker(d);
        });
      }).on("mouseover", function (d) {
        if (utils.isTouchDevice()) return;
        _this.model.marker.highlightMarker(d);
        var KEY = _this.KEY || _this.model.entities.getDimension();
        // hovered label should be on top of other labels: if "a" is not the hovered element "d", send "a" to the back
        _this.entityLabels.sort(function (a, b) {
          return a[KEY] != d[KEY] ? -1 : 1;
        });
        d3.select(this).selectAll("." + _cssPrefix + "-label-x").classed("vzb-transparent", false);
      }).on("mouseout", function (d) {
        if (utils.isTouchDevice()) return;
        _this.model.marker.clearHighlighted();
        d3.select(this).selectAll("." + _cssPrefix + "-label-x").classed("vzb-transparent", true);
      }).on("click", function (d) {
        if (!utils.isTouchDevice()) return;
        var cross = d3.select(this).selectAll("." + _cssPrefix + "-label-x");
        var KEY = _this.KEY || _this.model.entities.getDimension();
        var hidden = cross.classed("vzb-transparent");
        if (hidden) {
          // hovered label should be on top of other labels: if "a" is not the hovered element "d", send "a" to the back
          _this.entityLabels.sort(function (a, b) {
            return a[KEY] != d[KEY] ? -1 : 1;
          });
          _this.showCloseCross(null, false);
        }
        cross.classed("vzb-transparent", !hidden);
        if (!_this.options.SUPPRESS_HIGHLIGHT_DURING_PLAY || !_this.model.time.playing) {
          if (hidden) {
            _this.model.marker.setHighlight(d);
          } else {
            _this.model.marker.clearHighlighted();
          }
        }
      });

      return label;
    };

    label.line = function (container) {
      container.append("line").attr("class", _cssPrefix + "-label-line");
    };

    label._repositionLabels = _repositionLabels;
    function _repositionLabels(d, i, labelContext, _X, _Y, _X0, _Y0, duration, showhide, lineGroup) {

      var cache = _this.cached[d[_this.KEY]];

      var labelGroup = d3.select(labelContext);

      //protect label and line from the broken data
      var brokenInputs = !_X && _X !== 0 || !_Y && _Y !== 0 || !_X0 && _X0 !== 0 || !_Y0 && _Y0 !== 0;
      if (brokenInputs) {
        labelGroup.classed("vzb-invisible", brokenInputs);
        lineGroup.classed("vzb-invisible", brokenInputs);
        return;
      }

      var viewWidth = _this.context.width;
      var viewHeight = _this.context.height;
      var rectBBox = cache.rectBBox;
      var width = rectBBox.width;
      var height = rectBBox.height;

      //apply limits so that the label doesn't stick out of the visible field
      if (_X - width <= 0) {
        //check left
        _X = width;
        cache.labelX_ = (_X - _this.xScale(cache.labelX0)) / viewWidth;
      } else if (_X + 5 > viewWidth) {
        //check right
        _X = viewWidth - 5;
        cache.labelX_ = (_X - _this.xScale(cache.labelX0)) / viewWidth;
      }
      if (_Y - height * .75 <= 0) {
        // check top
        _Y = height * .75;
        cache.labelY_ = (_Y - _this.yScale(cache.labelY0)) / viewHeight;
      } else if (_Y + height * .35 > viewHeight) {
        //check bottom
        _Y = viewHeight - height * .35;
        cache.labelY_ = (_Y - _this.yScale(cache.labelY0)) / viewHeight;
      }

      if (duration == null) duration = _this.context.duration;
      if (cache._new) {
        duration = 0;
        delete cache._new;
      }
      if (duration) {
        if (showhide && !d.hidden) {
          //if need to show label

          labelGroup.classed("vzb-invisible", d.hidden);
          labelGroup.attr("transform", "translate(" + _X + "," + _Y + ")").style("opacity", 0).transition().duration(duration).ease("exp").style("opacity", 1)
          //i would like to set opactiy to null in the end of transition.
          //but then fade in animation is not working for some reason
          .each("interrupt", function () {
            labelGroup.style("opacity", 1);
          });
          lineGroup.classed("vzb-invisible", d.hidden);
          lineGroup.attr("transform", "translate(" + _X + "," + _Y + ")").style("opacity", 0).transition().duration(duration).ease("exp").style("opacity", 1)
          //i would like to set opactiy to null in the end of transition.
          //but then fade in animation is not working for some reason
          .each("interrupt", function () {
            lineGroup.style("opacity", 1);
          });
        } else if (showhide && d.hidden) {
          //if need to hide label

          labelGroup.style("opacity", 1).transition().duration(duration).ease("exp").style("opacity", 0).each("end", function () {
            labelGroup.style("opacity", 1) //i would like to set it to null. but then fade in animation is not working for some reason
            .classed("vzb-invisible", d.hidden);
          });
          lineGroup.style("opacity", 1).transition().duration(duration).ease("exp").style("opacity", 0).each("end", function () {
            lineGroup.style("opacity", 1) //i would like to set it to null. but then fade in animation is not working for some reason
            .classed("vzb-invisible", d.hidden);
          });
        } else {
          // just update the position

          labelGroup.transition().duration(duration).ease("linear").attr("transform", "translate(" + _X + "," + _Y + ")");
          lineGroup.transition().duration(duration).ease("linear").attr("transform", "translate(" + _X + "," + _Y + ")");
        }
      } else {
        labelGroup.interrupt().attr("transform", "translate(" + _X + "," + _Y + ")").transition();
        lineGroup.interrupt().attr("transform", "translate(" + _X + "," + _Y + ")").transition();
        if (showhide) labelGroup.classed("vzb-invisible", d.hidden);
        if (showhide) lineGroup.classed("vzb-invisible", d.hidden);
      }

      var diffX1 = _X0 - _X;
      var diffY1 = _Y0 - _Y;
      var textBBox = labelGroup.select('text').node().getBBox();
      var diffX2 = -textBBox.width * .5;
      var diffY2 = -height * .2;
      var labels = _this.model.ui.chart.labels;

      var bBox = labels.removeLabelBox ? textBBox : rectBBox;

      var FAR_COEFF = _this.activeProfile.labelLeashCoeff || 0;

      var lineHidden = circleRectIntersects({ x: diffX1, y: diffY1, r: cache.scaledS0 }, { x: diffX2, y: diffY2, width: bBox.height * 2 * FAR_COEFF + bBox.width, height: bBox.height * (2 * FAR_COEFF + 1) });
      lineGroup.select('line').classed("vzb-invisible", lineHidden);
      if (lineHidden) return;

      if (labels.removeLabelBox) {
        var angle = Math.atan2(diffX1 - diffX2, diffY1 - diffY2) * 180 / Math.PI;
        var deltaDiffX2 = angle >= 0 && angle <= 180 ? bBox.width * .5 : -bBox.width * .5;
        var deltaDiffY2 = Math.abs(angle) <= 90 ? bBox.height * .55 : -bBox.height * .45;
        diffX2 += Math.abs(diffX1 - diffX2) > textBBox.width * .5 ? deltaDiffX2 : 0;
        diffY2 += Math.abs(diffY1 - diffY2) > textBBox.height * .5 ? deltaDiffY2 : textBBox.height * .05;
      }

      var longerSideCoeff = Math.abs(diffX1) > Math.abs(diffY1) ? Math.abs(diffX1) : Math.abs(diffY1);
      lineGroup.select("line").style("stroke-dasharray", "0 " + cache.scaledS0 + " " + ~~longerSideCoeff * 2);

      lineGroup.selectAll("line").attr("x1", diffX1).attr("y1", diffY1).attr("x2", diffX2).attr("y2", diffY2);
    }

    /*
    * Adapted from
    * http://stackoverflow.com/questions/401847/circle-rectangle-collision-detection-intersection
    *
    * circle {
    *  x: center X
    *  y: center Y
    *  r: radius
    * }
    *
    * rect {
    *  x: center X
    *  y: center Y
    *  width: width
    *  height: height
    * }
    */
    function circleRectIntersects(circle, rect) {
      var circleDistanceX = Math.abs(circle.x - rect.x);
      var circleDistanceY = Math.abs(circle.y - rect.y);
      var halfRectWidth = rect.width * .5;
      var halfRectHeight = rect.height * .5;

      if (circleDistanceX > halfRectWidth + circle.r) {
        return false;
      }
      if (circleDistanceY > halfRectHeight + circle.r) {
        return false;
      }

      if (circleDistanceX <= halfRectWidth) {
        return true;
      }
      if (circleDistanceY <= halfRectHeight) {
        return true;
      }

      var cornerDistance_sq = Math.pow(circleDistanceX - halfRectWidth, 2) + Math.pow(circleDistanceY - halfRectHeight, 2);

      return cornerDistance_sq <= Math.pow(circle.r, 2);
    }

    return label;
  }();
};

var OPTIONS = {
  LABELS_CONTAINER_CLASS: '',
  LINES_CONTAINER_CLASS: '',
  LINES_CONTAINER_SELECTOR: '',
  CSS_PREFIX: '',
  SUPPRESS_HIGHLIGHT_DURING_PLAY: true
};

var Labels = _class2.default.extend({

  init: function init(context, conditions) {
    var _this = this;
    this.context = context;

    this.options = utils.extend({}, OPTIONS);
    this.label = label(this);
    this._xScale = null;
    this._yScale = null;
    this._closeCrossHeight = 0;
    this.labelSizeTextScale = null;
  },

  ready: function ready() {
    this.updateIndicators();
    this.updateLabelSizeLimits();
    //this.updateLabelsOnlyTextSize();
  },

  readyOnce: function readyOnce() {
    var _this = this;

    this.model = this.context.model;

    this.model.on("change:marker.select", function () {
      if (!_this.context._readyOnce) return;
      //console.log("EVENT change:entities:select");
      _this.selectDataPoints();
    });

    if (this.model.marker.size_label) this.model.on('change:marker.size_label.extent', function (evt, path) {
      //console.log("EVENT change:marker:size:max");
      if (!_this.context._readyOnce) return;
      _this.updateLabelSizeLimits();
      if (_this.model.time.splash) return;
      _this.updateLabelsOnlyTextSize();
    });

    if (this.model.ui.chart.labels.hasOwnProperty('removeLabelBox')) this.model.on('change:ui.chart.labels.removeLabelBox', function (evt, path) {
      //console.log("EVENT change:marker:size:max");
      if (!_this.context._readyOnce) return;
      _this.updateLabelsOnlyTextSize();
    });

    this.KEY = this.context.model.entities.getDimension();

    this.cached = {};

    this.label.setCssPrefix(this.options.CSS_PREFIX);

    this.rootEl = this.context.root.element instanceof Array ? this.context.root.element : d3.select(this.context.root.element);
    this.labelsContainer = this.rootEl.select("." + this.options.LABELS_CONTAINER_CLASS);
    this.linesContainer = this.rootEl.select("." + this.options.LINES_CONTAINER_CLASS);
    this.updateIndicators();
    this.updateSize();
    this.selectDataPoints();
  },

  config: function config(newOptions) {
    utils.extend(this.options, newOptions);
  },

  updateLabelSizeLimits: function updateLabelSizeLimits() {
    var _this = this;
    if (!this.model.marker.size_label) return;
    var extent = this.model.marker.size_label.extent || [0, 1];

    var minLabelTextSize = this.activeProfile.minLabelTextSize;
    var maxLabelTextSize = this.activeProfile.maxLabelTextSize;
    var minMaxDelta = maxLabelTextSize - minLabelTextSize;

    this.minLabelTextSize = Math.max(minLabelTextSize + minMaxDelta * extent[0], minLabelTextSize);
    this.maxLabelTextSize = Math.max(minLabelTextSize + minMaxDelta * extent[1], minLabelTextSize);

    if (this.model.marker.size_label.use == 'constant') {
      // if(!this.model.marker.size_label.which) {
      //   this.maxLabelTextSize = this.activeProfile.defaultLabelTextSize;
      //   this.model.marker.size_label.set({'domainMax': (this.maxLabelTextSize - minLabelTextSize) / minMaxDelta, 'which': '_default'});
      //   return;
      // }
      this.minLabelTextSize = this.maxLabelTextSize;
    }

    if (this.model.marker.size_label.scaleType !== "ordinal" || this.model.marker.size_label.use == 'constant') {
      this.labelSizeTextScale.range([_this.minLabelTextSize, _this.maxLabelTextSize]);
    } else {
      this.labelSizeTextScale.rangePoints([_this.minLabelTextSize, _this.maxLabelTextSize], 0).range();
    }
  },

  updateIndicators: function updateIndicators() {
    var _this = this;

    //scales
    if (this.model.marker.size_label) {
      this.labelSizeTextScale = this.model.marker.size_label.getScale();
    }
  },

  setScales: function setScales(xScale, yScale) {
    this._xScale = xScale;
    this._yScale = yScale;
  },

  setCloseCrossHeight: function setCloseCrossHeight(closeCrossHeight) {
    if (this._closeCrossHeight != closeCrossHeight) {
      this._closeCrossHeight = closeCrossHeight;
      this.updateLabelCloseGroupSize(this.entityLabels.selectAll("." + this.options.CSS_PREFIX + "-label-x"), this._closeCrossHeight);
    }
  },

  xScale: function xScale(x) {
    return this._xScale ? this._xScale(x) : x * this.context.width;
  },

  yScale: function yScale(y) {
    return this._yScale ? this._yScale(y) : y * this.context.height;
  },

  selectDataPoints: function selectDataPoints() {
    var _this = this;
    var KEY = this.KEY;
    var _cssPrefix = this.options.CSS_PREFIX;

    this.entityLabels = this.labelsContainer.selectAll("." + _cssPrefix + "-entity").data(_this.model.marker.select, function (d) {
      return d[KEY];
    });
    this.entityLines = this.linesContainer.selectAll("g.entity-line." + _cssPrefix + "-entity").data(_this.model.marker.select, function (d) {
      return d[KEY];
    });

    this.entityLabels.exit().each(function (d) {
      if (_this.cached[d[KEY]] != null) {
        _this.cached[d[KEY]] = void 0;
      }
    }).remove();
    this.entityLines.exit().remove();
    this.entityLines.enter().insert('g', function (d) {
      return this.querySelector("." + _this.options.LINES_CONTAINER_SELECTOR_PREFIX + d[KEY]);
    }).attr("class", function (d, index) {
      return _cssPrefix + "-entity entity-line line-" + d[KEY];
    }).each(function (d, index) {
      _this.label.line(d3.select(this));
    });

    this.entityLabels.enter().append("g").attr("class", function (d, index) {
      return _cssPrefix + "-entity label-" + d[KEY];
    }).each(function (d, index) {
      _this.cached[d[KEY]] = { _new: true };
      _this.label(d3.select(this));
    });
  },

  showCloseCross: function showCloseCross(d, show) {
    var KEY = this.KEY;
    //show the little cross on the selected label
    this.entityLabels.filter(function (f) {
      return d ? f[KEY] == d[KEY] : true;
    }).select("." + this.options.CSS_PREFIX + "-label-x").classed("vzb-transparent", !show);
  },

  highlight: function highlight(d, _highlight) {
    var KEY = this.KEY;
    var labels = this.entityLabels;
    if (d) {
      labels = labels.filter(function (f) {
        return d ? f[KEY] == d[KEY] : true;
      });
    }
    labels.classed("vzb-highlighted", _highlight);
  },

  updateLabel: function updateLabel(d, index, cache, valueX, valueY, valueS, valueC, valueL, valueLST, duration, showhide) {
    var _this = this;
    var KEY = this.KEY;
    if (d[KEY] == _this.druging) return;

    var _cssPrefix = this.options.CSS_PREFIX;

    // only for selected entities
    if (_this.model.marker.isSelected(d) && _this.entityLabels != null) {
      if (_this.cached[d[KEY]] == null) this.selectDataPoints();

      var cached = _this.cached[d[KEY]];
      if (cache) utils.extend(cached, cache);

      if (cached.scaledS0 == null || cached.labelX0 == null || cached.labelY0 == null) {
        //initialize label once
        if (valueS || valueS === 0) cached.scaledS0 = utils.areaToRadius(this.context.sScale(valueS));
        cached.labelX0 = valueX;
        cached.labelY0 = valueY;
        cached.valueLST = valueLST;
        cached.scaledC0 = valueC != null ? this.context.cScale(valueC) : this.context.COLOR_WHITEISH;
      }

      if (cached.labelX_ == null || cached.labelY_ == null) {
        var select = utils.find(_this.model.marker.select, function (f) {
          return f[KEY] == d[KEY];
        });
        cached.labelOffset = select.labelOffset || [0, 0];
      }

      var brokenInputs = !cached.labelX0 && cached.labelX0 !== 0 || !cached.labelY0 && cached.labelY0 !== 0 || !cached.scaledS0 && cached.scaledS0 !== 0;

      var lineGroup = _this.entityLines.filter(function (f) {
        return f[KEY] == d[KEY];
      });
      // reposition label
      _this.entityLabels.filter(function (f) {
        return f[KEY] == d[KEY];
      }).each(function (groupData) {

        var labelGroup = d3.select(this);

        if (brokenInputs) {
          labelGroup.classed("vzb-invisible", brokenInputs);
          lineGroup.classed("vzb-invisible", brokenInputs);
          return;
        }

        var text = labelGroup.selectAll("." + _cssPrefix + "-label-content").text(valueL);

        _this._updateLabelSize(d, index, labelGroup, valueLST, text);

        _this.positionLabel(d, index, this, duration, showhide, lineGroup);
      });
    }
  },

  _updateLabelSize: function _updateLabelSize(d, index, labelGroup, valueLST, text) {
    var _this = this;
    var KEY = this.KEY;
    var cached = _this.cached[d[KEY]];

    var _cssPrefix = this.options.CSS_PREFIX;

    var labels = _this.model.ui.chart.labels || {};
    labelGroup.classed('vzb-label-boxremoved', labels.removeLabelBox);

    var _text = text || labelGroup.selectAll("." + _cssPrefix + "-label-content");

    if (_this.labelSizeTextScale) {
      if (valueLST != null) {
        var range = _this.labelSizeTextScale.range();
        var fontSize = range[0] + Math.sqrt((_this.labelSizeTextScale(valueLST) - range[0]) * (range[1] - range[0]));
        _text.attr('font-size', fontSize + 'px');
      } else {
        _text.attr('font-size', '');
      }
    }

    var contentBBox = _text[0][0].getBBox();

    var rect = labelGroup.selectAll("rect");

    if (!cached.textWidth || cached.textWidth != contentBBox.width) {
      cached.textWidth = contentBBox.width;

      var labelCloseHeight = _this._closeCrossHeight || contentBBox.height; //_this.activeProfile.infoElHeight * 1.2;//contentBBox.height;

      var isRTL = _this.model.locale.isRTL();
      var labelCloseGroup = labelGroup.select("." + _cssPrefix + "-label-x").attr('transform', 'translate(' + (isRTL ? -contentBBox.width - 4 : 4) + ',' + -contentBBox.height * .85 + ')');

      this.updateLabelCloseGroupSize(labelCloseGroup, labelCloseHeight);

      rect.attr("width", contentBBox.width + 8).attr("height", contentBBox.height * 1.2).attr("x", -contentBBox.width - 4).attr("y", -contentBBox.height * .85).attr("rx", contentBBox.height * .2).attr("ry", contentBBox.height * .2);

      //cache label bound rect for reposition
      cached.rectBBox = rect.node().getBBox();
      //cached.moveX = 5;
      //cached.moveY = contentBBox.height * .3;
    }

    var glowRect = labelGroup.select(".vzb-label-glow");
    if (glowRect.attr("stroke") !== cached.scaledC0) {
      glowRect.attr("stroke", cached.scaledC0);
    }
  },

  updateLabelCloseGroupSize: function updateLabelCloseGroupSize(labelCloseGroup, labelCloseHeight) {
    labelCloseGroup.select("circle").attr("cx", /*contentBBox.height * .0 + */0).attr("cy", 0).attr("r", labelCloseHeight * .5);

    labelCloseGroup.select("svg").attr("x", -labelCloseHeight * .5).attr("y", labelCloseHeight * -.5).attr("width", labelCloseHeight).attr("height", labelCloseHeight);
  },

  updateLabelsOnlyTextSize: function updateLabelsOnlyTextSize() {
    var _this = this;
    var KEY = this.KEY;

    this.entityLabels.each(function (d, index) {
      var cached = _this.cached[d[KEY]];
      _this._updateLabelSize(d, index, d3.select(this), _this.context.frame.size_label[d[KEY]]);
      var lineGroup = _this.entityLines.filter(function (f) {
        return f[KEY] == d[KEY];
      });
      _this.positionLabel(d, index, this, 0, null, lineGroup);
    });
  },

  updateLabelOnlyPosition: function updateLabelOnlyPosition(d, index, cache) {
    var _this = this;
    var KEY = this.KEY;
    var cached = this.cached[d[KEY]];
    if (cache) utils.extend(cached, cache);

    var lineGroup = _this.entityLines.filter(function (f) {
      return f[KEY] == d[KEY];
    });

    this.entityLabels.filter(function (f) {
      return f[KEY] == d[KEY];
    }).each(function (groupData) {
      _this.positionLabel(d, index, this, 0, null, lineGroup);
    });
  },

  updateLabelOnlyColor: function updateLabelOnlyColor(d, index, cache) {
    var _this = this;
    var KEY = this.KEY;
    var cached = this.cached[d[KEY]];
    if (cache) utils.extend(cached, cache);

    var labelGroup = _this.entityLabels.filter(function (f) {
      return f[KEY] == d[KEY];
    });

    _this._updateLabelSize(d, index, labelGroup, null);
  },

  positionLabel: function positionLabel(d, index, context, duration, showhide, lineGroup) {
    var KEY = this.KEY;
    var cached = this.cached[d[KEY]];

    var viewWidth = this.context.width;
    var viewHeight = this.context.height;

    var resolvedX0 = this.xScale(cached.labelX0);
    var resolvedY0 = this.yScale(cached.labelY0);

    if (!cached.labelOffset) cached.labelOffset = [0, 0];
    cached.labelX_ = cached.labelOffset[0] || (-cached.scaledS0 * .75 - 5) / viewWidth;
    cached.labelY_ = cached.labelOffset[1] || (-cached.scaledS0 * .75 - 11) / viewHeight;

    //check default label position and switch to mirror position if position
    //does not bind to visible field

    var resolvedX = resolvedX0 + cached.labelX_ * viewWidth;
    if (cached.labelOffset[0] == 0) {
      if (resolvedX - cached.rectBBox.width <= 0) {
        //check left
        cached.labelX_ = (cached.scaledS0 * .75 + cached.rectBBox.width) / viewWidth;
        resolvedX = resolvedX0 + cached.labelX_ * viewWidth;
      } else if (resolvedX + 15 > viewWidth) {
        //check right
        cached.labelX_ = (viewWidth - 15 - resolvedX0) / viewWidth;
        resolvedX = resolvedX0 + cached.labelX_ * viewWidth;
      }
    }
    var resolvedY = resolvedY0 + cached.labelY_ * viewHeight;
    if (cached.labelOffset[1] == 0) {
      if (resolvedY - cached.rectBBox.height <= 0) {
        // check top
        cached.labelY_ = (cached.scaledS0 * .75 + cached.rectBBox.height) / viewHeight;
        resolvedY = resolvedY0 + cached.labelY_ * viewHeight;
      } else if (resolvedY + 10 > viewHeight) {
        //check bottom
        cached.labelY_ = (viewHeight - 10 - resolvedY0) / viewHeight;
        resolvedY = resolvedY0 + cached.labelY_ * viewHeight;
      }
    }
    this.label._repositionLabels(d, index, context, resolvedX, resolvedY, resolvedX0, resolvedY0, duration, showhide, lineGroup);
  },

  updateSize: function updateSize() {
    var profiles = {
      small: {
        minLabelTextSize: 7,
        maxLabelTextSize: 21,
        defaultLabelTextSize: 12,
        labelLeashCoeff: 0.4
      },
      medium: {
        minLabelTextSize: 7,
        maxLabelTextSize: 30,
        defaultLabelTextSize: 15,
        labelLeashCoeff: 0.3
      },
      large: {
        minLabelTextSize: 6,
        maxLabelTextSize: 48,
        defaultLabelTextSize: 20,
        labelLeashCoeff: 0.2
      }
    };

    var presentationProfiles = {
      medium: {
        minLabelTextSize: 15,
        maxLabelTextSize: 35,
        defaultLabelTextSize: 15,
        labelLeashCoeff: 0.3
      },
      large: {
        minLabelTextSize: 20,
        maxLabelTextSize: 55,
        defaultLabelTextSize: 20,
        labelLeashCoeff: 0.2
      }
    };

    this.activeProfile = this.context.getActiveProfile(profiles, presentationProfiles);
    this.updateLabelSizeLimits();
  }
});

exports.default = Labels;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _hook = __webpack_require__(48);

var _hook2 = _interopRequireDefault(_hook);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*!
 * VIZABI Axis Model (hook)
 */

var AxisModel = _hook2.default.extend({

  //some hooks can be important. like axis x and y
  //that means, if X or Y doesn't have data at some point, we can't show markers
  _important: true,

  /**
   * Default values for this model
   */
  getClassDefaults: function getClassDefaults() {
    var defaults = {
      use: null,
      which: null,
      domainMin: null,
      domainMax: null,
      zoomedMin: null,
      zoomedMax: null,
      scaleType: "linear",
      allow: {
        scales: ["linear", "log", "genericLog", "time", "pow"]
      }
    };
    return utils.deepExtend(this._super(), defaults);
  },

  _type: "axis",

  /**
   * Validates a color hook
   */
  validate: function validate() {
    this._super();

    //restore the correct object type for time values
    if (this.scale && this.scaleType == "time") {
      var obj = {};
      if (this.zoomedMin != null && !utils.isDate(this.zoomedMin)) obj.zoomedMin = this._space.time.parse(this.zoomedMin.toString());
      if (this.zoomedMax != null && !utils.isDate(this.zoomedMax)) obj.zoomedMax = this._space.time.parse(this.zoomedMax.toString());
      this.set(obj);
    }
  },

  /**
   * Gets the domain for this hook
   * @returns {Array} domain
   */
  buildScale: function buildScale() {
    var scaleType = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.scaleType;

    var domain;

    if (scaleType == "time") {

      var timeMdl = this._space.time;
      var limits = timeMdl.splash ? { min: timeMdl.parse(timeMdl.startOrigin), max: timeMdl.parse(timeMdl.endOrigin) } : { min: timeMdl.start, max: timeMdl.end };

      domain = [limits.min, limits.max];
      this.scale = d3.time.scale.utc().domain(domain);
    } else {

      if (!this.isDiscrete()) {
        var limits = this.getLimits(this.which);
        //default domain is based on limits
        domain = [limits.min, limits.max];
        //min and max can override the domain if defined
        domain[0] = this.domainMin != null ? +this.domainMin : domain[0];
        domain[1] = this.domainMax != null ? +this.domainMax : domain[1];
      } else {
        domain = this.use === "constant" ? [this.which] : this.getUnique(this.which);
      }

      scaleType = d3.min(domain) <= 0 && d3.max(domain) >= 0 && scaleType === "log" ? "genericLog" : scaleType;
      this.scale = d3.scale[scaleType || "linear"]().domain(domain);
    }

    this.scaleType = scaleType;
  },

  /**
   * Formats date according to time in this hook's space
   * @param {Date} date object to format
   * @returns {String} formatted date
   */
  formatDate: function formatDate(dateObject) {
    // improvement would be to check concept type of each space-dimension if it's time. 
    // Below code works as long we have one time model: time.
    return this._space.time.formatDate(dateObject);
  }

});

exports.default = AxisModel;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _d = __webpack_require__(40);

var _d2 = _interopRequireDefault(_d);

var _d3 = __webpack_require__(208);

var _d4 = _interopRequireDefault(_d3);

var _iconset = __webpack_require__(10);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

//LINE CHART COMPONENT
var LCComponent = _component2.default.extend({

  init: function init(config, context) {
    var _this = this;
    this.name = 'linechart';
    this.template = __webpack_require__(449);

    //define expected models for this component
    this.model_expects = [{
      name: "time",
      type: "time"
    }, {
      name: "entities",
      type: "entities"
    }, {
      name: "marker",
      type: "model"
    }, {
      name: "locale",
      type: "locale"
    }, {
      name: "ui",
      type: "ui"
    }];

    this.model_binds = {
      'change:time.value': function changeTimeValue() {
        if (!_this._readyOnce) return;
        _this.model.marker.getFrame(_this.model.time.value, function (frame, time) {
          if (!_this._frameIsValid(frame)) return utils.warn("change:time.value: empty data received from marker.getFrame(). doing nothing");
          _this.frameChanged(frame, time);
        });
      },
      'change:time.playing': function changeTimePlaying() {
        // hide tooltip on touch devices when playing
        if (_this.model.time.playing && utils.isTouchDevice() && !_this.tooltip.classed("vzb-hidden")) _this.tooltip.classed("vzb-hidden", true);
      },
      'change:time.start': function changeTimeStart() {
        if (!_this._readyOnce) return;
        _this.updateShow();
      },
      'change:time.end': function changeTimeEnd() {
        if (!_this._readyOnce) return;
        _this.updateShow();
      },
      'change:marker': function changeMarker(evt, path) {
        if (!_this._readyOnce) return;
        if (path.indexOf("domainMin") > -1 || path.indexOf("domainMax") > -1 || path.indexOf("zoomedMin") > -1 || path.indexOf("zoomedMax") > -1) {
          if (!_this.yScale || !_this.xScale) return; //abort if building of the scale is in progress
          _this.updateShow();
          _this.zoomToMaxMin();
          _this.updateSize();
          _this.updateTime();
          _this.redrawDataPoints();
          return;
        }
        if (path.indexOf("scaleType") > -1) {
          _this.updateShow();
          _this.zoomToMaxMin();
          _this.updateSize();
          _this.redrawDataPoints();
        }
      },
      "change:marker.highlight": function changeMarkerHighlight() {
        if (!_this._readyOnce) return;
        _this.highlightLines();
      },
      "change:marker.select": function changeMarkerSelect() {
        if (!_this._readyOnce) return;
        _this.updateDoubtOpacity();
        _this.highlightLines();
      },
      'change:marker.opacitySelectDim': function changeMarkerOpacitySelectDim() {
        if (!_this._readyOnce) return;
        _this.highlightLines();
      },
      'change:marker.opacityRegular': function changeMarkerOpacityRegular() {
        if (!_this._readyOnce) return;
        _this.highlightLines();
      }
    };

    this._super(config, context);

    this.xScale = null;
    this.yScale = null;

    this.rangeXRatio = 1;
    this.rangeXShift = 0;

    this.rangeYRatio = 1;
    this.rangeYShift = 0;
    this.lineWidthScale = d3.scale.linear().domain([0, 20]).range([7, 1]).clamp(true);
    this.xAxis = (0, _d2.default)().orient("bottom");
    this.yAxis = (0, _d2.default)().orient("left");

    this.isDataPreprocessed = false;
    this.timeUpdatedOnce = false;
    this.sizeUpdatedOnce = false;

    this.getNearestKey = utils.memoize(this.getNearestKey);
  },

  /*
   * domReady:
   * Executed after template is loaded
   * Ideally, it contains instantiations related to template
   */
  readyOnce: function readyOnce() {
    var _this = this;

    this.element = d3.select(this.element);
    this.graph = this.element.select('.vzb-lc-graph');

    this.yAxisElContainer = this.graph.select('.vzb-lc-axis-y');
    this.yAxisEl = this.yAxisElContainer.select('g');

    this.xAxisElContainer = this.graph.select('.vzb-lc-axis-x');
    this.xAxisEl = this.xAxisElContainer.select('g');

    this.xTitleEl = this.graph.select('.vzb-lc-axis-x-title');
    this.yTitleEl = this.graph.select('.vzb-lc-axis-y-title');
    this.yInfoEl = this.graph.select('.vzb-lc-axis-y-info');
    this.linesContainerCrop = this.graph.select('.vzb-lc-lines-crop');
    this.linesContainer = this.graph.select('.vzb-lc-lines');
    this.labelsContainerCrop = this.graph.select('.vzb-lc-labels-crop');
    this.labelsContainer = this.graph.select('.vzb-lc-labels');

    this.dataWarningEl = this.graph.select('.vzb-data-warning');

    this.verticalNow = this.labelsContainer.select(".vzb-lc-vertical-now");
    this.tooltip = this.element.select('.vzb-tooltip');
    //            this.filterDropshadowEl = this.element.select('#vzb-lc-filter-dropshadow');
    this.projectionX = this.graph.select(".vzb-lc-projection-x");
    this.projectionY = this.graph.select(".vzb-lc-projection-y");

    this.entityLines = null;
    this.entityLabels = null;
    this.totalLength_1 = {};

    this.KEY = this.model.entities.getDimension();
    this.collisionResolver = (0, _d4.default)().selector(".vzb-lc-label").value("valueY");

    //component events

    utils.setIcon(this.yInfoEl, _iconset.question).select("svg").attr("width", "0px").attr("height", "0px");

    this.yInfoEl.on("click", function () {
      _this.parent.findChildByName("gapminder-datanotes").pin();
    });
    this.yInfoEl.on("mouseover", function () {
      var rect = this.getBBox();
      var coord = utils.makeAbsoluteContext(this, this.farthestViewportElement)(rect.x - 10, rect.y + rect.height + 10);
      _this.parent.findChildByName("gapminder-datanotes").setHook('axis_y').show().setPos(coord.x, coord.y);
    });
    this.yInfoEl.on("mouseout", function () {
      _this.parent.findChildByName("gapminder-datanotes").hide();
    });

    this.wScale = d3.scale.linear().domain(this.model.ui.datawarning.doubtDomain).range(this.model.ui.datawarning.doubtRange);

    this.on("resize", function () {
      //return if updatesize exists with error
      if (_this.updateSize()) return;
      _this.updateTime();
      _this.redrawDataPoints();
    });
  },

  ready: function ready() {
    this.all_steps = this.model.time.getAllSteps();
    this.all_values = this.values = null;
    this.updateTime();
    this.updateUIStrings();
    this.updateShow();
    var _this = this;
    //null means we need to calculate all frames before we get to the callback
    this.model.marker.getFrame(null, function (allValues) {
      _this.all_values = allValues;
      _this.model.marker.getFrame(_this.model.time.value, function (values) {
        if (!_this._frameIsValid(values)) return;
        _this.values = values;
        _this.updateShow();
        _this.updateSize();
        _this.updateDoubtOpacity();
        _this.zoomToMaxMin();
        _this.redrawDataPoints();
        _this.linesContainerCrop.on('mousemove', _this.entityMousemove.bind(_this, null, null, _this)).on('mouseleave', _this.entityMouseout.bind(_this, null, null, _this));
      });
    });
  },

  _frameIsValid: function _frameIsValid(frame) {
    return !(!frame || Object.keys(frame.axis_y).length === 0 || Object.keys(frame.axis_x).length === 0 || Object.keys(frame.color).length === 0);
  },

  frameChanged: function frameChanged(frame, time) {
    //    if (time.toString() != this.model.time.value.toString()) return; // frame is outdated
    this.frame = frame;
    this.updateTime();
    if (!this.all_values) return;
    this.redrawDataPoints();
  },

  updateUIStrings: function updateUIStrings() {
    var _this = this;
    var conceptPropsY = _this.model.marker.axis_y.getConceptprops();
    var conceptPropsX = _this.model.marker.axis_x.getConceptprops();
    var conceptPropsC = _this.model.marker.color.getConceptprops();
    this.translator = this.model.locale.getTFunction();

    this.strings = {
      title: {
        Y: conceptPropsY.name,
        X: conceptPropsX.name,
        C: conceptPropsC.name
      },
      unit: {
        Y: conceptPropsY.unit || "",
        X: conceptPropsX.unit || "",
        C: conceptPropsC.unit || ""
      }
    };

    if (this.strings.unit.Y === "unit/" + this.model.marker.axis_y.which) this.strings.unit.Y = "";
    if (this.strings.unit.X === "unit/" + this.model.marker.axis_x.which) this.strings.unit.X = "";
    if (this.strings.unit.C === "unit/" + this.model.marker.color.which) this.strings.unit.C = "";

    if (!!this.strings.unit.Y) this.strings.unit.Y = ", " + this.strings.unit.Y;
    if (!!this.strings.unit.X) this.strings.unit.X = ", " + this.strings.unit.X;
    if (!!this.strings.unit.C) this.strings.unit.C = ", " + this.strings.unit.C;

    utils.setIcon(this.dataWarningEl, _iconset.warn).select("svg").attr("width", "0px").attr("height", "0px");
    this.dataWarningEl.append("text").attr("text-anchor", "end").text(this.translator("hints/dataWarning"));

    this.dataWarningEl.on("click", function () {
      _this.parent.findChildByName("gapminder-datawarning").toggle();
    }).on("mouseover", function () {
      _this.updateDoubtOpacity(1);
    }).on("mouseout", function () {
      _this.updateDoubtOpacity();
    });

    var xTitle = this.xTitleEl.selectAll("text").data([0]);
    xTitle.enter().append("text");

    var yTitle = this.yTitleEl.selectAll("text").data([0]);
    yTitle.enter().append("text");
    yTitle.on("click", function () {
      _this.parent.findChildByName("gapminder-treemenu").markerID("axis_y").alignX("left").alignY("top").updateView().toggle();
    });
  },

  updateDoubtOpacity: function updateDoubtOpacity(opacity) {
    if (opacity == null) opacity = this.wScale(+this.time.getUTCFullYear().toString());
    if (this.someSelected) opacity = 1;
    this.dataWarningEl.style("opacity", opacity);
  },

  /*
   * UPDATE SHOW:
   * Ideally should only update when show parameters change or data changes
   */
  updateShow: function updateShow() {
    var _this = this;
    var KEY = this.KEY;

    this.cached = {};
    //scales
    this.yScale = this.model.marker.axis_y.getScale();
    if (!this.splash) {
      var limits = this.model.marker.axis_y.getLimits(this.model.marker.axis_y.which);
      this.yScale.domain([limits.min, limits.max]);
    }
    this.xScale = this.model.marker.axis_x.getScale();
    this.cScale = this.model.marker.color.getScale();
    this.yAxis.tickFormat(this.model.marker.axis_y.getTickFormatter());
    this.xAxis.tickFormat(this.model.marker.axis_x.getTickFormatter());

    this.collisionResolver.scale(this.yScale).KEY(KEY);

    this.data = this.model.marker.getKeys();

    this.entityLines = this.linesContainer.selectAll('.vzb-lc-entity').data(this.data);
    this.entityLines.exit().remove();
    this.entityLines.enter().append("g").attr("class", "vzb-lc-entity").each(function (d, index) {
      var entity = d3.select(this);

      entity.append("path").attr("class", "vzb-lc-line-shadow");

      entity.append("path").attr("class", "vzb-lc-line");
    });

    this.entityLabels = this.labelsContainer.selectAll('.vzb-lc-entity').data(this.data);
    this.entityLabels.exit().remove();
    this.entityLabels.enter().append("g").attr("class", "vzb-lc-entity").each(function (d, index) {
      var entity = d3.select(this);

      entity.append("circle").attr("class", "vzb-lc-circle").attr("cx", 0);

      var labelGroup = entity.append("g").attr("class", "vzb-lc-label");

      labelGroup.append("text").attr("class", "vzb-lc-labelname").attr("dy", ".35em");

      labelGroup.append("text").attr("class", "vzb-lc-label-value").attr("dy", "1.6em");
    });

    if (this.all_values && this.values) {
      this.entityLabels.each(function (d, index) {
        var entity = d3.select(this);
        var color = _this.cScale(_this.values.color[d[KEY]]);
        var colorShadow = _this.model.marker.color.which == "geo.world_4region" ? _this.model.marker.color.getColorShade({
          colorID: _this.values.color[d[KEY]],
          shadeID: "shade"
        }) : d3.rgb(color).darker(0.5).toString();

        var label = _this.values.label[d[KEY]];
        var value = _this.yAxis.tickFormat()(_this.values.axis_y[d[KEY]]);
        var name = label.length < 13 ? label : label.substring(0, 10) + '...';
        var valueHideLimit = _this.ui.chart.labels.min_number_of_entities_when_values_hide;

        entity.select("circle").style("fill", color);
        entity.select(".vzb-lc-labelname").style("fill", colorShadow).text(name + " " + (_this.data.length < valueHideLimit ? value : ""));

        entity.select(".vzb-lc-label-value").style("fill", colorShadow);
      });
    }

    //line template
    this.line = d3.svg.line()
    //see https://bl.ocks.org/mbostock/4342190
    //"monotone" can also work. "basis" would skip the points on the sharp turns. "linear" is ugly
    .interpolate("cardinal").x(function (d) {
      return _this.xScale(d[0]);
    }).y(function (d) {
      return _this.yScale(d[1]);
    });
  },

  /*
   * UPDATE TIME:
   * Ideally should only update when time or data changes
   */
  updateTime: function updateTime() {
    var _this = this;
    var KEY = this.KEY;
    var time_1 = this.time === null ? this.model.time.value : this.time;
    this.time = this.model.time.value;
    this.duration = this.model.time.playing && this.time - time_1 > 0 ? this.model.time.delayAnimations : 0;

    var timeDim = this.model.time.getDimension();
    var filter = {};

    filter[timeDim] = this.time;

    this.prev_steps = this.all_steps.filter(function (f) {
      return f < _this.time;
    });

    this.timeUpdatedOnce = true;
  },

  profiles: {
    "small": {
      margin: {
        top: 30,
        right: 20,
        left: 40,
        bottom: 20
      },
      infoElHeight: 16,
      yAxisTitleBottomMargin: 6,
      tick_spacing: 60,
      text_padding: 12,
      lollipopRadius: 6,
      limitMaxTickNumberX: 5
    },
    "medium": {
      margin: {
        top: 40,
        right: 60,
        left: 60,
        bottom: 25
      },
      infoElHeight: 20,
      yAxisTitleBottomMargin: 6,
      tick_spacing: 80,
      text_padding: 15,
      lollipopRadius: 7,
      limitMaxTickNumberX: 10
    },
    "large": {
      margin: {
        top: 50,
        right: 60,
        left: 60,
        bottom: 30
      },
      infoElHeight: 22,
      yAxisTitleBottomMargin: 6,
      tick_spacing: 100,
      text_padding: 20,
      lollipopRadius: 9,
      limitMaxTickNumberX: 0 // unlimited
    }
  },
  presentationProfileChanges: {
    "medium": {
      margin: { top: 70, bottom: 40, left: 70 },
      yAxisTitleBottomMargin: 20,
      xAxisTitleBottomMargin: 20,
      infoElHeight: 26,
      text_padding: 30
    },
    "large": {
      margin: { top: 70, bottom: 50, left: 70 },
      yAxisTitleBottomMargin: 20,
      xAxisTitleBottomMargin: 20,
      infoElHeight: 32,
      text_padding: 36,
      hideSTitle: true
    }
  },

  timeSliderProfiles: {
    small: {
      margin: {
        top: 9,
        right: 15,
        bottom: 10,
        left: 10
      }
    },
    medium: {
      margin: {
        top: 9,
        right: 15,
        bottom: 10,
        left: 20
      }
    },
    large: {
      margin: {
        top: 9,
        right: 15,
        bottom: 10,
        left: 25
      }
    }
  },

  /*
   * RESIZE:
   * Executed whenever the container is resized
   * Ideally, it contains only operations related to size
   */
  updateSize: function updateSize() {

    var _this = this;
    var values = this.values;
    var KEY = this.KEY;

    var padding = 2;

    this.activeProfile = this.getActiveProfile(this.profiles, this.presentationProfileChanges);
    this.margin = this.activeProfile.margin;
    this.tick_spacing = this.activeProfile.tick_spacing;

    var infoElHeight = this.activeProfile.infoElHeight;

    //adjust right this.margin according to biggest label

    var longestLabelWidth = 0;

    this.entityLabels.selectAll(".vzb-lc-labelname").attr("dx", _this.activeProfile.text_padding).each(function (d, index) {
      var width = this.getComputedTextLength();
      if (width > longestLabelWidth) longestLabelWidth = width;
    });

    this.entityLabels.selectAll(".vzb-lc-circle").attr("r", _this.activeProfile.lollipopRadius);

    this.margin.right = Math.max(this.margin.right, longestLabelWidth + this.activeProfile.text_padding + 20);

    //stage
    this.height = parseInt(this.element.style("height"), 10) - this.margin.top - this.margin.bottom || 0;
    this.width = parseInt(this.element.style("width"), 10) - this.margin.left - this.margin.right || 0;
    this.linesContainerCrop.attr("width", this.width).attr("height", Math.max(0, this.height));

    this.labelsContainerCrop.attr("width", this.width + this.margin.right).attr("height", Math.max(0, this.height));

    if (this.height <= 0 || this.width <= 0) return utils.warn("Line chart updateSize() abort: vizabi container is too little or has display:none");

    this.collisionResolver.height(this.height);

    this.graph.attr("transform", "translate(" + this.margin.left + "," + this.margin.top + ")");

    this.yScale.range([this.height - this.activeProfile.lollipopRadius, this.activeProfile.lollipopRadius]);
    this.xScale.range([this.rangeXShift, this.width * this.rangeXRatio + this.rangeXShift]);

    this.yAxis.scale(this.yScale).orient("left").tickSize(-this.width, 0).tickPadding(6).tickSizeMinor(-this.width, 0).labelerOptions({
      scaleType: this.model.marker.axis_y.scaleType,
      toolMargin: this.margin,
      limitMaxTickNumber: 6,
      viewportLength: this.height,
      formatter: this.model.marker.axis_y.getTickFormatter()
    });

    this.xAxis.scale(this.xScale).tickSize(-this.height, 0).tickSizeMinor(-this.height, 0).tickPadding(6).labelerOptions({
      scaleType: this.model.marker.axis_x.scaleType,
      limitMaxTickNumber: this.activeProfile.limitMaxTickNumberX,
      toolMargin: this.margin,
      bump: this.activeProfile.text_padding * 2,
      formatter: this.model.marker.axis_x.getTickFormatter()
      //showOuter: true
    });

    this.xAxisElContainer.attr("width", this.width + this.activeProfile.text_padding * 2).attr("height", this.activeProfile.margin.bottom + this.height).attr("y", -1).attr("x", -this.activeProfile.text_padding);

    this.xAxisEl.attr("transform", "translate(" + (this.activeProfile.text_padding - 1) + "," + (this.height + 1) + ")");

    this.yAxisElContainer.attr("width", this.activeProfile.margin.left + this.width).attr("height", Math.max(0, this.height)).attr("x", -this.activeProfile.margin.left);
    this.yAxisEl.attr("transform", "translate(" + (this.activeProfile.margin.left - 1) + "," + 0 + ")");

    this.yAxisEl.call(this.yAxis);
    this.xAxisEl.call(this.xAxis);

    this.yTitleEl.style("font-size", infoElHeight + "px").attr("transform", "translate(" + (10 - this.activeProfile.margin.left) + ", -" + this.activeProfile.yAxisTitleBottomMargin + ")");

    var yTitleText = this.yTitleEl.select("text").text(this.strings.title.Y + this.strings.unit.Y);
    if (yTitleText.node().getBBox().width > this.width) yTitleText.text(this.strings.title.Y);

    if (this.yInfoEl.select('svg').node()) {
      var titleBBox = this.yTitleEl.node().getBBox();
      var translate = d3.transform(this.yTitleEl.attr('transform')).translate;

      this.yInfoEl.select('svg').attr("width", infoElHeight + "px").attr("height", infoElHeight + "px");
      this.yInfoEl.attr('transform', 'translate(' + (titleBBox.x + translate[0] + titleBBox.width + infoElHeight * .4) + ',' + (translate[1] - infoElHeight * 0.8) + ')');
    }

    var warnBB = this.dataWarningEl.select("text").node().getBBox();
    this.dataWarningEl.select("svg").attr("width", warnBB.height * 0.75).attr("height", warnBB.height * 0.75).attr("x", -warnBB.width - warnBB.height * 1.2).attr("y", -warnBB.height * 0.65);

    this.dataWarningEl.attr("transform", "translate(" + (this.width + warnBB.width + warnBB.height * 2) + ",-" + this.activeProfile.yAxisTitleBottomMargin + ")").select("text");

    var xTitleText = this.xTitleEl.select("text").text(this.strings.title.X + this.strings.unit.X);

    this.xTitleEl.style("font-size", infoElHeight + "px").attr("transform", "translate(" + (this.width + this.activeProfile.text_padding + this.activeProfile.yAxisTitleBottomMargin) + "," + (this.height + xTitleText.node().getBBox().height * 0.72) + ")");

    if (xTitleText.node().getBBox().width > this.width - 100) xTitleText.text(this.strings.title.X);

    // adjust the vertical dashed line
    this.verticalNow.attr("y1", this.yScale.range()[0]).attr("y2", this.yScale.range()[1]).attr("x1", 0).attr("x2", 0);
    this.projectionX.attr("y1", _this.yScale.range()[0]);
    this.projectionY.attr("x2", _this.xScale.range()[0]);

    if (utils.isTouchDevice()) {
      _this.tooltip.classed("vzb-hidden", true);
      _this.verticalNow.style("opacity", 1);
      _this.projectionX.style("opacity", 0);
      _this.projectionY.style("opacity", 0);
      _this.xAxisEl.call(_this.xAxis.highlightValue(_this.time));
      _this.yAxisEl.call(_this.yAxis.highlightValue("none"));
      _this.graph.selectAll(".vzb-lc-entity").each(function () {
        d3.select(this).classed("vzb-dimmed", false).classed("vzb-hovered", false);
      });

      _this.hoveringNow = null;
    }
    var opts = {
      rangeMax: this.xScale.range()[1],
      mRight: this.margin.right,
      profile: this.timeSliderProfiles[this.getLayoutProfile()]
    };
    this.parent.trigger('myEvent', opts);

    this.sizeUpdatedOnce = true;
  },

  /*
   * REDRAW DATA POINTS:
   * Here plotting happens
   */
  redrawDataPoints: function redrawDataPoints() {
    var _this = this;
    var KEY = this.KEY;
    //    var values = this.values;

    if (!_this.all_values) return;
    this.model.marker.getFrame(this.time, function (values, time) {
      if (!_this._frameIsValid(values)) return;
      _this.values = values;
      if (!_this.timeUpdatedOnce) {
        _this.updateTime();
      }
      if (!_this.sizeUpdatedOnce) {
        _this.updateSize();
      }
      _this.updateDoubtOpacity();

      _this.lineWidth = _this.lineWidthScale(_this.data.length);
      _this.shadowWidth = _this.lineWidth * 1.3;
      _this.entityLines.each(function (d, index) {
        var entity = d3.select(this);
        var label = values.label[d[KEY]];

        var color = _this.cScale(values.color[d[KEY]]);
        var colorShadow = _this.model.marker.color.which == "geo.world_4region" ? _this.model.marker.color.getColorShade({
          colorID: values.color[d[KEY]],
          shadeID: "shade"
        }) : d3.rgb(color).darker(0.5).toString();

        //TODO: optimization is possible if getValues would return both x and time
        //TODO: optimization is possible if getValues would return a limited number of points, say 1 point per screen pixel

        var xy = _this.prev_steps.map(function (frame, i) {
          return [frame, _this.all_values[frame] ? _this.all_values[frame].axis_y[d[KEY]] : null];
        }).filter(function (d) {
          return d[1] || d[1] === 0;
        });

        // add last point 
        if (values.axis_y[d[KEY]]) {
          xy.push([values.axis_x[d[KEY]], values.axis_y[d[KEY]]]);
        }

        if (xy.length > 0) {
          _this.cached[d[KEY]] = {
            valueX: xy[xy.length - 1][0],
            valueY: xy[xy.length - 1][1]
          };
        } else {
          delete _this.cached[d[KEY]];
        }

        // the following fixes the ugly line butts sticking out of the axis line
        //if(x[0]!=null && x[1]!=null) xy.splice(1, 0, [(+x[0]*0.99+x[1]*0.01), y[0]]);
        var path2 = entity.select(".vzb-lc-line");

        if (_this.model.time.playing && _this.totalLength_1[d[KEY]] === null) {
          _this.totalLength_1[d[KEY]] = path2.node().getTotalLength();
        }

        var path1 = entity.select(".vzb-lc-line-shadow").style("stroke", colorShadow).style("stroke-width", _this.shadowWidth + "px").attr("transform", "translate(0, " + (_this.shadowWidth - _this.lineWidth) + ")").attr("d", _this.line(xy));
        path2
        //.style("filter", "none")
        .style("stroke", color).style("stroke-width", _this.lineWidth + "px").attr("d", _this.line(xy));
        var totalLength = path2.node().getTotalLength();

        // this section ensures the smooth transition while playing and not needed otherwise
        if (_this.model.time.playing) {

          path1.interrupt().attr("stroke-dasharray", totalLength).attr("stroke-dashoffset", totalLength - _this.totalLength_1[d[KEY]]).transition().delay(0).duration(_this.duration).ease("linear").attr("stroke-dashoffset", 0);
          path2.interrupt().attr("stroke-dasharray", totalLength).attr("stroke-dashoffset", totalLength - _this.totalLength_1[d[KEY]]).transition().delay(0).duration(_this.duration).ease("linear").attr("stroke-dashoffset", 0);

          _this.totalLength_1[d[KEY]] = totalLength;
        } else {
          //reset saved line lengths
          _this.totalLength_1[d[KEY]] = null;

          path1.attr("stroke-dasharray", "none").attr("stroke-dashoffset", "none");

          path2.attr("stroke-dasharray", "none").attr("stroke-dashoffset", "none");
        }
      });

      _this.entityLabels.each(function (d, index) {
        var entity = d3.select(this);
        if (_this.cached[d[KEY]]) {
          entity.classed("vzb-hidden", false).transition().duration(_this.duration).ease("linear").attr("transform", "translate(" + _this.xScale(d3.min([_this.cached[d[KEY]]["valueX"]])) + ",0)");

          entity.select(".vzb-lc-circle").transition().duration(_this.duration).ease("linear").attr("cy", _this.yScale(_this.cached[d[KEY]]["valueY"]) + 1);

          entity.select(".vzb-lc-label").transition().duration(_this.duration).ease("linear").attr("transform", "translate(0," + _this.yScale(_this.cached[d[KEY]]["valueY"]) + ")");
        } else {
          entity.classed("vzb-hidden", true);
        }
      });
      _this.verticalNow.transition().duration(_this.duration).ease("linear").attr("transform", "translate(" + _this.xScale(d3.min([_this.model.marker.axis_x.zoomedMax, _this.time])) + ",0)");

      if (!_this.hoveringNow && _this.time - _this.model.time.start !== 0) {
        if (!_this.ui.chart.hideXAxisValue) _this.xAxisEl.call(_this.xAxis.highlightTransDuration(_this.duration).highlightValue(_this.time));
        _this.verticalNow.style("opacity", 1);
      } else {
        _this.verticalNow.style("opacity", 0);
      }

      // Call flush() after any zero-duration transitions to synchronously flush the timer queue
      // and thus make transition instantaneous. See https://github.com/mbostock/d3/issues/1951
      if (_this.duration == 0) {
        d3.timer.flush();
      }

      // cancel previously queued simulation if we just ordered a new one
      // then order a new collision resolving
      clearTimeout(_this.collisionTimeout);
      _this.collisionTimeout = setTimeout(function () {
        _this.entityLabels.call(_this.collisionResolver.data(_this.cached));
      }, _this.model.time.delayAnimations * 1.5);
    });
  },

  entityMousemove: function entityMousemove(me, index, context, closestToMouse) {
    var _this = context;
    var KEY = _this.KEY;
    var values = _this.values;

    var mouse = d3.mouse(_this.element.node()).map(function (d) {
      return parseInt(d);
    });

    var resolvedTime = _this.xScale.invert(mouse[0] - _this.margin.left);
    if (_this.time - resolvedTime < 0) {
      resolvedTime = _this.time;
    } else if (resolvedTime < this.model.time['start']) {
      resolvedTime = this.model.time['start'];
    }
    var resolvedValue;
    var timeDim = _this.model.time.getDimension();

    var mousePos = mouse[1] - _this.margin.top;

    if (!utils.isDate(resolvedTime)) resolvedTime = this.model.time.parse(resolvedTime);

    this.model.marker.getFrame(resolvedTime, function (data) {
      if (!_this._frameIsValid(data)) return;
      var nearestKey = _this.getNearestKey(mousePos, data.axis_y, _this.yScale.bind(_this));
      resolvedValue = data.axis_y[nearestKey];
      if (!me) me = {};
      me[KEY] = nearestKey;
      if (!_this.model.marker.isHighlighted(me)) {
        _this.model.marker.clearHighlighted();
        _this.model.marker.highlightMarker(me);
      }
      _this.hoveringNow = me;

      if (utils.isNaN(resolvedValue)) return;

      var scaledTime = _this.xScale(resolvedTime);
      var scaledValue = _this.yScale(resolvedValue);

      if (_this.ui.chart.whenHovering.showTooltip) {
        //position tooltip
        _this.tooltip
        //.style("right", (_this.width - scaledTime + _this.margin.right ) + "px")
        .style("left", scaledTime + _this.margin.left + "px").style("bottom", _this.height - scaledValue + _this.margin.bottom + "px").text(_this.yAxis.tickFormat()(resolvedValue)).classed("vzb-hidden", false);
      }

      // bring the projection lines to the hovering point
      if (_this.ui.chart.whenHovering.hideVerticalNow) {
        _this.verticalNow.style("opacity", 0);
      }

      if (_this.ui.chart.whenHovering.showProjectionLineX) {
        _this.projectionX.style("opacity", 1).attr("y2", scaledValue).attr("x1", scaledTime).attr("x2", scaledTime);
      }
      if (_this.ui.chart.whenHovering.showProjectionLineY) {
        _this.projectionY.style("opacity", 1).attr("y1", scaledValue).attr("y2", scaledValue).attr("x1", scaledTime);
      }

      if (_this.ui.chart.whenHovering.higlightValueX) _this.xAxisEl.call(_this.xAxis.highlightValue(resolvedTime).highlightTransDuration(0));

      if (_this.ui.chart.whenHovering.higlightValueY) _this.yAxisEl.call(_this.yAxis.highlightValue(resolvedValue).highlightTransDuration(0));

      clearTimeout(_this.unhoverTimeout);
    });
  },

  entityMouseout: function entityMouseout(me, index, context) {
    var _this = context;
    if (d3.event.relatedTarget && d3.select(d3.event.relatedTarget).classed('vzb-tooltip')) return;

    // hide and show things like it was before hovering
    _this.unhoverTimeout = setTimeout(function () {
      _this.tooltip.classed("vzb-hidden", true);
      _this.verticalNow.style("opacity", 1);
      _this.projectionX.style("opacity", 0);
      _this.projectionY.style("opacity", 0);
      _this.xAxisEl.call(_this.xAxis.highlightValue(_this.time));
      _this.yAxisEl.call(_this.yAxis.highlightValue("none"));

      _this.model.marker.clearHighlighted();

      _this.hoveringNow = null;
    }, 300);
  },

  /*
   * Highlights all hovered lines
   */
  highlightLines: function highlightLines() {
    var _this = this;

    var OPACITY_HIGHLT = 1.0;
    var OPACITY_HIGHLT_DIM = .3;
    var OPACITY_SELECT = this.model.marker.opacityRegular;
    var OPACITY_REGULAR = this.model.marker.opacityRegular;
    var OPACITY_SELECT_DIM = this.model.marker.opacitySelectDim;

    var someHighlighted = this.model.marker.highlight.length > 0;
    var someSelected = this.model.marker.select.length > 0;
    this.graph.selectAll(".vzb-lc-entity").each(function () {
      d3.select(this).style("opacity", function (d) {
        if (_this.model.marker.isHighlighted(d)) return OPACITY_HIGHLT;
        if (someSelected) {
          return _this.model.marker.isSelected(d) ? OPACITY_SELECT : OPACITY_SELECT_DIM;
        }
        if (someHighlighted) return OPACITY_HIGHLT_DIM;
        return OPACITY_REGULAR;
      });
    });
  },

  zoomToMaxMin: function zoomToMaxMin() {
    var _this = this;
    //
    /*
        if(this.model.marker.axis_y.zoomedMin == null ) this.model.marker.axis_y.zoomedMin = this.yScale.domain()[0];
        if(this.model.marker.axis_y.zoomedMax == null ) this.model.marker.axis_y.zoomedMax = this.yScale.domain()[1];
    */

    if (this.model.marker.axis_x.zoomedMin != null && this.model.marker.axis_x.zoomedMax != null) {
      this.xScale.domain([this.model.marker.axis_x.zoomedMin, this.model.marker.axis_x.zoomedMax]);
      this.xAxisEl.call(this.xAxis);
    }
    if (this.model.marker.axis_y.zoomedMin != null && this.model.marker.axis_y.zoomedMax != null) {
      if ((this.model.marker.axis_y.zoomedMin <= 0 || this.model.marker.axis_y.zoomedMax <= 0) && this.model.marker.axis_y.scaleType == "log") {
        this.yScale = d3.scale.genericLog().domain([this.model.marker.axis_y.zoomedMin, this.model.marker.axis_y.zoomedMax]).range(this.yScale.range());
        this.model.marker.axis_y.scale = d3.scale.genericLog().domain([this.model.marker.axis_y.zoomedMin, this.model.marker.axis_y.zoomedMax]).range(this.yScale.range());
        this.yScale = this.model.marker.axis_y.scale;
      } else {
        this.yScale.domain([this.model.marker.axis_y.zoomedMin, this.model.marker.axis_y.zoomedMax]);
      }
      this.yAxisEl.call(this.yAxis);
    }
  },

  /**
   * Returns key from obj which value has the smallest difference with val
   */
  getNearestKey: function getNearestKey(val, obj, fn) {
    var keys = Object.keys(obj);
    var resKey = keys[0];
    for (var i = 1; i < keys.length; i++) {
      var key = keys[i];
      if (Math.abs((fn ? fn(obj[key]) : obj[key]) - val) < Math.abs((fn ? fn(obj[resKey]) : obj[resKey]) - val)) {
        resKey = key;
      }
    }
    return resKey;
  }

}); /*!
     * VIZABI LINECHART
     */

exports.default = LCComponent;

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

"use strict";
// 22.1.3.6 Array.prototype.fill(value, start = 0, end = this.length)
'use strict';
var toObject = __webpack_require__(13)
  , toIndex  = __webpack_require__(56)
  , toLength = __webpack_require__(12);
module.exports = function fill(value /*, start = 0, end = @length */){
  var O      = toObject(this)
    , length = toLength(O.length)
    , aLen   = arguments.length
    , index  = toIndex(aLen > 1 ? arguments[1] : undefined, length)
    , end    = aLen > 2 ? arguments[2] : undefined
    , endPos = end === undefined ? length : toIndex(end, length);
  while(endPos > index)O[index++] = value;
  return O;
};

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

"use strict";
'use strict';
var $defineProperty = __webpack_require__(9)
  , createDesc      = __webpack_require__(42);

module.exports = function(object, index, value){
  if(index in object)$defineProperty.f(object, index, createDesc(0, value));
  else object[index] = value;
};

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

var isObject = __webpack_require__(6)
  , document = __webpack_require__(4).document
  // in old IE typeof document.createElement is 'object'
  , is = isObject(document) && isObject(document.createElement);
module.exports = function(it){
  return is ? document.createElement(it) : {};
};

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

// IE 8- don't enum bug keys
module.exports = (
  'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'
).split(',');

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

var MATCH = __webpack_require__(7)('match');
module.exports = function(KEY){
  var re = /./;
  try {
    '/./'[KEY](re);
  } catch(e){
    try {
      re[MATCH] = false;
      return !'/./'[KEY](re);
    } catch(f){ /* empty */ }
  } return true;
};

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

module.exports = __webpack_require__(4).document && document.documentElement;

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

var isObject       = __webpack_require__(6)
  , setPrototypeOf = __webpack_require__(103).set;
module.exports = function(that, target, C){
  var P, S = target.constructor;
  if(S !== C && typeof S == 'function' && (P = S.prototype) !== C.prototype && isObject(P) && setPrototypeOf){
    setPrototypeOf(that, P);
  } return that;
};

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

// check on default Array iterator
var Iterators  = __webpack_require__(62)
  , ITERATOR   = __webpack_require__(7)('iterator')
  , ArrayProto = Array.prototype;

module.exports = function(it){
  return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it);
};

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

// 7.2.2 IsArray(argument)
var cof = __webpack_require__(28);
module.exports = Array.isArray || function isArray(arg){
  return cof(arg) == 'Array';
};

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

"use strict";
'use strict';
var create         = __webpack_require__(51)
  , descriptor     = __webpack_require__(42)
  , setToStringTag = __webpack_require__(63)
  , IteratorPrototype = {};

// 25.1.2.1.1 %IteratorPrototype%[@@iterator]()
__webpack_require__(17)(IteratorPrototype, __webpack_require__(7)('iterator'), function(){ return this; });

module.exports = function(Constructor, NAME, next){
  Constructor.prototype = create(IteratorPrototype, {next: descriptor(1, next)});
  setToStringTag(Constructor, NAME + ' Iterator');
};

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

"use strict";
'use strict';
var LIBRARY        = __webpack_require__(50)
  , $export        = __webpack_require__(0)
  , redefine       = __webpack_require__(18)
  , hide           = __webpack_require__(17)
  , has            = __webpack_require__(15)
  , Iterators      = __webpack_require__(62)
  , $iterCreate    = __webpack_require__(98)
  , setToStringTag = __webpack_require__(63)
  , getPrototypeOf = __webpack_require__(26)
  , ITERATOR       = __webpack_require__(7)('iterator')
  , BUGGY          = !([].keys && 'next' in [].keys()) // Safari has buggy iterators w/o `next`
  , FF_ITERATOR    = '@@iterator'
  , KEYS           = 'keys'
  , VALUES         = 'values';

var returnThis = function(){ return this; };

module.exports = function(Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED){
  $iterCreate(Constructor, NAME, next);
  var getMethod = function(kind){
    if(!BUGGY && kind in proto)return proto[kind];
    switch(kind){
      case KEYS: return function keys(){ return new Constructor(this, kind); };
      case VALUES: return function values(){ return new Constructor(this, kind); };
    } return function entries(){ return new Constructor(this, kind); };
  };
  var TAG        = NAME + ' Iterator'
    , DEF_VALUES = DEFAULT == VALUES
    , VALUES_BUG = false
    , proto      = Base.prototype
    , $native    = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT]
    , $default   = $native || getMethod(DEFAULT)
    , $entries   = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined
    , $anyNative = NAME == 'Array' ? proto.entries || $native : $native
    , methods, key, IteratorPrototype;
  // Fix native
  if($anyNative){
    IteratorPrototype = getPrototypeOf($anyNative.call(new Base));
    if(IteratorPrototype !== Object.prototype){
      // Set @@toStringTag to native iterators
      setToStringTag(IteratorPrototype, TAG, true);
      // fix for some old engines
      if(!LIBRARY && !has(IteratorPrototype, ITERATOR))hide(IteratorPrototype, ITERATOR, returnThis);
    }
  }
  // fix Array#{values, @@iterator}.name in V8 / FF
  if(DEF_VALUES && $native && $native.name !== VALUES){
    VALUES_BUG = true;
    $default = function values(){ return $native.call(this); };
  }
  // Define iterator
  if((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])){
    hide(proto, ITERATOR, $default);
  }
  // Plug for library
  Iterators[NAME] = $default;
  Iterators[TAG]  = returnThis;
  if(DEFAULT){
    methods = {
      values:  DEF_VALUES ? $default : getMethod(VALUES),
      keys:    IS_SET     ? $default : getMethod(KEYS),
      entries: $entries
    };
    if(FORCED)for(key in methods){
      if(!(key in proto))redefine(proto, key, methods[key]);
    } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods);
  }
  return methods;
};

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

// 20.2.2.14 Math.expm1(x)
var $expm1 = Math.expm1;
module.exports = (!$expm1
  // Old FF bug
  || $expm1(10) > 22025.465794806719 || $expm1(10) < 22025.4657948067165168
  // Tor Browser bug
  || $expm1(-2e-17) != -2e-17
) ? function expm1(x){
  return (x = +x) == 0 ? x : x > -1e-6 && x < 1e-6 ? x + x * x / 2 : Math.exp(x) - 1;
} : $expm1;

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

// 20.2.2.28 Math.sign(x)
module.exports = Math.sign || function sign(x){
  return (x = +x) == 0 || x != x ? x : x < 0 ? -1 : 1;
};

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

var global    = __webpack_require__(4)
  , macrotask = __webpack_require__(110).set
  , Observer  = global.MutationObserver || global.WebKitMutationObserver
  , process   = global.process
  , Promise   = global.Promise
  , isNode    = __webpack_require__(28)(process) == 'process';

module.exports = function(){
  var head, last, notify;

  var flush = function(){
    var parent, fn;
    if(isNode && (parent = process.domain))parent.exit();
    while(head){
      fn   = head.fn;
      head = head.next;
      try {
        fn();
      } catch(e){
        if(head)notify();
        else last = undefined;
        throw e;
      }
    } last = undefined;
    if(parent)parent.enter();
  };

  // Node.js
  if(isNode){
    notify = function(){
      process.nextTick(flush);
    };
  // browsers with MutationObserver
  } else if(Observer){
    var toggle = true
      , node   = document.createTextNode('');
    new Observer(flush).observe(node, {characterData: true}); // eslint-disable-line no-new
    notify = function(){
      node.data = toggle = !toggle;
    };
  // environments with maybe non-completely correct, but existent Promise
  } else if(Promise && Promise.resolve){
    var promise = Promise.resolve();
    notify = function(){
      promise.then(flush);
    };
  // for other environments - macrotask based on:
  // - setImmediate
  // - MessageChannel
  // - window.postMessag
  // - onreadystatechange
  // - setTimeout
  } else {
    notify = function(){
      // strange IE + webpack dev server bug - use .call(global)
      macrotask.call(global, flush);
    };
  }

  return function(fn){
    var task = {fn: fn, next: undefined};
    if(last)last.next = task;
    if(!head){
      head = task;
      notify();
    } last = task;
  };
};

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

// Works with __proto__ only. Old v8 can't work with null proto objects.
/* eslint-disable no-proto */
var isObject = __webpack_require__(6)
  , anObject = __webpack_require__(3);
var check = function(O, proto){
  anObject(O);
  if(!isObject(proto) && proto !== null)throw TypeError(proto + ": can't set as prototype!");
};
module.exports = {
  set: Object.setPrototypeOf || ('__proto__' in {} ? // eslint-disable-line
    function(test, buggy, set){
      try {
        set = __webpack_require__(35)(Function.call, __webpack_require__(25).f(Object.prototype, '__proto__').set, 2);
        set(test, []);
        buggy = !(test instanceof Array);
      } catch(e){ buggy = true; }
      return function setPrototypeOf(O, proto){
        check(O, proto);
        if(buggy)O.__proto__ = proto;
        else set(O, proto);
        return O;
      };
    }({}, false) : undefined),
  check: check
};

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

var shared = __webpack_require__(81)('keys')
  , uid    = __webpack_require__(57);
module.exports = function(key){
  return shared[key] || (shared[key] = uid(key));
};

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

// 7.3.20 SpeciesConstructor(O, defaultConstructor)
var anObject  = __webpack_require__(3)
  , aFunction = __webpack_require__(16)
  , SPECIES   = __webpack_require__(7)('species');
module.exports = function(O, D){
  var C = anObject(O).constructor, S;
  return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S);
};

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

var toInteger = __webpack_require__(43)
  , defined   = __webpack_require__(29);
// true  -> String#at
// false -> String#codePointAt
module.exports = function(TO_STRING){
  return function(that, pos){
    var s = String(defined(that))
      , i = toInteger(pos)
      , l = s.length
      , a, b;
    if(i < 0 || i >= l)return TO_STRING ? '' : undefined;
    a = s.charCodeAt(i);
    return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff
      ? TO_STRING ? s.charAt(i) : a
      : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;
  };
};

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

// helper for String#{startsWith, endsWith, includes}
var isRegExp = __webpack_require__(77)
  , defined  = __webpack_require__(29);

module.exports = function(that, searchString, NAME){
  if(isRegExp(searchString))throw TypeError('String#' + NAME + " doesn't accept regex!");
  return String(defined(that));
};

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

"use strict";
'use strict';
var toInteger = __webpack_require__(43)
  , defined   = __webpack_require__(29);

module.exports = function repeat(count){
  var str = String(defined(this))
    , res = ''
    , n   = toInteger(count);
  if(n < 0 || n == Infinity)throw RangeError("Count can't be negative");
  for(;n > 0; (n >>>= 1) && (str += str))if(n & 1)res += str;
  return res;
};

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

module.exports = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' +
  '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF';

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

var ctx                = __webpack_require__(35)
  , invoke             = __webpack_require__(76)
  , html               = __webpack_require__(94)
  , cel                = __webpack_require__(91)
  , global             = __webpack_require__(4)
  , process            = global.process
  , setTask            = global.setImmediate
  , clearTask          = global.clearImmediate
  , MessageChannel     = global.MessageChannel
  , counter            = 0
  , queue              = {}
  , ONREADYSTATECHANGE = 'onreadystatechange'
  , defer, channel, port;
var run = function(){
  var id = +this;
  if(queue.hasOwnProperty(id)){
    var fn = queue[id];
    delete queue[id];
    fn();
  }
};
var listener = function(event){
  run.call(event.data);
};
// Node.js 0.9+ & IE10+ has setImmediate, otherwise:
if(!setTask || !clearTask){
  setTask = function setImmediate(fn){
    var args = [], i = 1;
    while(arguments.length > i)args.push(arguments[i++]);
    queue[++counter] = function(){
      invoke(typeof fn == 'function' ? fn : Function(fn), args);
    };
    defer(counter);
    return counter;
  };
  clearTask = function clearImmediate(id){
    delete queue[id];
  };
  // Node.js 0.8-
  if(__webpack_require__(28)(process) == 'process'){
    defer = function(id){
      process.nextTick(ctx(run, id, 1));
    };
  // Browsers with MessageChannel, includes WebWorkers
  } else if(MessageChannel){
    channel = new MessageChannel;
    port    = channel.port2;
    channel.port1.onmessage = listener;
    defer = ctx(port.postMessage, port, 1);
  // Browsers with postMessage, skip WebWorkers
  // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'
  } else if(global.addEventListener && typeof postMessage == 'function' && !global.importScripts){
    defer = function(id){
      global.postMessage(id + '', '*');
    };
    global.addEventListener('message', listener, false);
  // IE8-
  } else if(ONREADYSTATECHANGE in cel('script')){
    defer = function(id){
      html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function(){
        html.removeChild(this);
        run.call(id);
      };
    };
  // Rest old browsers
  } else {
    defer = function(id){
      setTimeout(ctx(run, id, 1), 0);
    };
  }
}
module.exports = {
  set:   setTask,
  clear: clearTask
};

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

"use strict";
'use strict';
var global         = __webpack_require__(4)
  , DESCRIPTORS    = __webpack_require__(8)
  , LIBRARY        = __webpack_require__(50)
  , $typed         = __webpack_require__(82)
  , hide           = __webpack_require__(17)
  , redefineAll    = __webpack_require__(54)
  , fails          = __webpack_require__(5)
  , anInstance     = __webpack_require__(49)
  , toInteger      = __webpack_require__(43)
  , toLength       = __webpack_require__(12)
  , gOPN           = __webpack_require__(52).f
  , dP             = __webpack_require__(9).f
  , arrayFill      = __webpack_require__(89)
  , setToStringTag = __webpack_require__(63)
  , ARRAY_BUFFER   = 'ArrayBuffer'
  , DATA_VIEW      = 'DataView'
  , PROTOTYPE      = 'prototype'
  , WRONG_LENGTH   = 'Wrong length!'
  , WRONG_INDEX    = 'Wrong index!'
  , $ArrayBuffer   = global[ARRAY_BUFFER]
  , $DataView      = global[DATA_VIEW]
  , Math           = global.Math
  , RangeError     = global.RangeError
  , Infinity       = global.Infinity
  , BaseBuffer     = $ArrayBuffer
  , abs            = Math.abs
  , pow            = Math.pow
  , floor          = Math.floor
  , log            = Math.log
  , LN2            = Math.LN2
  , BUFFER         = 'buffer'
  , BYTE_LENGTH    = 'byteLength'
  , BYTE_OFFSET    = 'byteOffset'
  , $BUFFER        = DESCRIPTORS ? '_b' : BUFFER
  , $LENGTH        = DESCRIPTORS ? '_l' : BYTE_LENGTH
  , $OFFSET        = DESCRIPTORS ? '_o' : BYTE_OFFSET;

// IEEE754 conversions based on https://github.com/feross/ieee754
var packIEEE754 = function(value, mLen, nBytes){
  var buffer = Array(nBytes)
    , eLen   = nBytes * 8 - mLen - 1
    , eMax   = (1 << eLen) - 1
    , eBias  = eMax >> 1
    , rt     = mLen === 23 ? pow(2, -24) - pow(2, -77) : 0
    , i      = 0
    , s      = value < 0 || value === 0 && 1 / value < 0 ? 1 : 0
    , e, m, c;
  value = abs(value)
  if(value != value || value === Infinity){
    m = value != value ? 1 : 0;
    e = eMax;
  } else {
    e = floor(log(value) / LN2);
    if(value * (c = pow(2, -e)) < 1){
      e--;
      c *= 2;
    }
    if(e + eBias >= 1){
      value += rt / c;
    } else {
      value += rt * pow(2, 1 - eBias);
    }
    if(value * c >= 2){
      e++;
      c /= 2;
    }
    if(e + eBias >= eMax){
      m = 0;
      e = eMax;
    } else if(e + eBias >= 1){
      m = (value * c - 1) * pow(2, mLen);
      e = e + eBias;
    } else {
      m = value * pow(2, eBias - 1) * pow(2, mLen);
      e = 0;
    }
  }
  for(; mLen >= 8; buffer[i++] = m & 255, m /= 256, mLen -= 8);
  e = e << mLen | m;
  eLen += mLen;
  for(; eLen > 0; buffer[i++] = e & 255, e /= 256, eLen -= 8);
  buffer[--i] |= s * 128;
  return buffer;
};
var unpackIEEE754 = function(buffer, mLen, nBytes){
  var eLen  = nBytes * 8 - mLen - 1
    , eMax  = (1 << eLen) - 1
    , eBias = eMax >> 1
    , nBits = eLen - 7
    , i     = nBytes - 1
    , s     = buffer[i--]
    , e     = s & 127
    , m;
  s >>= 7;
  for(; nBits > 0; e = e * 256 + buffer[i], i--, nBits -= 8);
  m = e & (1 << -nBits) - 1;
  e >>= -nBits;
  nBits += mLen;
  for(; nBits > 0; m = m * 256 + buffer[i], i--, nBits -= 8);
  if(e === 0){
    e = 1 - eBias;
  } else if(e === eMax){
    return m ? NaN : s ? -Infinity : Infinity;
  } else {
    m = m + pow(2, mLen);
    e = e - eBias;
  } return (s ? -1 : 1) * m * pow(2, e - mLen);
};

var unpackI32 = function(bytes){
  return bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0];
};
var packI8 = function(it){
  return [it & 0xff];
};
var packI16 = function(it){
  return [it & 0xff, it >> 8 & 0xff];
};
var packI32 = function(it){
  return [it & 0xff, it >> 8 & 0xff, it >> 16 & 0xff, it >> 24 & 0xff];
};
var packF64 = function(it){
  return packIEEE754(it, 52, 8);
};
var packF32 = function(it){
  return packIEEE754(it, 23, 4);
};

var addGetter = function(C, key, internal){
  dP(C[PROTOTYPE], key, {get: function(){ return this[internal]; }});
};

var get = function(view, bytes, index, isLittleEndian){
  var numIndex = +index
    , intIndex = toInteger(numIndex);
  if(numIndex != intIndex || intIndex < 0 || intIndex + bytes > view[$LENGTH])throw RangeError(WRONG_INDEX);
  var store = view[$BUFFER]._b
    , start = intIndex + view[$OFFSET]
    , pack  = store.slice(start, start + bytes);
  return isLittleEndian ? pack : pack.reverse();
};
var set = function(view, bytes, index, conversion, value, isLittleEndian){
  var numIndex = +index
    , intIndex = toInteger(numIndex);
  if(numIndex != intIndex || intIndex < 0 || intIndex + bytes > view[$LENGTH])throw RangeError(WRONG_INDEX);
  var store = view[$BUFFER]._b
    , start = intIndex + view[$OFFSET]
    , pack  = conversion(+value);
  for(var i = 0; i < bytes; i++)store[start + i] = pack[isLittleEndian ? i : bytes - i - 1];
};

var validateArrayBufferArguments = function(that, length){
  anInstance(that, $ArrayBuffer, ARRAY_BUFFER);
  var numberLength = +length
    , byteLength   = toLength(numberLength);
  if(numberLength != byteLength)throw RangeError(WRONG_LENGTH);
  return byteLength;
};

if(!$typed.ABV){
  $ArrayBuffer = function ArrayBuffer(length){
    var byteLength = validateArrayBufferArguments(this, length);
    this._b       = arrayFill.call(Array(byteLength), 0);
    this[$LENGTH] = byteLength;
  };

  $DataView = function DataView(buffer, byteOffset, byteLength){
    anInstance(this, $DataView, DATA_VIEW);
    anInstance(buffer, $ArrayBuffer, DATA_VIEW);
    var bufferLength = buffer[$LENGTH]
      , offset       = toInteger(byteOffset);
    if(offset < 0 || offset > bufferLength)throw RangeError('Wrong offset!');
    byteLength = byteLength === undefined ? bufferLength - offset : toLength(byteLength);
    if(offset + byteLength > bufferLength)throw RangeError(WRONG_LENGTH);
    this[$BUFFER] = buffer;
    this[$OFFSET] = offset;
    this[$LENGTH] = byteLength;
  };

  if(DESCRIPTORS){
    addGetter($ArrayBuffer, BYTE_LENGTH, '_l');
    addGetter($DataView, BUFFER, '_b');
    addGetter($DataView, BYTE_LENGTH, '_l');
    addGetter($DataView, BYTE_OFFSET, '_o');
  }

  redefineAll($DataView[PROTOTYPE], {
    getInt8: function getInt8(byteOffset){
      return get(this, 1, byteOffset)[0] << 24 >> 24;
    },
    getUint8: function getUint8(byteOffset){
      return get(this, 1, byteOffset)[0];
    },
    getInt16: function getInt16(byteOffset /*, littleEndian */){
      var bytes = get(this, 2, byteOffset, arguments[1]);
      return (bytes[1] << 8 | bytes[0]) << 16 >> 16;
    },
    getUint16: function getUint16(byteOffset /*, littleEndian */){
      var bytes = get(this, 2, byteOffset, arguments[1]);
      return bytes[1] << 8 | bytes[0];
    },
    getInt32: function getInt32(byteOffset /*, littleEndian */){
      return unpackI32(get(this, 4, byteOffset, arguments[1]));
    },
    getUint32: function getUint32(byteOffset /*, littleEndian */){
      return unpackI32(get(this, 4, byteOffset, arguments[1])) >>> 0;
    },
    getFloat32: function getFloat32(byteOffset /*, littleEndian */){
      return unpackIEEE754(get(this, 4, byteOffset, arguments[1]), 23, 4);
    },
    getFloat64: function getFloat64(byteOffset /*, littleEndian */){
      return unpackIEEE754(get(this, 8, byteOffset, arguments[1]), 52, 8);
    },
    setInt8: function setInt8(byteOffset, value){
      set(this, 1, byteOffset, packI8, value);
    },
    setUint8: function setUint8(byteOffset, value){
      set(this, 1, byteOffset, packI8, value);
    },
    setInt16: function setInt16(byteOffset, value /*, littleEndian */){
      set(this, 2, byteOffset, packI16, value, arguments[2]);
    },
    setUint16: function setUint16(byteOffset, value /*, littleEndian */){
      set(this, 2, byteOffset, packI16, value, arguments[2]);
    },
    setInt32: function setInt32(byteOffset, value /*, littleEndian */){
      set(this, 4, byteOffset, packI32, value, arguments[2]);
    },
    setUint32: function setUint32(byteOffset, value /*, littleEndian */){
      set(this, 4, byteOffset, packI32, value, arguments[2]);
    },
    setFloat32: function setFloat32(byteOffset, value /*, littleEndian */){
      set(this, 4, byteOffset, packF32, value, arguments[2]);
    },
    setFloat64: function setFloat64(byteOffset, value /*, littleEndian */){
      set(this, 8, byteOffset, packF64, value, arguments[2]);
    }
  });
} else {
  if(!fails(function(){
    new $ArrayBuffer;     // eslint-disable-line no-new
  }) || !fails(function(){
    new $ArrayBuffer(.5); // eslint-disable-line no-new
  })){
    $ArrayBuffer = function ArrayBuffer(length){
      return new BaseBuffer(validateArrayBufferArguments(this, length));
    };
    var ArrayBufferProto = $ArrayBuffer[PROTOTYPE] = BaseBuffer[PROTOTYPE];
    for(var keys = gOPN(BaseBuffer), j = 0, key; keys.length > j; ){
      if(!((key = keys[j++]) in $ArrayBuffer))hide($ArrayBuffer, key, BaseBuffer[key]);
    };
    if(!LIBRARY)ArrayBufferProto.constructor = $ArrayBuffer;
  }
  // iOS Safari 7.x bug
  var view = new $DataView(new $ArrayBuffer(2))
    , $setInt8 = $DataView[PROTOTYPE].setInt8;
  view.setInt8(0, 2147483648);
  view.setInt8(1, 2147483649);
  if(view.getInt8(0) || !view.getInt8(1))redefineAll($DataView[PROTOTYPE], {
    setInt8: function setInt8(byteOffset, value){
      $setInt8.call(this, byteOffset, value << 24 >> 24);
    },
    setUint8: function setUint8(byteOffset, value){
      $setInt8.call(this, byteOffset, value << 24 >> 24);
    }
  }, true);
}
setToStringTag($ArrayBuffer, ARRAY_BUFFER);
setToStringTag($DataView, DATA_VIEW);
hide($DataView[PROTOTYPE], $typed.VIEW, true);
exports[ARRAY_BUFFER] = $ArrayBuffer;
exports[DATA_VIEW] = $DataView;

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

var global         = __webpack_require__(4)
  , core           = __webpack_require__(34)
  , LIBRARY        = __webpack_require__(50)
  , wksExt         = __webpack_require__(174)
  , defineProperty = __webpack_require__(9).f;
module.exports = function(name){
  var $Symbol = core.Symbol || (core.Symbol = LIBRARY ? {} : global.Symbol || {});
  if(name.charAt(0) != '_' && !(name in $Symbol))defineProperty($Symbol, name, {value: wksExt.f(name)});
};

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

var classof   = __webpack_require__(67)
  , ITERATOR  = __webpack_require__(7)('iterator')
  , Iterators = __webpack_require__(62);
module.exports = __webpack_require__(34).getIteratorMethod = function(it){
  if(it != undefined)return it[ITERATOR]
    || it['@@iterator']
    || Iterators[classof(it)];
};

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

"use strict";
'use strict';
var addToUnscopables = __webpack_require__(60)
  , step             = __webpack_require__(162)
  , Iterators        = __webpack_require__(62)
  , toIObject        = __webpack_require__(20);

// 22.1.3.4 Array.prototype.entries()
// 22.1.3.13 Array.prototype.keys()
// 22.1.3.29 Array.prototype.values()
// 22.1.3.30 Array.prototype[@@iterator]()
module.exports = __webpack_require__(99)(Array, 'Array', function(iterated, kind){
  this._t = toIObject(iterated); // target
  this._i = 0;                   // next index
  this._k = kind;                // kind
// 22.1.5.2.1 %ArrayIteratorPrototype%.next()
}, function(){
  var O     = this._t
    , kind  = this._k
    , index = this._i++;
  if(!O || index >= O.length){
    this._t = undefined;
    return step(1);
  }
  if(kind == 'keys'  )return step(0, index);
  if(kind == 'values')return step(0, O[index]);
  return step(0, [index, O[index]]);
}, 'values');

// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)
Iterators.Arguments = Iterators.Array;

addToUnscopables('keys');
addToUnscopables('values');
addToUnscopables('entries');

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _buttonlist = __webpack_require__(22);

var _buttonlist2 = _interopRequireDefault(_buttonlist);

var _iconset = __webpack_require__(10);

var iconset = _interopRequireWildcard(_iconset);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*!
 * VIZABI OPTIONSBUTTONLIST
 * Reusable optionsbuttonlist component
 */

//default existing buttons
var class_active = "vzb-active";
// var class_active_locked = "vzb-active-locked";
// var class_expand_dialog = "vzb-dialog-side";
// var class_hide_btn = "vzb-dialog-side-btn";
// var class_unavailable = "vzb-unavailable";
// var class_vzb_fullscreen = "vzb-force-fullscreen";
// var class_container_fullscreen = "vzb-container-fullscreen";

var OptionsButtonList = _buttonlist2.default.extend({

  /**
   * Initializes the buttonlist
   * @param config component configuration
   * @param context component context (parent)
   */
  init: function init(config, context) {

    //set properties
    var _this = this;
    this.name = 'gapminder-optionsbuttonlist';

    this._super(config, context);
  },

  readyOnce: function readyOnce() {
    var _this = this;
    Object.keys(this._available_buttons).forEach(function (buttonId) {
      var button = _this._available_buttons[buttonId];
      button.required = !button.required;
    });

    this.buttonListComp = this.root.findChildByName("gapminder-buttonlist");

    this.buttonListComp.on("click", function (evt, button) {
      var btn = _this.element.selectAll(".vzb-buttonlist-btn[data-btn='" + button.id + "']");
      btn.classed(class_active, button.active);
    });

    this.buttonListComp.on("toggle", function (evt, params) {
      var btn = _this.element.selectAll(".vzb-buttonlist-btn");
      var visibleButton = 0;
      btn.each(function (d) {
        var button = d3.select(this);
        var isHidden = params.hiddenButtons.indexOf(d.id) == -1;
        button.style('display', isHidden ? 'none' : '');
        if (!isHidden) visibleButton++;
      });
    });

    this._super();
  },

  proceedClick: function proceedClick(id) {
    var _this = this;
    this.buttonListComp.proceedClick(id);
    var btn_data = this.element.selectAll(".vzb-buttonlist-btn[data-btn='" + id + "']").datum();
    if (btn_data.func) {
      setTimeout(function () {
        _this.root.findChildByName("gapminder-dialogs").closeAllDialogs();
      }, 200);
    }
  },

  _toggleButtons: function _toggleButtons() {
    //
  }

});

exports.default = OptionsButtonList;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
    value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _dialog = __webpack_require__(11);

var _dialog2 = _interopRequireDefault(_dialog);

var _globals = __webpack_require__(44);

var _globals2 = _interopRequireDefault(_globals);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*
 * Size dialog
 */

var About = _dialog2.default.extend({

    /**
     * Initializes the dialog component
     * @param config component configuration
     * @param context component context (parent)
     */
    init: function init(config, parent) {
        this.name = 'about';

        this._super(config, parent);
    },

    readyOnce: function readyOnce() {
        var version = _globals2.default.version;
        var updated = new Date(parseInt(_globals2.default.build));

        this.element = d3.select(this.element);
        this.element.select(".vzb-about-text0").html("This chart is made with Vizabi,");
        this.element.select(".vzb-about-text1").html("a project by <a href='http://gapminder.org'>Gapminder Foundation</a>");
        this.element.select(".vzb-about-version").html("<a href='https://github.com/Gapminder/vizabi/releases/tag/v" + version + "'>Version: " + version + " (alpha)</a>");
        this.element.select(".vzb-about-updated").html("Build: " + d3.time.format("%Y-%m-%d at %H:%M")(updated));
        this.element.select(".vzb-about-text2").html("Alpha version: don't expect too much!");
        this.element.select(".vzb-about-report").html("<a href='https://getsatisfaction.com/gapminder/'>Report a problem</a>");
        this.element.select(".vzb-about-credits").html("<a href='https://github.com/Gapminder/vizabi/graphs/contributors'>Contributors</a>");
    }

});

exports.default = About;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _dialog = __webpack_require__(11);

var _dialog2 = _interopRequireDefault(_dialog);

var _indicatorpicker = __webpack_require__(47);

var _indicatorpicker2 = _interopRequireDefault(_indicatorpicker);

var _minmaxinputs = __webpack_require__(85);

var _minmaxinputs2 = _interopRequireDefault(_minmaxinputs);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*
 * Axes dialog
 */

var Axes = _dialog2.default.extend({

  /**
   * Initializes the dialog component
   * @param config component configuration
   * @param context component context (parent)
   */
  init: function init(config, parent) {
    this.name = 'axes';
    var _this = this;

    this.components = [{
      component: _indicatorpicker2.default,
      placeholder: '.vzb-xaxis-selector',
      model: ["state.time", "state.entities", "state.marker", "locale"],
      markerID: "axis_x"
    }, {
      component: _minmaxinputs2.default,
      placeholder: '.vzb-xaxis-minmax',
      model: ["state.marker", "state.time", "locale"],
      markerID: "axis_x",
      ui: {
        selectDomainMinMax: false,
        selectZoomedMinMax: true
      }
    }, {
      component: _indicatorpicker2.default,
      placeholder: '.vzb-yaxis-selector',
      model: ["state.time", "state.entities", "state.marker", "locale"],
      markerID: "axis_y"
    }, {
      component: _minmaxinputs2.default,
      placeholder: '.vzb-yaxis-minmax',
      model: ["state.marker", "state.time", "locale"],
      markerID: "axis_y",
      ui: {
        selectDomainMinMax: false,
        selectZoomedMinMax: true
      }
    }];

    this._super(config, parent);
  }
});

exports.default = Axes;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _dialog = __webpack_require__(11);

var _dialog2 = _interopRequireDefault(_dialog);

var _minmaxinputs = __webpack_require__(85);

var _minmaxinputs2 = _interopRequireDefault(_minmaxinputs);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*
 * Axes dialog
 */

var Axes = _dialog2.default.extend({

  /**
   * Initializes the dialog component
   * @param config component configuration
   * @param context component context (parent)
   */
  init: function init(config, parent) {
    this.name = 'axesmc';
    var _this = this;

    this.model_binds = {
      'change:ui.chart.xLogStops': function changeUiChartXLogStops() {
        _this.updateView();
      },
      'change:ui.chart.yMaxMethod': function changeUiChartYMaxMethod() {
        _this.updateView();
      }
    };

    this.components = [{
      component: _minmaxinputs2.default,
      placeholder: '.vzb-xlimits-container',
      model: ["state.marker", "state.time", "locale"],
      markerID: "axis_x",
      ui: {
        selectDomainMinMax: false,
        selectZoomedMinMax: true
      }
    }];

    this._super(config, parent);
  },

  readyOnce: function readyOnce() {
    this._super();

    var _this = this;

    this.yMaxRadio = this.element.select('.vzb-yaxis-container').selectAll('input').on("change", function () {
      _this.setModel("yMaxMethod", d3.select(this).node().value);
    });

    this.xLogStops = this.element.select('.vzb-xaxis-container').selectAll('input').on("change", function () {
      _this.setModel("xLogStops", d3.select(this).node().value);
    });

    this.probeCheck = this.element.select(".vzb-probe-check").on("change", function () {
      _this.setModel("showProbeX", d3.select(this).property('checked'));
    });

    this.probeFieldEl = this.element.select(".vzb-probe-field").on("change", function () {
      var result = parseFloat(this.value.replace(",", "."));
      if (!result || result <= _this.model.state.marker.axis_x.tailCutX) {
        this.value = _this.model.ui.chart.probeX;
        return;
      } else if (result > _this.model.state.marker.axis_x.domainMax) {
        result = _this.model.state.marker.axis_x.domainMax;
      }
      this.value = result;
      _this.setModel("probeX", result);
    });

    this.updateView();
  },

  updateView: function updateView() {
    var _this = this;

    this.yMaxRadio.property('checked', function () {
      return d3.select(this).node().value === _this.model.ui.chart.yMaxMethod;
    });
    this.xLogStops.property('checked', function () {
      return _this.model.ui.chart.xLogStops.indexOf(+d3.select(this).node().value) !== -1;
    });
    this.probeCheck.property('checked', this.model.ui.chart.showProbeX);
    this.probeFieldEl.property("value", this.model.ui.chart.probeX);
  },

  setModel: function setModel(what, value) {
    var result;

    if (what == "yMaxMethod") {
      result = value;
    }
    if (what == "xLogStops") {
      result = [];
      this.xLogStops.each(function () {
        if (d3.select(this).property('checked')) result.push(+d3.select(this).node().value);
      });
    }
    if (what == "probeX" || what == "showProbeX") {
      result = value;
    }

    this.model.ui.chart[what] = result;
  }
});

exports.default = Axes;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _dialog = __webpack_require__(11);

var _dialog2 = _interopRequireDefault(_dialog);

var _colorlegend = __webpack_require__(84);

var _colorlegend2 = _interopRequireDefault(_colorlegend);

var _indicatorpicker = __webpack_require__(47);

var _indicatorpicker2 = _interopRequireDefault(_indicatorpicker);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*!
 * VIZABI COLOR DIALOG
 */

var Colors = _dialog2.default.extend({

  /**
   * Initializes the dialog component
   * @param config component configuration
   * @param context component context (parent)
   */
  init: function init(config, parent) {
    this.name = 'colors';

    this.components = [{
      component: _indicatorpicker2.default,
      placeholder: '.vzb-caxis-selector',
      model: ["state.time", "state.entities", "state.marker", "locale"],
      markerID: "color",
      showHoverValues: true
    }, {
      component: _colorlegend2.default,
      placeholder: '.vzb-clegend-container',
      model: ["state.time", "state.entities", "state.marker", "locale"]
    }];

    this._super(config, parent);
  }

});

exports.default = Colors;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _dialog = __webpack_require__(11);

var _dialog2 = _interopRequireDefault(_dialog);

var _simpleslider = __webpack_require__(65);

var _simpleslider2 = _interopRequireDefault(_simpleslider);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*!
 * VIZABI FIND CONTROL
 * Reusable find dialog
 */

var Find = _dialog2.default.extend({

  init: function init(config, parent) {
    this.name = 'find';
    var _this = this;

    this.components = [{
      component: _simpleslider2.default,
      placeholder: '.vzb-dialog-bubbleopacity',
      model: ["state.marker"],
      arg: "opacitySelectDim",
      properties: { step: 0.01 }
    }];

    this.model_binds = {
      "change:state.marker.select": function changeStateMarkerSelect(evt) {
        _this.selectDataPoints();
        _this.showHideDeselect();
      },
      "change:state.time.playing": function changeStateTimePlaying(evt) {
        if (!_this.model.state.time.playing) {
          _this.time = _this.model.state.time.value;

          _this.model.state.marker.getFrame(_this.time, function (values, time) {
            if (!values || _this.time - time) return;
            _this.redrawDataPoints(values);
          });
        }
      },
      "change:state.time.value": function changeStateTimeValue(evt) {
        // hide changes if the dialog is not visible
        if (!_this.placeholderEl.classed('vzb-active') && !_this.placeholderEl.classed('vzb-sidebar')) return;

        _this.time = _this.model.state.time.value;

        _this.model.state.marker.getFrame(_this.time, function (values) {
          if (!values) return;
          _this.redrawDataPoints(values);
        });
      },
      "translate:locale": function translateLocale() {
        _this.input_search.attr("placeholder", _this.translator("placeholder/search") + "...");
      }
    };

    this._super(config, parent);
  },

  /**
   * Grab the list div
   */
  readyOnce: function readyOnce() {
    this._super();

    this.list = this.element.select(".vzb-find-list");
    this.input_search = this.element.select(".vzb-find-search");
    this.deselect_all = this.element.select(".vzb-find-deselect");
    this.opacity_nonselected = this.element.select(".vzb-dialog-bubbleopacity");

    this.KEY = this.model.state.entities.getDimension();

    var _this = this;

    this.input_search.on("keyup", function () {
      var event = d3.event;
      if (event.keyCode == 13 && _this.input_search.node().value == "select all") {
        _this.input_search.node().value = "";
        //clear highlight so it doesn't get in the way when selecting an entity
        if (!utils.isTouchDevice()) _this.model.state.marker.clearHighlighted();
        _this.model.state.marker.selectAll();
      }
    });

    this.input_search.on("input", function () {
      _this.showHideSearch();
    });

    this.deselect_all.on("click", function () {
      _this.deselectMarkers();
    });

    this.translator = this.model.locale.getTFunction();
    this.input_search.attr("placeholder", this.translator("placeholder/search") + "...");

    //make sure it refreshes when all is reloaded
    this.root.on('ready', function () {
      _this.ready();
    });
  },

  open: function open() {
    var _this = this;
    this._super();

    this.input_search.node().value = "";
    this.showHideSearch();

    this.time = this.model.state.time.value;

    this.model.state.marker.getFrame(this.time, function (values) {
      if (!values) return;
      _this.redrawDataPoints(values);
    });
  },

  /**
   * Build the list everytime it updates
   */
  //TODO: split update in render and update methods
  ready: function ready() {
    this._super();

    var _this = this;
    var KEY = this.KEY;

    this.time = this.model.state.time.value;
    this.model.state.marker.getFrame(this.time, function (values) {
      if (!values) return;

      var data = _this.model.state.marker.getKeys().map(function (d) {
        var pointer = {};
        pointer[KEY] = d[KEY];
        pointer.brokenData = false;
        pointer.name = values.label[d[KEY]];

        return pointer;
      });

      //sort data alphabetically
      data.sort(function (a, b) {
        return a.name < b.name ? -1 : 1;
      });

      _this.list.html("");

      _this.items = _this.list.selectAll(".vzb-find-item").data(data).enter().append("div").attr("class", "vzb-find-item vzb-dialog-checkbox");

      _this.items.append("input").attr("type", "checkbox").attr("class", "vzb-find-item").attr("id", function (d) {
        return "-find-" + d[KEY] + "-" + _this._id;
      }).on("change", function (d) {
        //clear highlight so it doesn't get in the way when selecting an entity
        if (!utils.isTouchDevice()) _this.model.state.marker.clearHighlighted();
        _this.model.state.marker.selectMarker(d);
        //return to highlighted state
        if (!utils.isTouchDevice() && !d.brokenData) _this.model.state.marker.highlightMarker(d);
      });

      _this.items.append("label").attr("for", function (d) {
        return "-find-" + d[KEY] + "-" + _this._id;
      }).text(function (d) {
        return d.name;
      }).on("mouseover", function (d) {
        if (!utils.isTouchDevice() && !d.brokenData) _this.model.state.marker.highlightMarker(d);
      }).on("mouseout", function (d) {
        if (!utils.isTouchDevice()) _this.model.state.marker.clearHighlighted();
      });
      utils.preventAncestorScrolling(_this.element.select('.vzb-dialog-scrollable'));

      _this.redrawDataPoints(values);
      _this.selectDataPoints();
      _this.showHideSearch();
      _this.showHideDeselect();
    });
  },

  redrawDataPoints: function redrawDataPoints(values) {
    var _this = this;
    var KEY = this.KEY;

    _this.items.each(function (d) {
      var view = d3.select(this).select("label");

      d.brokenData = false;
      utils.forEach(values, function (hook, name) {
        //TODO: remove the hack with hardcoded hook names (see discussion in #1389)
        if (name !== "color" && name !== "size_label" && _this.model.state.marker[name].use !== "constant" && !hook[d[KEY]] && hook[d[KEY]] !== 0) {
          d.brokenData = true;
        }
      });

      view.classed("vzb-find-item-brokendata", d.brokenData).attr("title", d.brokenData ? _this.model.state.time.formatDate(_this.time) + ": " + _this.translator("hints/nodata") : "");
    });
  },

  selectDataPoints: function selectDataPoints() {
    var KEY = this.KEY;
    var selected = this.model.state.marker.getSelected(KEY);
    this.items.selectAll("input").property("checked", function (d) {
      return selected.indexOf(d[KEY]) !== -1;
    });
  },

  showHideSearch: function showHideSearch() {
    var search = this.input_search.node().value || "";
    search = search.toLowerCase();

    this.list.selectAll(".vzb-find-item").classed("vzb-hidden", function (d) {
      var lower = (d.name || "").toLowerCase();
      return lower.indexOf(search) === -1;
    });
  },

  showHideDeselect: function showHideDeselect() {
    var someSelected = !!this.model.state.marker.select.length;
    this.deselect_all.classed('vzb-hidden', !someSelected);
    this.opacity_nonselected.classed('vzb-hidden', !someSelected);
  },

  deselectMarkers: function deselectMarkers() {
    this.model.state.marker.clearSelected();
  },

  transitionEnd: function transitionEnd(event) {
    this._super(event);

    if (!utils.isTouchDevice()) this.input_search.node().focus();
  }

});

exports.default = Find;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _dialog = __webpack_require__(11);

var _dialog2 = _interopRequireDefault(_dialog);

var _sizeslider = __webpack_require__(133);

var _sizeslider2 = _interopRequireDefault(_sizeslider);

var _indicatorpicker = __webpack_require__(47);

var _indicatorpicker2 = _interopRequireDefault(_indicatorpicker);

var _simplecheckbox = __webpack_require__(58);

var _simplecheckbox2 = _interopRequireDefault(_simplecheckbox);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*
 * Label dialog
 */

var Label = _dialog2.default.extend({

  /**
   * Initializes the dialog component
   * @param config component configuration
   * @param context component context (parent)
   */
  init: function init(config, parent) {
    this.name = 'label';

    // in dialog, this.model_expects = ["state", "data"];

    this.components = [{
      component: _sizeslider2.default,
      placeholder: '.vzb-dialog-sizeslider',
      model: ["state.marker.size_label", "locale"],
      propertyname: 'LabelTextSize',
      ui: {
        constantUnit: "unit/pixels"
      }
    }, {
      component: _indicatorpicker2.default,
      placeholder: '.vzb-saxis-selector',
      model: ["state.time", "state.entities", "state.marker", "locale"],
      markerID: "size_label",
      showHoverValues: true
    }, {
      component: _simplecheckbox2.default,
      placeholder: '.vzb-removelabelbox-switch',
      model: ["ui.chart", "locale"],
      checkbox: 'removeLabelBox',
      submodel: 'labels'
    }];

    this._super(config, parent);
  }
});

exports.default = Label;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _dialog = __webpack_require__(11);

var _dialog2 = _interopRequireDefault(_dialog);

var _simpleslider = __webpack_require__(65);

var _simpleslider2 = _interopRequireDefault(_simpleslider);

var _bubblesize = __webpack_require__(83);

var _bubblesize2 = _interopRequireDefault(_bubblesize);

var _colorlegend = __webpack_require__(84);

var _colorlegend2 = _interopRequireDefault(_colorlegend);

var _indicatorpicker = __webpack_require__(47);

var _indicatorpicker2 = _interopRequireDefault(_indicatorpicker);

var _simplecheckbox = __webpack_require__(58);

var _simplecheckbox2 = _interopRequireDefault(_simplecheckbox);

var _optionsbuttonlist = __webpack_require__(115);

var _optionsbuttonlist2 = _interopRequireDefault(_optionsbuttonlist);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*
 * More options dialog
 */

var MoreOptions = _dialog2.default.extend({

  /**
   * Initializes the dialog component
   * @param config component configuration
   * @param context component context (parent)
   */
  init: function init(config, parent) {
    this.name = 'moreoptions';

    //specifying components
    this.components = [{
      component: _optionsbuttonlist2.default,
      placeholder: '.vzb-dialog-options-buttonlist',
      model: ['state', 'ui', 'locale']
    }];

    this._super(config, parent);
  },

  readyOnce: function readyOnce() {
    this._super();

    var _this = this;
    this.accordionEl = this.contentEl.select('.vzb-accordion');

    this.on('dragend', function () {
      _this._setMaxHeight();
    });

    var dialog_popup = (this.model.ui.dialogs || {}).popup || [];
    var dialog_moreoptions = (this.model.ui.dialogs || {}).moreoptions || [];

    // if dialog_moreoptions has been passed in with boolean param or array must check and covert to array
    if (dialog_moreoptions === true) {
      dialog_moreoptions = dialog_popup;
      (this.model.ui.dialogs || {}).moreoptions = dialog_moreoptions;
    }

    this._addDialogs(dialog_moreoptions);

    //accordion
    if (this.accordionEl) {
      var titleEl = this.accordionEl.selectAll('.vzb-accordion-section').select('.vzb-dialog-title>span:first-child');
      titleEl.on('click', function (d) {
        var element = _this.components[d.component].element;
        var sectionEl = _this.components[d.component].placeholderEl;
        var activeEl = _this.accordionEl.select('.vzb-accordion-active');
        if (activeEl) {
          activeEl.classed('vzb-accordion-active', false);
        }
        if (sectionEl.node() !== activeEl.node()) {
          sectionEl.classed('vzb-accordion-active', true);
        }
      });
    }
  },

  _addDialogs: function _addDialogs(dialog_list) {
    this._components_config = [];
    var details_dlgs = [];
    if (!dialog_list.length) return;
    //add a component for each dialog
    for (var i = 0; i < dialog_list.length; i++) {

      //check moreoptions in dialog.moreoptions
      if (dialog_list[i] === "moreoptions") continue;

      var dlg = dialog_list[i];
      var dlg_config = utils.deepClone(this.parent._available_dialogs[dlg]);

      //if it's a dialog, add component
      if (dlg_config && dlg_config.dialog) {
        var comps = this._components_config;

        //add corresponding component
        comps.push({
          component: dlg_config.dialog,
          placeholder: '.vzb-dialogs-dialog[data-dlg="' + dlg + '"]',
          model: ["state", "ui", "locale"]
        });

        dlg_config.component = comps.length - 1;

        dlg_config.id = dlg;
        details_dlgs.push(dlg_config);
      }
    };

    this.accordionEl.selectAll('div').data(details_dlgs).enter().append("div").attr('class', function (d) {
      var cls = 'vzb-dialogs-dialog vzb-moreoptions vzb-accordion-section';
      return cls;
    }).attr('data-dlg', function (d) {
      return d.id;
    });

    this.loadSubComponents();

    var _this = this;
    //render each subcomponent
    utils.forEach(this.components, function (subcomp) {
      subcomp.render();
      _this.on('resize', function () {
        subcomp.trigger('resize');
      });
    });
  }
});

exports.default = MoreOptions;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _dialog = __webpack_require__(11);

var _dialog2 = _interopRequireDefault(_dialog);

var _simpleslider = __webpack_require__(65);

var _simpleslider2 = _interopRequireDefault(_simpleslider);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*
 * Size dialog
 */

var Opacity = _dialog2.default.extend({

  /**
   * Initializes the dialog component
   * @param config component configuration
   * @param context component context (parent)
   */
  init: function init(config, parent) {
    this.name = 'opacity';

    // in dialog, this.model_expects = ["state", "data"];

    this.components = [{
      component: _simpleslider2.default,
      placeholder: '.vzb-dialog-bubbleopacity-regular',
      model: ["state.marker"],
      arg: "opacityRegular",
      properties: { step: 0.01 }
    }, {
      component: _simpleslider2.default,
      placeholder: '.vzb-dialog-bubbleopacity-selectdim',
      model: ["state.marker"],
      arg: "opacitySelectDim",
      properties: { step: 0.01 }
    }];

    this._super(config, parent);
  }
});

exports.default = Opacity;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _dialog = __webpack_require__(11);

var _dialog2 = _interopRequireDefault(_dialog);

var _simplecheckbox = __webpack_require__(58);

var _simplecheckbox2 = _interopRequireDefault(_simplecheckbox);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*
 * Size dialog
 */

var Presentation = _dialog2.default.extend({

  /**
   * Initializes the dialog component
   * @param config component configuration
   * @param context component context (parent)
   */
  init: function init(config, parent) {
    this.name = 'presentation';

    // in dialog, this.model_expects = ["state", "data"];

    this.components = [{
      component: _simplecheckbox2.default,
      placeholder: '.vzb-presentationmode-switch',
      model: ["ui", "locale"],
      checkbox: 'presentation'
    }];

    this._super(config, parent);
  }
});

exports.default = Presentation;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _dialog = __webpack_require__(11);

var _dialog2 = _interopRequireDefault(_dialog);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*!
 * VIZABI SHOW CONTROL
 * Reusable show dialog
 */

var Show = _dialog2.default.extend({

  init: function init(config, parent) {
    this.name = 'show';
    var _this = this;

    this.model_binds = {
      "change:state.entities.show": function changeStateEntitiesShow(evt) {
        _this.redraw();
      }
    };

    this._super(config, parent);
  },

  /**
   * Grab the list div
   */
  readyOnce: function readyOnce() {
    this._super();
    this.list = this.element.select(".vzb-show-list");
    this.input_search = this.element.select(".vzb-show-search");
    this.deselect_all = this.element.select(".vzb-show-deselect");

    this.KEY = this.model.state.entities.getDimension();
    this.TIMEDIM = this.model.state.time.getDimension();

    var _this = this;
    this.input_search.on("input", function () {
      _this.showHideSearch();
    });

    this.deselect_all.on("click", function () {
      _this.deselectEntities();
    });

    //make sure it refreshes when all is reloaded
    this.root.on('ready', function () {
      _this.redraw();
    });
  },

  open: function open() {
    this._super();

    this.input_search.node().value = "";
    this.showHideSearch();
  },

  ready: function ready() {
    this._super();
    this.redraw();
    utils.preventAncestorScrolling(this.element.select('.vzb-dialog-scrollable'));
  },

  redraw: function redraw() {

    var _this = this;
    this.translator = this.model.locale.getTFunction();

    this.model.state.marker_allpossible.getFrame(this.model.state.time.value, function (values) {
      if (!values) return;
      var data = utils.keys(values.label).map(function (d) {
        var result = {};
        result[_this.KEY] = d;
        result["label"] = values.label[d];
        return result;
      });

      //sort data alphabetically
      data.sort(function (a, b) {
        return a.label < b.label ? -1 : 1;
      });

      _this.list.html("");

      var items = _this.list.selectAll(".vzb-show-item").data(data).enter().append("div").attr("class", "vzb-show-item vzb-dialog-checkbox");

      items.append("input").attr("type", "checkbox").attr("class", "vzb-show-item").attr("id", function (d) {
        return "-show-" + d[_this.KEY] + "-" + _this._id;
      }).property("checked", function (d) {
        return _this.model.state.entities.isShown(d);
      }).on("change", function (d) {

        _this.model.state.marker.clearSelected();
        _this.model.state.entities.showEntity(d);
        _this.showHideDeselect();
      });

      items.append("label").attr("for", function (d) {
        return "-show-" + d[_this.KEY] + "-" + _this._id;
      }).text(function (d) {
        return d.label;
      });

      _this.input_search.attr("placeholder", _this.translator("placeholder/search") + "...");

      _this.showHideSearch();
      _this.showHideDeselect();
    });
  },

  showHideSearch: function showHideSearch() {

    var search = this.input_search.node().value || "";
    search = search.toLowerCase();

    this.list.selectAll(".vzb-show-item").classed("vzb-hidden", function (d) {
      var lower = d.label.toLowerCase();
      return lower.indexOf(search) === -1;
    });
  },

  showHideDeselect: function showHideDeselect() {
    var show = this.model.state.entities.show[this.KEY];
    this.deselect_all.classed('vzb-hidden', !show || show.length == 0);
  },

  deselectEntities: function deselectEntities() {
    this.model.state.entities.clearShow();
    this.showHideDeselect();
  },

  transitionEnd: function transitionEnd(event) {
    this._super(event);

    if (!utils.isTouchDevice()) this.input_search.node().focus();
  }

});

exports.default = Show;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _dialog = __webpack_require__(11);

var _dialog2 = _interopRequireDefault(_dialog);

var _indicatorpicker = __webpack_require__(47);

var _indicatorpicker2 = _interopRequireDefault(_indicatorpicker);

var _simplecheckbox = __webpack_require__(58);

var _simplecheckbox2 = _interopRequireDefault(_simplecheckbox);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*!
 * VIZABI SIDE CONTROL
 * Reusable side dialog
 */

var Side = _dialog2.default.extend({

  init: function init(config, parent) {
    this.name = 'side';
    var _this = this;

    this.model_binds = {
      "change:state.entities_side.show": function changeStateEntities_sideShow(evt) {
        _this.redraw();
      }
    };

    this.components = [{
      component: _indicatorpicker2.default,
      placeholder: '.vzb-side-selector',
      model: ["state.time", "state.entities_side", "state.marker", "locale"],
      markerID: "hook_side",
      showHoverValues: false
    }, {
      component: _simplecheckbox2.default,
      placeholder: '.vzb-flipsides-switch',
      model: ["ui.chart", "locale"],
      checkbox: 'flipSides'
    }];

    this._super(config, parent);
  },

  /**
   * Grab the list div
   */
  readyOnce: function readyOnce() {
    this._super();
    this.list = this.element.select(".vzb-side-list");
    this.input_search = this.element.select(".vzb-side-search");
    this.deselect_all = this.element.select(".vzb-side-deselect");

    this.KEY = this.model.state.entities_side.getDimension();
    this.TIMEDIM = this.model.state.time.getDimension();

    var _this = this;
    this.input_search.on("input", function () {
      _this.showHideSearch();
    });

    this.deselect_all.on("click", function () {
      _this.deselectEntities();
    });

    //make sure it refreshes when all is reloaded
    this.root.on('ready', function () {
      _this.redraw();
    });
  },

  open: function open() {
    this._super();

    this.input_search.node().value = "";
    this.showHideSearch();
  },

  ready: function ready() {
    this._super();
    this.redraw();
    utils.preventAncestorScrolling(this.element.select('.vzb-dialog-scrollable'));
  },

  redraw: function redraw() {

    var _this = this;
    this.translator = this.model.locale.getTFunction();

    this.model.state.marker_allpossibleside.getFrame(this.model.state.time.value, function (values) {
      if (!values) return;
      var data = utils.keys(values.label).map(function (d) {
        var result = {};
        result[_this.KEY] = d;
        result["label"] = values.label[d];
        return result;
      });

      //sort data alphabetically
      data.sort(function (a, b) {
        return a.label < b.label ? -1 : 1;
      });

      _this.list.html("");

      var items = _this.list.selectAll(".vzb-side-item").data(data).enter().append("div").attr("class", "vzb-side-item vzb-dialog-checkbox");

      items.append("input").attr("type", "checkbox").attr("class", "vzb-side-item").attr("id", function (d) {
        return "-side-" + d[_this.KEY] + "-" + _this._id;
      }).property("checked", function (d) {
        return _this.model.state.entities_side.isShown(d);
      }).on("change", function (d) {

        _this.model.state.marker.clearSelected();
        _this.model.state.entities_side.showEntity(d);
        _this.showHideDeselect();
      });

      items.append("label").attr("for", function (d) {
        return "-side-" + d[_this.KEY] + "-" + _this._id;
      }).text(function (d) {
        return d.label;
      });

      _this.input_search.attr("placeholder", _this.translator("placeholder/search") + "...");

      _this.showHideSearch();
      _this.showHideDeselect();
    });
  },

  showHideSearch: function showHideSearch() {

    var search = this.input_search.node().value || "";
    search = search.toLowerCase();

    this.list.selectAll(".vzb-side-item").classed("vzb-hidden", function (d) {
      var lower = d.label.toLowerCase();
      return lower.indexOf(search) === -1;
    });
  },

  showHideDeselect: function showHideDeselect() {
    var show = this.model.state.entities_side.show[this.KEY];
    this.deselect_all.classed('vzb-hidden', !show || show.length == 0);
  },

  deselectEntities: function deselectEntities() {
    this.model.state.entities_side.clearShow();
    this.showHideDeselect();
  },

  transitionEnd: function transitionEnd(event) {
    this._super(event);

    if (!utils.isTouchDevice()) this.input_search.node().focus();
  }

});

exports.default = Side;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _dialog = __webpack_require__(11);

var _dialog2 = _interopRequireDefault(_dialog);

var _bubblesize = __webpack_require__(83);

var _bubblesize2 = _interopRequireDefault(_bubblesize);

var _indicatorpicker = __webpack_require__(47);

var _indicatorpicker2 = _interopRequireDefault(_indicatorpicker);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*
 * Size dialog
 */

var Size = _dialog2.default.extend({

  /**
   * Initializes the dialog component
   * @param config component configuration
   * @param context component context (parent)
   */
  init: function init(config, parent) {
    this.name = 'size';

    // in dialog, this.model_expects = ["state", "ui", "locale"];

    this.components = [{
      component: _indicatorpicker2.default,
      placeholder: '.vzb-saxis-selector',
      model: ["state.time", "state.entities", "state.marker", "locale"],
      markerID: "size",
      showHoverValues: true
    }];

    // config.ui is same as this.model.ui here but this.model.ui is not yet available because constructor hasn't been called. 
    // can't call constructor earlier because this.components needs to be complete before calling constructor
    if (!config.ui.chart || config.ui.chart.sizeSelectorActive !== 0) {
      this.components.push({
        component: _bubblesize2.default,
        placeholder: '.vzb-dialog-bubblesize',
        model: ["state.marker.size"],
        ui: {
          show_button: false
        }
      });
    }

    this._super(config, parent);
  }
});

exports.default = Size;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _dialog = __webpack_require__(11);

var _dialog2 = _interopRequireDefault(_dialog);

var _simpleslider = __webpack_require__(65);

var _simpleslider2 = _interopRequireDefault(_simpleslider);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*
 * Size dialog
 */

var Speed = _dialog2.default.extend({

  /**
   * Initializes the dialog component
   * @param config component configuration
   * @param context component context (parent)
   */
  init: function init(config, parent) {
    this.name = 'speed';

    // in dialog, this.model_expects = ["state", "data"];

    this.components = [{
      component: _simpleslider2.default,
      placeholder: '.vzb-dialog-placeholder',
      model: ["state.time"],
      arg: "delay",
      properties: { min: 1, max: 6, step: 0.1, scale: d3.scale.linear().domain([1, 2, 3, 4, 5, 6]).range([1200, 900, 450, 200, 150, 100])
      }
    }];

    this._super(config, parent);
  }
});

exports.default = Speed;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
    value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _dialog = __webpack_require__(11);

var _dialog2 = _interopRequireDefault(_dialog);

var _draggablelist = __webpack_require__(132);

var _draggablelist2 = _interopRequireDefault(_draggablelist);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*
 * stack dialog
 */

var Stack = _dialog2.default.extend({

    /**
     * Initializes the dialog component
     * @param config component configuration
     * @param context component context (parent)
     */
    init: function init(config, parent) {
        this.name = 'stack';
        var _this = this;

        // in dialog, this.model_expects = ["state", "ui", "locale"];

        this.components = [{
            component: _draggablelist2.default,
            placeholder: '.vzb-dialog-draggablelist',
            model: ["state.marker.group", "state.marker.color", "locale", "ui.chart"],
            groupID: "manualSorting",
            isEnabled: "manualSortingEnabled",
            dataArrFn: _this.manualSorting.bind(_this),
            lang: ''
        }];

        this.model_binds = {
            'change:state.marker.group': function changeStateMarkerGroup(evt) {
                //console.log("group change " + evt);
                if (!_this._ready) return;
                _this.updateView();
            }
        };

        this._super(config, parent);
    },

    readyOnce: function readyOnce() {
        this._super();

        var _this = this;
        this.group = this.model.state.marker.group;
        this.stack = this.model.state.marker.stack;

        this.howToStackEl = this.element.select('.vzb-howtostack').selectAll("input").on("change", function () {
            _this.setModel("stack", d3.select(this).node().value);
        });
        this.howToMergeEl = this.element.select('.vzb-howtomerge').selectAll("input").on("change", function () {
            _this.setModel("merge", d3.select(this).node().value);
        });

        this.updateView();
    },

    ready: function ready() {
        this._super();
        if (!this.model.state.marker.color.isDiscrete()) {
            if (this.stack.use == "property") {
                this.setModel("stack", "none");
                return;
            } else if (this.group.merge) {
                this.setModel("merge", "none");
                return;
            }
        }
        this.updateView();
    },

    updateView: function updateView() {
        var _this = this;

        this.howToStackEl.property('checked', function () {
            if (d3.select(this).node().value === "none") return _this.stack.which === "none";
            if (d3.select(this).node().value === "bycolor") return _this.stack.which === _this.model.state.marker.color.which;
            if (d3.select(this).node().value === "all") return _this.stack.which === "all";
        }).attr('disabled', function () {
            if (d3.select(this).node().value === "none") return null; // always enabled
            if (d3.select(this).node().value === "all") return null; // always enabled
            if (d3.select(this).node().value === "bycolor") return _this.model.state.marker.color.use !== "property" ? true : null;
        });

        _this.model.ui.chart.manualSortingEnabled = _this.stack.which == "all";

        this.howToMergeEl.property('checked', function () {
            if (d3.select(this).node().value === "none") return !_this.group.merge && !_this.stack.merge;
            if (d3.select(this).node().value === "grouped") return _this.group.merge;
            if (d3.select(this).node().value === "stacked") return _this.stack.merge;
        }).attr('disabled', function () {
            if (d3.select(this).node().value === "none") return null; // always enabled
            if (d3.select(this).node().value === "grouped") return _this.stack.which === "none" || _this.model.state.marker.color.use !== "property" ? true : null;
            if (d3.select(this).node().value === "stacked") return _this.stack.which === "all" ? null : true;
        });
    },

    manualSorting: function manualSorting(value) {
        if (arguments.length === 0) return this.model.state.marker.group.manualSorting;
        this.model.state.marker.group.manualSorting = value;
    },

    setModel: function setModel(what, value) {

        var obj = { stack: {}, group: {} };

        if (what === "merge") {
            switch (value) {
                case "none":
                    obj.group.merge = false;
                    obj.stack.merge = false;
                    break;
                case "grouped":
                    obj.group.merge = true;
                    obj.stack.merge = false;
                    break;
                case "stacked":
                    obj.group.merge = false;
                    obj.stack.merge = true;
                    break;
            }
        }
        if (what === "stack") {

            switch (value) {
                case "all":
                    obj.stack.use = "constant";
                    obj.stack.which = "all";
                    break;
                case "none":
                    obj.stack.use = "constant";
                    obj.stack.which = "none";
                    break;
                case "bycolor":
                    obj.stack.use = "property";
                    obj.stack.which = this.model.state.marker.color.which;
                    break;
            }

            //validate possible merge values in group and stack hooks
            if (value === "none" && this.group.merge) obj.group.merge = false;
            if (value !== "all" && this.stack.merge) obj.stack.merge = false;
        }

        this.model.state.marker.set(obj);
    }
});

exports.default = Stack;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _dialog = __webpack_require__(11);

var _dialog2 = _interopRequireDefault(_dialog);

var _d = __webpack_require__(66);

var _d2 = _interopRequireDefault(_d);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/*
 * Timedisplay dialog
 */
var TimeDisplay = _dialog2.default.extend({
  init: function init(config, parent) {
    var _this = this;

    this.name = 'timedisplay';

    this.model_binds = {
      'change:state.time.value': function changeStateTimeValue() {
        _this.updateTime();
      }
    };

    this._super(config, parent);
  },
  ready: function ready() {
    this.updateTime();
  },
  readyOnce: function readyOnce() {
    this._super();
    this.timeLabel = new _d2.default(this.element.select('.vzb-timedisplay'));
    this.timeLabel.setConditions({ widthRatio: 1, heightRatio: 1 });
    this.timeLabel.resize(this.contentEl.style('width'), this.contentEl.style('height'));
  },
  updateTime: function updateTime() {
    var timeMdl = this.model.state.time;
    this.time_1 = this.time == null ? timeMdl.value : this.time;
    this.time = timeMdl.value;
    var duration = timeMdl.playing && this.time - this.time_1 > 0 ? timeMdl.delayAnimations : 0;
    this.timeLabel.setText(timeMdl.formatDate(this.time, 'ui'), duration);
  }
});

exports.default = TimeDisplay;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _dialog = __webpack_require__(11);

var _dialog2 = _interopRequireDefault(_dialog);

var _zoombuttonlist = __webpack_require__(134);

var _zoombuttonlist2 = _interopRequireDefault(_zoombuttonlist);

var _simplecheckbox = __webpack_require__(58);

var _simplecheckbox2 = _interopRequireDefault(_simplecheckbox);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*
 * Zoom dialog
 */

var Zoom = _dialog2.default.extend({

  /**
   * Initializes the dialog component
   * @param config component configuration
   * @param context component context (parent)
   */
  init: function init(config, parent) {
    this.name = 'zoom';

    // in dialog, this.model_expects = ["state", "data"];

    this.components = [{
      component: _zoombuttonlist2.default,
      placeholder: '.vzb-dialog-zoom-buttonlist',
      model: ["state", "ui", "locale"]
    }, {
      component: _simplecheckbox2.default,
      placeholder: '.vzb-zoomonscrolling-switch',
      model: ["ui", "locale"],
      checkbox: 'zoomOnScrolling'
    }, {
      component: _simplecheckbox2.default,
      placeholder: '.vzb-adaptminmaxzoom-switch',
      model: ["ui", "locale"],
      checkbox: 'adaptMinMaxZoom'
    }];

    this._super(config, parent);
  }
});

exports.default = Zoom;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

var DraggableList = _component2.default.extend({

  init: function init(config, context) {
    this.template = '<span class="vzb-dl-holder"><ul class="vzb-draggable list vzb-dialog-scrollable"></ul></span>';
    var _this = this;
    this.name = 'draggableList';

    this.dataArrFn = config.dataArrFn;
    this.lang = config.lang;

    this.model_expects = [{
      name: "group",
      type: "model"
    }, {
      name: "color",
      type: "color"
    }, {
      name: "locale",
      type: "locale"
    }, {
      name: "chart",
      type: "model"
    }];

    this.groupID = config.groupID;
    this.isEnabled = config.isEnabled;
    this.draggable = true;

    if (!config.groupID) utils.warn("draggablelist.js complains on 'groupID' property: " + config.groupID);

    this.model_binds = {
      "translate:locale": function translateLocale(evt) {
        _this.updateView();
      },
      "change:group.which": function changeGroupWhich(evt) {
        _this.updateView();
      }
    };

    this.model_binds["change:group." + this.groupID] = function (evt) {
      _this.updateView();
    };
    this.model_binds["change:chart." + this.isEnabled] = function (evt) {
      _this.draggable = _this.model.chart[_this.isEnabled];
      _this.updateView();
    };

    this._super(config, context);

    this.updateData = utils.debounce(this.updateData, 1000);

    this.itemDragger = d3.behavior.drag().on('dragstart', function (draggedData, i) {
      if (_this.dataUpdateFlag || !_this.draggable) return;
      d3.event.sourceEvent.stopPropagation();
      _this.parentBoundRect = _this.element.node().getBoundingClientRect();
      _this.element.selectAll('div').each(function (d, i) {
        var boundRect = this.getBoundingClientRect();
        d._y = boundRect.top;
        d._top = 0;
        if (draggedData.data === d.data) {
          d._height = boundRect.height;
          _this.selectedNode = this;
        }
      });
      d3.select(_this.selectedNode).classed('dragged', true);
    }).on('drag', function (draggedData, draggedIndex) {
      if (_this.dataUpdateFlag || !_this.draggable) return;
      draggedData._top += d3.event.dy;
      var newDraggedY = draggedData._y + draggedData._top;
      if (newDraggedY > _this.parentBoundRect.top && newDraggedY + draggedData._height < _this.parentBoundRect.top + _this.parentBoundRect.height) {
        _this.itemsEl.style('top', function (d, i) {
          var top = 0;

          if (i < draggedIndex && d._y + draggedData._height * .5 > newDraggedY) {
            top = draggedData._height;
          } else if (i > draggedIndex && d._y - draggedData._height * .5 < newDraggedY) {
            top = -draggedData._height;
          }

          if (i != draggedIndex) d._top = top;
          return d._top + "px";
        });
      }
    }).on('dragend', function (d, i) {
      if (_this.dataUpdateFlag || !_this.draggable) return;
      _this.getData();
    });
  },

  ready: function ready() {
    var _this = this;

    var labels = _this.model.color.getColorlegendMarker().label.getItems();
    this.dataArrFn(utils.keys(labels));

    this.updateView();

    this.itemsEl = this.element.selectAll('div');

    this.itemsEl.call(_this.itemDragger);

    var test = this.itemsEl.select('li').on('mouseover', function () {
      d3.select(this).classed('hover', true);
    }).on('mouseout', function () {
      d3.select(this).classed('hover', false);
    }).on('touchstart', function () {
      d3.event.preventDefault();
    });
  },

  updateView: function updateView() {
    var _this = this;

    this.items = this.element.selectAll('div').data(function () {
      return _this.dataArrFn().map(function (d) {
        return { data: d };
      });
    });
    var draggable = _this.draggable ? true : null;
    this.items.enter().append('div').append('li');

    var labels = _this.model.color.getColorlegendMarker().label.getItems();
    this.items.select('li').classed('hover', false).each(function (val, index) {
      d3.select(this).attr('data', val['data']).text(labels[val['data']]);
    });
    this.items.exit().remove();
    this.element.selectAll('div').style('top', '').attr('draggable', draggable).classed('dragged', false);
    this.dataUpdateFlag = false;
  },

  getData: function getData() {
    var dataArr = [];
    var data = this.element.selectAll('div').data();

    dataArr = data.sort(function (a, b) {
      return a._y + a._top - (b._y + b._top);
    }).map(function (d) {
      return d.data;
    });
    if (utils.arrayEquals(this.dataArrFn(), dataArr)) {
      this.updateView();
    } else {
      this.dataUpdateFlag = true;
      this.updateData(dataArr);
    }
  },

  updateData: function updateData(dataArr) {
    this.dataArrFn(dataArr);
  },

  readyOnce: function readyOnce() {
    var _this = this;

    this.element = d3.select(this.element).select('.list');
  }

});

exports.default = DraggableList;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*!
 * VIZABI BUBBLE SIZE slider
 * Reusable bubble size slider
 */

var OPTIONS = {
  EXTENT_MIN: 0,
  EXTENT_MAX: 1,
  TEXT_PARAMS: { TOP: 18, LEFT: 10, MAX_WIDTH: 42, MAX_HEIGHT: 16 },
  BAR_WIDTH: 6,
  THUMB_RADIUS: 10,
  THUMB_STROKE_WIDTH: 4,
  INTRO_DURATION: 250,
  MARGIN: { TOP: 2, LEFT: 5, RIGHT: 5 }
};

var profiles = {
  "small": {
    minLabelTextSize: 7,
    maxLabelTextSize: 21,
    defaultLabelTextSize: 12
  },
  "medium": {
    minLabelTextSize: 7,
    maxLabelTextSize: 30,
    defaultLabelTextSize: 15
  },
  "large": {
    minLabelTextSize: 6,
    maxLabelTextSize: 48,
    defaultLabelTextSize: 20
  }
};

var SizeSlider = _component2.default.extend({

  /**
   * Initializes the timeslider.
   * Executed once before any template is rendered.
   * @param config The options passed to the component
   * @param context The component's parent
   */
  init: function init(config, context) {

    this.name = 'sizeslider';

    this.template = this.template || __webpack_require__(440);

    this.propertyName = config.propertyname;

    this.model_expects = [{
      name: "size",
      type: "size"
    }, {
      name: "locale",
      type: "locale"
    }];

    var _this = this;
    this.model_binds = {
      'change:size.domainMin': changeMinMaxHandler,
      'change:size.domainMax': changeMinMaxHandler,
      'change:size.extent': changeMinMaxHandler,
      'ready': function ready() {
        _this.modelReady();
      }
    };

    function changeMinMaxHandler(evt, path) {
      var size = _this.model.size.extent || [OPTIONS.EXTENT_MIN, OPTIONS.EXTENT_MAX];
      //_this._updateArcs(size);
      _this._updateLabels(size);
      _this.sliderEl.call(_this.brush.extent(size));
      if (size[0] == size[1]) {
        _this.sliderEl.selectAll(".resize").style("display", "block");
      }
    }

    this._setModel = utils.throttle(this._setModel, 50);
    //contructor is the same as any component
    this._super(config, context);
  },

  modelReady: function modelReady() {
    var _this = this;
    _this.modelUse = _this.model.size.use;
    var size = _this.model.size.extent || [OPTIONS.EXTENT_MIN, OPTIONS.EXTENT_MAX];
    if (_this.modelUse != 'constant') {
      _this.sizeScaleMinMax = _this.model.size.getScale().domain();
      _this.sliderEl.selectAll('.w').classed('vzb-hidden', false);
      _this.sliderEl.select('.extent').classed('vzb-hidden', false);
      _this.sliderEl.select('.background').classed('vzb-pointerevents-none', false);
      _this._setLabelsText();
    } else {
      _this.sliderEl.selectAll('.w').classed('vzb-hidden', true);
      _this.sliderEl.select('.extent').classed('vzb-hidden', true);
      _this.sliderEl.select('.background').classed('vzb-pointerevents-none', true);
      if (!_this.model.size.which) {
        var p = _this.propertyActiveProfile;
        size[1] = (p.default - p.min) / (p.max - p.min);
        _this.model.size.which = '_default';
      }
    }
    _this.sliderEl.call(_this.brush.extent([size[0], size[1]]));
    _this.sliderEl.call(_this.brush.event);
  },

  /**
   * Executes after the template is loaded and rendered.
   * Ideally, it contains HTML instantiations related to template
   * At this point, this.element and this.placeholder are available as a d3 object
   */
  readyOnce: function readyOnce() {
    var _this = this;
    var values = _this.model.size.extent || [OPTIONS.EXTENT_MIN, OPTIONS.EXTENT_MAX];
    this.element = d3.select(this.element);
    this.sliderSvg = this.element.select(".vzb-szs-svg");
    this.sliderWrap = this.sliderSvg.select(".vzb-szs-slider-wrap");
    this.sliderEl = this.sliderWrap.select(".vzb-szs-slider");

    var textMargin = { v: OPTIONS.TEXT_PARAMS.TOP, h: OPTIONS.TEXT_PARAMS.LEFT },
        textMaxWidth = OPTIONS.TEXT_PARAMS.MAX_WIDTH,
        textMaxHeight = OPTIONS.TEXT_PARAMS.MAX_HEIGHT,
        barWidth = OPTIONS.BAR_WIDTH,
        thumbRadius = OPTIONS.THUMB_RADIUS,
        thumbStrokeWidth = OPTIONS.THUMB_STROKE_WIDTH,
        padding = {
      top: OPTIONS.MARGIN.TOP + barWidth * 1.25,
      left: thumbRadius,
      right: thumbRadius,
      bottom: barWidth + textMaxHeight
    };

    var componentWidth = this.element.node().offsetWidth;

    this.padding = padding;

    this.propertyActiveProfile = this.getPropertyActiveProfile();
    this.translator = this.model.locale.getTFunction();

    this.propertyScale = d3.scale.linear().domain([OPTIONS.EXTENT_MIN, OPTIONS.EXTENT_MAX]).range([this.propertyActiveProfile.min, this.propertyActiveProfile.max]).clamp(true);

    this.xScale = d3.scale.linear().domain([OPTIONS.EXTENT_MIN, OPTIONS.EXTENT_MAX]).range([0, componentWidth - padding.left - padding.right]).clamp(true);

    this.brush = d3.svg.brush().x(this.xScale).extent([OPTIONS.EXTENT_MIN, OPTIONS.EXTENT_MAX]).on("brush", function () {
      _this._setFromExtent(true, false, false); // non persistent change
    }).on("brushend", function () {
      _this.sliderEl.selectAll(".resize").style("display", null);

      _this._setFromExtent(true, true); // force a persistent change
    });

    this.sliderEl.call(_this.brush);

    this.sliderEl.selectAll('.background').attr('style', '');

    //For return to round thumbs
    //var thumbArc = d3.svg.arc()
    //  .outerRadius(thumbRadius)
    //  .startAngle(0)
    //  .endAngle(2 * Math.PI)

    this.sliderThumbs = this.sliderEl.selectAll(".resize").sort(d3.descending).classed("vzb-szs-slider-thumb", true);

    this.sliderThumbs.append("g").attr("class", "vzb-szs-slider-thumb-badge").append("path").attr('d', function (d, i) {
      return "M0 " + barWidth * .5 + "l" + -thumbRadius + " " + thumbRadius * 1.5 + "h" + thumbRadius * 2 + "Z";
    });

    this.sliderThumbs.append("path").attr("class", "vzb-szs-slider-thumb-arc");
    this.sliderEl.selectAll("text").data([0, 0]).enter().append("text").attr("class", function (d, i) {
      return "vzb-szs-slider-thumb-label " + (i ? 'e' : 'w');
    }).attr("dy", -barWidth * 1.25 + 'px').attr("text-anchor", function (d, i) {
      return 1 - i ? "start" : "end";
    });

    this.sliderLabelsEl = this.sliderEl.selectAll("text.vzb-szs-slider-thumb-label");

    this.sliderEl.selectAll("rect").attr("height", barWidth).attr("rx", barWidth * 0.25).attr("ry", barWidth * 0.25).attr("transform", "translate(0," + -barWidth * 0.5 + ")");
    this.sliderEl.select(".extent").classed("vzb-szs-slider-extent", true);

    this.on("resize", function () {
      //console.log("EVENT: resize");
      _this.propertyActiveProfile = _this.getPropertyActiveProfile();
      _this.propertyScale.range([_this.propertyActiveProfile.min, _this.propertyActiveProfile.max]);

      var componentWidth = _this.element.node().offsetWidth;

      _this.xScale.range([0, componentWidth - _this.padding.left - _this.padding.right]);
      _this._updateSize();

      _this.sliderEl.call(_this.brush.extent(_this.brush.extent()));
      _this._setFromExtent(false, false, false); // non persistent change
    });

    this._updateSize();

    this.sliderEl.call(this.brush.extent(values));
    _this._setFromExtent(false, false, false); // non persistent change

    _this.sizeScaleMinMax = _this.model.size.getScale().domain();

    if (_this.sizeScaleMinMax) {
      _this._setLabelsText();
    }

    if (_this.model._ready) this.modelReady();
  },

  getPropertyActiveProfile: function getPropertyActiveProfile() {
    var profile = profiles[this.getLayoutProfile()];
    return { min: profile['min' + this.propertyName], max: profile['max' + this.propertyName], default: profile['default' + this.propertyName] };
  },

  /*
   * RESIZE:
   * Executed whenever the container is resized
   */
  _updateSize: function _updateSize() {
    this.sliderSvg.attr("height", this.propertyActiveProfile.max + this.padding.top + this.padding.bottom).attr("width", '100%');
    this.sliderWrap.attr("transform", "translate(" + this.padding.left + "," + (this.propertyActiveProfile.max + this.padding.top) + ")");
  },

  //   _updateArcs: function(s) {
  //     var _this = this;
  //     var valueArc = d3.svg.arc()
  //       .outerRadius(function (d) { return _this.xScale(d) * 0.5 })
  //       .innerRadius(function (d) { return _this.xScale(d) * 0.5 })
  //       .startAngle(-Math.PI * 0.5)
  //       .endAngle(Math.PI * 0.5);
  //
  //     this.sliderThumbs.select('.vzb-szs-slider-thumb-arc').data(s)
  //       .attr("d", valueArc)
  //       .attr("transform", function (d) {return "translate(" + (-_this.xScale(d) * 0.25) + ",0)"; })
  //   },
  //
  _updateLabels: function _updateLabels(s) {
    var _this = this;
    var arcLabelTransform = function arcLabelTransform(d, i) {
      var dX = _this.xScale(i),
          dY = 0; //i ? -textMargin.v : 0;
      return "translate(" + dX + "," + dY + ")";
    };
    this.sliderLabelsEl.data(s).attr("transform", arcLabelTransform).attr("font-size", function (d, i) {
      return _this.propertyScale(d);
    });
    if (_this.model.size.use === 'constant') this.sliderLabelsEl.data(s).text(function (d) {
      return ~~_this.propertyScale(d) + (_this.translator(_this.ui.constantUnit) || "");
    });
  },

  _setLabelsText: function _setLabelsText() {
    var _this = this;
    _this.sliderLabelsEl.data([_this.model.size.getTickFormatter()(_this.sizeScaleMinMax[0]), _this.model.size.getTickFormatter()(_this.sizeScaleMinMax[1])]).text(function (d) {
      return d;
    });
  },

  /**
   * Prepares setting of the current model with the values from extent.
   * @param {boolean} set model
   * @param {boolean} force force firing the change event
   * @param {boolean} persistent sets the persistency of the change event
   */
  _setFromExtent: function _setFromExtent(setModel, force, persistent) {
    var s = this.brush.extent();
    //    this._updateArcs(s);
    this._updateLabels(s);
    if (setModel) this._setModel(s, force, persistent);
  },

  /**
   * Sets the current value in model. avoid updating more than once in framerate
   * @param {number} value
   * @param {boolean} force force firing the change event
   * @param {boolean} persistent sets the persistency of the change event
   */
  _setModel: function _setModel(value, force, persistent) {
    value = [+value[0].toFixed(2), +value[1].toFixed(2)];
    this.model.size.set({ "extent": value }, force, persistent);
  }

});

exports.default = SizeSlider;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _iconset = __webpack_require__(10);

var iconset = _interopRequireWildcard(_iconset);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*!
 * VIZABI OPTIONSBUTTONLIST
 * Reusable optionsbuttonlist component
 */

//default existing buttons
var class_active = "vzb-active";
// var class_active_locked = "vzb-active-locked";
// var class_expand_dialog = "vzb-dialog-side";
// var class_hide_btn = "vzb-dialog-side-btn";
// var class_unavailable = "vzb-unavailable";
// var class_vzb_fullscreen = "vzb-force-fullscreen";
// var class_container_fullscreen = "vzb-container-fullscreen";

var ZoomButtonList = _component2.default.extend({

  /**
   * Initializes the buttonlist
   * @param config component configuration
   * @param context component context (parent)
   */
  init: function init(config, context) {

    //set properties
    var _this = this;
    this.name = 'gapminder-zoombuttonlist';

    this.model_expects = [{
      name: "state",
      type: "model"
    }, {
      name: "ui",
      type: "ui"
    }, {
      name: "locale",
      type: "locale"
    }];

    this._available_buttons = {
      'arrow': {
        title: "buttons/cursorarrow",
        icon: "cursorArrow",
        func: this.toggleCursorMode.bind(this),
        required: true,
        statebind: "ui.cursorMode",
        statebindfunc: this.setCursorMode.bind(this)
      },
      'plus': {
        title: "buttons/cursorplus",
        icon: "cursorPlus",
        func: this.toggleCursorMode.bind(this),
        required: true,
        statebind: "ui.cursorMode",
        statebindfunc: this.setCursorMode.bind(this)
      },
      'minus': {
        title: "buttons/cursorminus",
        icon: "cursorMinus",
        func: this.toggleCursorMode.bind(this),
        required: true,
        statebind: "ui.cursorMode",
        statebindfunc: this.setCursorMode.bind(this)
      },
      'hundredpercent': {
        title: "buttons/hundredpercent",
        icon: "hundredPercent",
        func: this.toggleHundredPercent.bind(this),
        required: true
        // ,
        // statebind: "ui.chart.trails",
        // statebindfunc: this.setBubbleTrails.bind(this)
      }
    };

    this.model_binds = {};

    Object.keys(this._available_buttons).forEach(function (buttonId) {
      var button = _this._available_buttons[buttonId];
      if (button && button.statebind) {
        _this.model_binds['change:' + button.statebind] = function (evt) {
          button.statebindfunc(buttonId, evt.source.value);
        };
      }
    });

    this._super(config, context);
  },

  readyOnce: function readyOnce() {
    var _this = this;

    this.element = d3.select(this.placeholder);
    this.element.selectAll("div").remove();

    this._addButtons(Object.keys(this._available_buttons), []);
    this.setCursorMode('arrow');
  },

  /*
   * adds buttons configuration to the components and template_data
   * @param {Array} button_list list of buttons to be added
   */
  _addButtons: function _addButtons(button_list, button_expand) {
    var _this = this;
    this._components_config = [];
    var details_btns = [];
    if (!button_list.length) return;
    //add a component for each button
    for (var i = 0; i < button_list.length; i++) {

      var btn = button_list[i];
      var btn_config = this._available_buttons[btn];

      //add template data
      var d = btn_config ? btn : "_default";
      var details_btn = utils.clone(this._available_buttons[d]);

      details_btn.id = btn;
      details_btn.icon = iconset[details_btn.icon];
      details_btns.push(details_btn);
    };

    var t = this.getTranslationFunction(true);

    this.element.selectAll('button').data(details_btns).enter().append("button").attr('class', function (d) {
      var cls = 'vzb-buttonlist-btn';
      if (button_expand.length > 0) {
        if (button_expand.indexOf(d.id) > -1) {
          cls += ' vzb-dialog-side-btn';
        }
      }

      return cls;
    }).attr('data-btn', function (d) {
      return d.id;
    }).html(function (btn) {
      return "<span class='vzb-buttonlist-btn-icon fa'>" + btn.icon + "</span><span class='vzb-buttonlist-btn-title'>" + t(btn.title) + "</span>";
    });

    var buttons = this.element.selectAll(".vzb-buttonlist-btn");

    //clicking the button
    buttons.on('click', function () {

      d3.event.preventDefault();
      d3.event.stopPropagation();

      var id = d3.select(this).attr("data-btn");
      _this.proceedClick(id);
    });
  },

  proceedClick: function proceedClick(id) {
    var _this = this;
    var btn = _this.element.selectAll(".vzb-buttonlist-btn[data-btn='" + id + "']"),
        classes = btn.attr("class"),
        btn_config = _this._available_buttons[id];

    if (btn_config && btn_config.func) {
      btn_config.func(id);
    } else {
      var btn_active = classes.indexOf(class_active) === -1;

      btn.classed(class_active, btn_active);
      var evt = {};
      evt['id'] = id;
      evt['active'] = btn_active;
      _this.trigger('click', evt);
    }
  },

  setButtonActive: function setButtonActive(id, boolActive) {
    var btn = this.element.selectAll(".vzb-buttonlist-btn[data-btn='" + id + "']");

    btn.classed(class_active, boolActive);
  },

  toggleCursorMode: function toggleCursorMode(id) {
    var value = id;
    this.model.ui.set('cursorMode', value, false, false);
  },

  setCursorMode: function setCursorMode(id) {
    var value = this.model.ui.cursorMode ? this.model.ui.cursorMode : 'arrow';
    this.element.selectAll(".vzb-buttonlist-btn").classed(class_active, function (d) {
      return d.id == value;
    });
  },

  toggleHundredPercent: function toggleHundredPercent(id) {
    this.root.trigger("resetZoom");
  }

});

exports.default = ZoomButtonList;

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

"use strict";
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});

exports.default = function () {
  d3.geo.project = function (object, projection) {
    var stream = projection.stream;
    if (!stream) throw new Error("not yet supported");
    return (object && d3_geo_projectObjectType.hasOwnProperty(object.type) ? d3_geo_projectObjectType[object.type] : d3_geo_projectGeometry)(object, stream);
  };
  function d3_geo_projectFeature(object, stream) {
    return {
      type: "Feature",
      id: object.id,
      properties: object.properties,
      geometry: d3_geo_projectGeometry(object.geometry, stream)
    };
  }
  function d3_geo_projectGeometry(geometry, stream) {
    if (!geometry) return null;
    if (geometry.type === "GeometryCollection") return {
      type: "GeometryCollection",
      geometries: object.geometries.map(function (geometry) {
        return d3_geo_projectGeometry(geometry, stream);
      })
    };
    if (!d3_geo_projectGeometryType.hasOwnProperty(geometry.type)) return null;
    var sink = d3_geo_projectGeometryType[geometry.type];
    d3.geo.stream(geometry, stream(sink));
    return sink.result();
  }
  var d3_geo_projectObjectType = {
    Feature: d3_geo_projectFeature,
    FeatureCollection: function FeatureCollection(object, stream) {
      return {
        type: "FeatureCollection",
        features: object.features.map(function (feature) {
          return d3_geo_projectFeature(feature, stream);
        })
      };
    }
  };
  var d3_geo_projectPoints = [],
      d3_geo_projectLines = [];
  var d3_geo_projectPoint = {
    point: function point(x, y) {
      d3_geo_projectPoints.push([x, y]);
    },
    result: function result() {
      var result = !d3_geo_projectPoints.length ? null : d3_geo_projectPoints.length < 2 ? {
        type: "Point",
        coordinates: d3_geo_projectPoints[0]
      } : {
        type: "MultiPoint",
        coordinates: d3_geo_projectPoints
      };
      d3_geo_projectPoints = [];
      return result;
    }
  };
  var d3_geo_projectLine = {
    lineStart: d3_geo_projectNoop,
    point: function point(x, y) {
      d3_geo_projectPoints.push([x, y]);
    },
    lineEnd: function lineEnd() {
      if (d3_geo_projectPoints.length) d3_geo_projectLines.push(d3_geo_projectPoints), d3_geo_projectPoints = [];
    },
    result: function result() {
      var result = !d3_geo_projectLines.length ? null : d3_geo_projectLines.length < 2 ? {
        type: "LineString",
        coordinates: d3_geo_projectLines[0]
      } : {
        type: "MultiLineString",
        coordinates: d3_geo_projectLines
      };
      d3_geo_projectLines = [];
      return result;
    }
  };
  var d3_geo_projectPolygon = {
    polygonStart: d3_geo_projectNoop,
    lineStart: d3_geo_projectNoop,
    point: function point(x, y) {
      d3_geo_projectPoints.push([x, y]);
    },
    lineEnd: function lineEnd() {
      var n = d3_geo_projectPoints.length;
      if (n) {
        do {
          d3_geo_projectPoints.push(d3_geo_projectPoints[0].slice());
        } while (++n < 4);
        d3_geo_projectLines.push(d3_geo_projectPoints), d3_geo_projectPoints = [];
      }
    },
    polygonEnd: d3_geo_projectNoop,
    result: function result() {
      if (!d3_geo_projectLines.length) return null;
      var polygons = [],
          holes = [];
      d3_geo_projectLines.forEach(function (ring) {
        if (d3_geo_projectClockwise(ring)) polygons.push([ring]);else holes.push(ring);
      });
      holes.forEach(function (hole) {
        var point = hole[0];
        polygons.some(function (polygon) {
          if (d3_geo_projectContains(polygon[0], point)) {
            polygon.push(hole);
            return true;
          }
        }) || polygons.push([hole]);
      });
      d3_geo_projectLines = [];
      return !polygons.length ? null : polygons.length > 1 ? {
        type: "MultiPolygon",
        coordinates: polygons
      } : {
        type: "Polygon",
        coordinates: polygons[0]
      };
    }
  };
  var d3_geo_projectGeometryType = {
    Point: d3_geo_projectPoint,
    MultiPoint: d3_geo_projectPoint,
    LineString: d3_geo_projectLine,
    MultiLineString: d3_geo_projectLine,
    Polygon: d3_geo_projectPolygon,
    MultiPolygon: d3_geo_projectPolygon,
    Sphere: d3_geo_projectPolygon
  };
  function d3_geo_projectNoop() {}
  function d3_geo_projectClockwise(ring) {
    if ((n = ring.length) < 4) return false;
    var i = 0,
        n,
        area = ring[n - 1][1] * ring[0][0] - ring[n - 1][0] * ring[0][1];
    while (++i < n) {
      area += ring[i - 1][1] * ring[i][0] - ring[i - 1][0] * ring[i][1];
    }return area <= 0;
  }
  function d3_geo_projectContains(ring, point) {
    var x = point[0],
        y = point[1],
        contains = false;
    for (var i = 0, n = ring.length, j = n - 1; i < n; j = i++) {
      var pi = ring[i],
          xi = pi[0],
          yi = pi[1],
          pj = ring[j],
          xj = pj[0],
          yj = pj[1];
      if (yi > y ^ yj > y && x < (xj - xi) * (y - yi) / (yj - yi) + xi) contains = !contains;
    }
    return contains;
  }
  var ε = 1e-6,
      ε2 = ε * ε,
      π = Math.PI,
      halfπ = π / 2,
      sqrtπ = Math.sqrt(π),
      radians = π / 180,
      degrees = 180 / π;
  function sinci(x) {
    return x ? x / Math.sin(x) : 1;
  }
  function sgn(x) {
    return x > 0 ? 1 : x < 0 ? -1 : 0;
  }
  function asin(x) {
    return x > 1 ? halfπ : x < -1 ? -halfπ : Math.asin(x);
  }
  function acos(x) {
    return x > 1 ? 0 : x < -1 ? π : Math.acos(x);
  }
  function asqrt(x) {
    return x > 0 ? Math.sqrt(x) : 0;
  }
  var projection = d3.geo.projection,
      projectionMutator = d3.geo.projectionMutator;
  d3.geo.interrupt = function (project) {
    var lobes = [[[[-π, 0], [0, halfπ], [π, 0]]], [[[-π, 0], [0, -halfπ], [π, 0]]]];
    var bounds;
    function forward(λ, φ) {
      var sign = φ < 0 ? -1 : +1,
          hemilobes = lobes[+(φ < 0)];
      for (var i = 0, n = hemilobes.length - 1; i < n && λ > hemilobes[i][2][0]; ++i) {}
      var coordinates = project(λ - hemilobes[i][1][0], φ);
      coordinates[0] += project(hemilobes[i][1][0], sign * φ > sign * hemilobes[i][0][1] ? hemilobes[i][0][1] : φ)[0];
      return coordinates;
    }
    function reset() {
      bounds = lobes.map(function (hemilobes) {
        return hemilobes.map(function (lobe) {
          var x0 = project(lobe[0][0], lobe[0][1])[0],
              x1 = project(lobe[2][0], lobe[2][1])[0],
              y0 = project(lobe[1][0], lobe[0][1])[1],
              y1 = project(lobe[1][0], lobe[1][1])[1],
              t;
          if (y0 > y1) t = y0, y0 = y1, y1 = t;
          return [[x0, y0], [x1, y1]];
        });
      });
    }
    if (project.invert) forward.invert = function (x, y) {
      var hemibounds = bounds[+(y < 0)],
          hemilobes = lobes[+(y < 0)];
      for (var i = 0, n = hemibounds.length; i < n; ++i) {
        var b = hemibounds[i];
        if (b[0][0] <= x && x < b[1][0] && b[0][1] <= y && y < b[1][1]) {
          var coordinates = project.invert(x - project(hemilobes[i][1][0], 0)[0], y);
          coordinates[0] += hemilobes[i][1][0];
          return pointEqual(forward(coordinates[0], coordinates[1]), [x, y]) ? coordinates : null;
        }
      }
    };
    var projection = d3.geo.projection(forward),
        stream_ = projection.stream;
    projection.stream = function (stream) {
      var rotate = projection.rotate(),
          rotateStream = stream_(stream),
          sphereStream = (projection.rotate([0, 0]), stream_(stream));
      projection.rotate(rotate);
      rotateStream.sphere = function () {
        d3.geo.stream(sphere(), sphereStream);
      };
      return rotateStream;
    };
    projection.lobes = function (_) {
      if (!arguments.length) return lobes.map(function (lobes) {
        return lobes.map(function (lobe) {
          return [[lobe[0][0] * 180 / π, lobe[0][1] * 180 / π], [lobe[1][0] * 180 / π, lobe[1][1] * 180 / π], [lobe[2][0] * 180 / π, lobe[2][1] * 180 / π]];
        });
      });
      lobes = _.map(function (lobes) {
        return lobes.map(function (lobe) {
          return [[lobe[0][0] * π / 180, lobe[0][1] * π / 180], [lobe[1][0] * π / 180, lobe[1][1] * π / 180], [lobe[2][0] * π / 180, lobe[2][1] * π / 180]];
        });
      });
      reset();
      return projection;
    };
    function sphere() {
      var ε = 1e-6,
          coordinates = [];
      for (var i = 0, n = lobes[0].length; i < n; ++i) {
        var lobe = lobes[0][i],
            λ0 = lobe[0][0] * 180 / π,
            φ0 = lobe[0][1] * 180 / π,
            φ1 = lobe[1][1] * 180 / π,
            λ2 = lobe[2][0] * 180 / π,
            φ2 = lobe[2][1] * 180 / π;
        coordinates.push(resample([[λ0 + ε, φ0 + ε], [λ0 + ε, φ1 - ε], [λ2 - ε, φ1 - ε], [λ2 - ε, φ2 + ε]], 30));
      }
      for (var i = lobes[1].length - 1; i >= 0; --i) {
        var lobe = lobes[1][i],
            λ0 = lobe[0][0] * 180 / π,
            φ0 = lobe[0][1] * 180 / π,
            φ1 = lobe[1][1] * 180 / π,
            λ2 = lobe[2][0] * 180 / π,
            φ2 = lobe[2][1] * 180 / π;
        coordinates.push(resample([[λ2 - ε, φ2 - ε], [λ2 - ε, φ1 + ε], [λ0 + ε, φ1 + ε], [λ0 + ε, φ0 - ε]], 30));
      }
      return {
        type: "Polygon",
        coordinates: [d3.merge(coordinates)]
      };
    }
    function resample(coordinates, m) {
      var i = -1,
          n = coordinates.length,
          p0 = coordinates[0],
          p1,
          dx,
          dy,
          resampled = [];
      while (++i < n) {
        p1 = coordinates[i];
        dx = (p1[0] - p0[0]) / m;
        dy = (p1[1] - p0[1]) / m;
        for (var j = 0; j < m; ++j) {
          resampled.push([p0[0] + j * dx, p0[1] + j * dy]);
        }p0 = p1;
      }
      resampled.push(p1);
      return resampled;
    }
    function pointEqual(a, b) {
      return Math.abs(a[0] - b[0]) < ε && Math.abs(a[1] - b[1]) < ε;
    }
    return projection;
  };
  function airy(β) {
    var tanβ_2 = Math.tan(.5 * β),
        B = 2 * Math.log(Math.cos(.5 * β)) / (tanβ_2 * tanβ_2);
    function forward(λ, φ) {
      var cosλ = Math.cos(λ),
          cosφ = Math.cos(φ),
          sinφ = Math.sin(φ),
          cosz = cosφ * cosλ,
          K = -((1 - cosz ? Math.log(.5 * (1 + cosz)) / (1 - cosz) : -.5) + B / (1 + cosz));
      return [K * cosφ * Math.sin(λ), K * sinφ];
    }
    forward.invert = function (x, y) {
      var ρ = Math.sqrt(x * x + y * y),
          z = β * -.5,
          i = 50,
          δ;
      if (!ρ) return [0, 0];
      do {
        var z_2 = .5 * z,
            cosz_2 = Math.cos(z_2),
            sinz_2 = Math.sin(z_2),
            tanz_2 = Math.tan(z_2),
            lnsecz_2 = Math.log(1 / cosz_2);
        z -= δ = (2 / tanz_2 * lnsecz_2 - B * tanz_2 - ρ) / (-lnsecz_2 / (sinz_2 * sinz_2) + 1 - B / (2 * cosz_2 * cosz_2));
      } while (Math.abs(δ) > ε && --i > 0);
      var sinz = Math.sin(z);
      return [Math.atan2(x * sinz, ρ * Math.cos(z)), asin(y * sinz / ρ)];
    };
    return forward;
  }
  function airyProjection() {
    var β = halfπ,
        m = projectionMutator(airy),
        p = m(β);
    p.radius = function (_) {
      if (!arguments.length) return β / π * 180;
      return m(β = _ * π / 180);
    };
    return p;
  }
  (d3.geo.airy = airyProjection).raw = airy;
  function aitoff(λ, φ) {
    var cosφ = Math.cos(φ),
        sinciα = sinci(acos(cosφ * Math.cos(λ /= 2)));
    return [2 * cosφ * Math.sin(λ) * sinciα, Math.sin(φ) * sinciα];
  }
  aitoff.invert = function (x, y) {
    if (x * x + 4 * y * y > π * π + ε) return;
    var λ = x,
        φ = y,
        i = 25;
    do {
      var sinλ = Math.sin(λ),
          sinλ_2 = Math.sin(λ / 2),
          cosλ_2 = Math.cos(λ / 2),
          sinφ = Math.sin(φ),
          cosφ = Math.cos(φ),
          sin_2φ = Math.sin(2 * φ),
          sin2φ = sinφ * sinφ,
          cos2φ = cosφ * cosφ,
          sin2λ_2 = sinλ_2 * sinλ_2,
          C = 1 - cos2φ * cosλ_2 * cosλ_2,
          E = C ? acos(cosφ * cosλ_2) * Math.sqrt(F = 1 / C) : F = 0,
          F,
          fx = 2 * E * cosφ * sinλ_2 - x,
          fy = E * sinφ - y,
          δxδλ = F * (cos2φ * sin2λ_2 + E * cosφ * cosλ_2 * sin2φ),
          δxδφ = F * (.5 * sinλ * sin_2φ - E * 2 * sinφ * sinλ_2),
          δyδλ = F * .25 * (sin_2φ * sinλ_2 - E * sinφ * cos2φ * sinλ),
          δyδφ = F * (sin2φ * cosλ_2 + E * sin2λ_2 * cosφ),
          denominator = δxδφ * δyδλ - δyδφ * δxδλ;
      if (!denominator) break;
      var δλ = (fy * δxδφ - fx * δyδφ) / denominator,
          δφ = (fx * δyδλ - fy * δxδλ) / denominator;
      λ -= δλ, φ -= δφ;
    } while ((Math.abs(δλ) > ε || Math.abs(δφ) > ε) && --i > 0);
    return [λ, φ];
  };
  (d3.geo.aitoff = function () {
    return projection(aitoff);
  }).raw = aitoff;
  function armadillo(φ0) {
    var sinφ0 = Math.sin(φ0),
        cosφ0 = Math.cos(φ0),
        sφ0 = φ0 > 0 ? 1 : -1,
        tanφ0 = Math.tan(sφ0 * φ0),
        k = (1 + sinφ0 - cosφ0) / 2;
    function forward(λ, φ) {
      var cosφ = Math.cos(φ),
          cosλ = Math.cos(λ /= 2);
      return [(1 + cosφ) * Math.sin(λ), (sφ0 * φ > -Math.atan2(cosλ, tanφ0) - .001 ? 0 : -sφ0 * 10) + k + Math.sin(φ) * cosφ0 - (1 + cosφ) * sinφ0 * cosλ];
    }
    forward.invert = function (x, y) {
      var λ = 0,
          φ = 0,
          i = 50;
      do {
        var cosλ = Math.cos(λ),
            sinλ = Math.sin(λ),
            cosφ = Math.cos(φ),
            sinφ = Math.sin(φ),
            A = 1 + cosφ,
            fx = A * sinλ - x,
            fy = k + sinφ * cosφ0 - A * sinφ0 * cosλ - y,
            δxδλ = .5 * A * cosλ,
            δxδφ = -sinλ * sinφ,
            δyδλ = .5 * sinφ0 * A * sinλ,
            δyδφ = cosφ0 * cosφ + sinφ0 * cosλ * sinφ,
            denominator = δxδφ * δyδλ - δyδφ * δxδλ,
            δλ = .5 * (fy * δxδφ - fx * δyδφ) / denominator,
            δφ = (fx * δyδλ - fy * δxδλ) / denominator;
        λ -= δλ, φ -= δφ;
      } while ((Math.abs(δλ) > ε || Math.abs(δφ) > ε) && --i > 0);
      return sφ0 * φ > -Math.atan2(Math.cos(λ), tanφ0) - .001 ? [λ * 2, φ] : null;
    };
    return forward;
  }
  function armadilloProjection() {
    var φ0 = π / 9,
        sφ0 = φ0 > 0 ? 1 : -1,
        tanφ0 = Math.tan(sφ0 * φ0),
        m = projectionMutator(armadillo),
        p = m(φ0),
        stream_ = p.stream;
    p.parallel = function (_) {
      if (!arguments.length) return φ0 / π * 180;
      tanφ0 = Math.tan((sφ0 = (φ0 = _ * π / 180) > 0 ? 1 : -1) * φ0);
      return m(φ0);
    };
    p.stream = function (stream) {
      var rotate = p.rotate(),
          rotateStream = stream_(stream),
          sphereStream = (p.rotate([0, 0]), stream_(stream));
      p.rotate(rotate);
      rotateStream.sphere = function () {
        sphereStream.polygonStart(), sphereStream.lineStart();
        for (var λ = sφ0 * -180; sφ0 * λ < 180; λ += sφ0 * 90) {
          sphereStream.point(λ, sφ0 * 90);
        }while (sφ0 * (λ -= φ0) >= -180) {
          sphereStream.point(λ, sφ0 * -Math.atan2(Math.cos(λ * radians / 2), tanφ0) * degrees);
        }
        sphereStream.lineEnd(), sphereStream.polygonEnd();
      };
      return rotateStream;
    };
    return p;
  }
  (d3.geo.armadillo = armadilloProjection).raw = armadillo;
  function tanh(x) {
    x = Math.exp(2 * x);
    return (x - 1) / (x + 1);
  }
  function sinh(x) {
    return .5 * (Math.exp(x) - Math.exp(-x));
  }
  function cosh(x) {
    return .5 * (Math.exp(x) + Math.exp(-x));
  }
  function arsinh(x) {
    return Math.log(x + asqrt(x * x + 1));
  }
  function arcosh(x) {
    return Math.log(x + asqrt(x * x - 1));
  }
  function august(λ, φ) {
    var tanφ = Math.tan(φ / 2),
        k = asqrt(1 - tanφ * tanφ),
        c = 1 + k * Math.cos(λ /= 2),
        x = Math.sin(λ) * k / c,
        y = tanφ / c,
        x2 = x * x,
        y2 = y * y;
    return [4 / 3 * x * (3 + x2 - 3 * y2), 4 / 3 * y * (3 + 3 * x2 - y2)];
  }
  august.invert = function (x, y) {
    x *= 3 / 8, y *= 3 / 8;
    if (!x && Math.abs(y) > 1) return null;
    var x2 = x * x,
        y2 = y * y,
        s = 1 + x2 + y2,
        sin3η = Math.sqrt(.5 * (s - Math.sqrt(s * s - 4 * y * y))),
        η = asin(sin3η) / 3,
        ξ = sin3η ? arcosh(Math.abs(y / sin3η)) / 3 : arsinh(Math.abs(x)) / 3,
        cosη = Math.cos(η),
        coshξ = cosh(ξ),
        d = coshξ * coshξ - cosη * cosη;
    return [sgn(x) * 2 * Math.atan2(sinh(ξ) * cosη, .25 - d), sgn(y) * 2 * Math.atan2(coshξ * Math.sin(η), .25 + d)];
  };
  (d3.geo.august = function () {
    return projection(august);
  }).raw = august;
  var bakerφ = Math.log(1 + Math.SQRT2);
  function baker(λ, φ) {
    var φ0 = Math.abs(φ);
    return φ0 < π / 4 ? [λ, Math.log(Math.tan(π / 4 + φ / 2))] : [λ * Math.cos(φ0) * (2 * Math.SQRT2 - 1 / Math.sin(φ0)), sgn(φ) * (2 * Math.SQRT2 * (φ0 - π / 4) - Math.log(Math.tan(φ0 / 2)))];
  }
  baker.invert = function (x, y) {
    if ((y0 = Math.abs(y)) < bakerφ) return [x, 2 * Math.atan(Math.exp(y)) - halfπ];
    var sqrt8 = Math.sqrt(8),
        φ = π / 4,
        i = 25,
        δ,
        y0;
    do {
      var cosφ_2 = Math.cos(φ / 2),
          tanφ_2 = Math.tan(φ / 2);
      φ -= δ = (sqrt8 * (φ - π / 4) - Math.log(tanφ_2) - y0) / (sqrt8 - .5 * cosφ_2 * cosφ_2 / tanφ_2);
    } while (Math.abs(δ) > ε2 && --i > 0);
    return [x / (Math.cos(φ) * (sqrt8 - 1 / Math.sin(φ))), sgn(y) * φ];
  };
  (d3.geo.baker = function () {
    return projection(baker);
  }).raw = baker;
  var berghausAzimuthalEquidistant = d3.geo.azimuthalEquidistant.raw;
  function berghaus(n) {
    var k = 2 * π / n;
    function forward(λ, φ) {
      var p = berghausAzimuthalEquidistant(λ, φ);
      if (Math.abs(λ) > halfπ) {
        var θ = Math.atan2(p[1], p[0]),
            r = Math.sqrt(p[0] * p[0] + p[1] * p[1]),
            θ0 = k * Math.round((θ - halfπ) / k) + halfπ,
            α = Math.atan2(Math.sin(θ -= θ0), 2 - Math.cos(θ));
        θ = θ0 + asin(π / r * Math.sin(α)) - α;
        p[0] = r * Math.cos(θ);
        p[1] = r * Math.sin(θ);
      }
      return p;
    }
    forward.invert = function (x, y) {
      var r = Math.sqrt(x * x + y * y);
      if (r > halfπ) {
        var θ = Math.atan2(y, x),
            θ0 = k * Math.round((θ - halfπ) / k) + halfπ,
            s = θ > θ0 ? -1 : 1,
            A = r * Math.cos(θ0 - θ),
            cotα = 1 / Math.tan(s * Math.acos((A - π) / Math.sqrt(π * (π - 2 * A) + r * r)));
        θ = θ0 + 2 * Math.atan((cotα + s * Math.sqrt(cotα * cotα - 3)) / 3);
        x = r * Math.cos(θ), y = r * Math.sin(θ);
      }
      return berghausAzimuthalEquidistant.invert(x, y);
    };
    return forward;
  }
  function berghausProjection() {
    var n = 5,
        m = projectionMutator(berghaus),
        p = m(n),
        stream_ = p.stream,
        ε = .01,
        cr = -Math.cos(ε * radians),
        sr = Math.sin(ε * radians);
    p.lobes = function (_) {
      if (!arguments.length) return n;
      return m(n = +_);
    };
    p.stream = function (stream) {
      var rotate = p.rotate(),
          rotateStream = stream_(stream),
          sphereStream = (p.rotate([0, 0]), stream_(stream));
      p.rotate(rotate);
      rotateStream.sphere = function () {
        sphereStream.polygonStart(), sphereStream.lineStart();
        for (var i = 0, δ = 360 / n, δ0 = 2 * π / n, φ = 90 - 180 / n, φ0 = halfπ; i < n; ++i, φ -= δ, φ0 -= δ0) {
          sphereStream.point(Math.atan2(sr * Math.cos(φ0), cr) * degrees, asin(sr * Math.sin(φ0)) * degrees);
          if (φ < -90) {
            sphereStream.point(-90, -180 - φ - ε);
            sphereStream.point(-90, -180 - φ + ε);
          } else {
            sphereStream.point(90, φ + ε);
            sphereStream.point(90, φ - ε);
          }
        }
        sphereStream.lineEnd(), sphereStream.polygonEnd();
      };
      return rotateStream;
    };
    return p;
  }
  (d3.geo.berghaus = berghausProjection).raw = berghaus;
  function mollweideBromleyθ(Cp) {
    return function (θ) {
      var Cpsinθ = Cp * Math.sin(θ),
          i = 30,
          δ;
      do {
        θ -= δ = (θ + Math.sin(θ) - Cpsinθ) / (1 + Math.cos(θ));
      } while (Math.abs(δ) > ε && --i > 0);
      return θ / 2;
    };
  }
  function mollweideBromley(Cx, Cy, Cp) {
    var θ = mollweideBromleyθ(Cp);
    function forward(λ, φ) {
      return [Cx * λ * Math.cos(φ = θ(φ)), Cy * Math.sin(φ)];
    }
    forward.invert = function (x, y) {
      var θ = asin(y / Cy);
      return [x / (Cx * Math.cos(θ)), asin((2 * θ + Math.sin(2 * θ)) / Cp)];
    };
    return forward;
  }
  var mollweideθ = mollweideBromleyθ(π),
      mollweide = mollweideBromley(Math.SQRT2 / halfπ, Math.SQRT2, π);
  (d3.geo.mollweide = function () {
    return projection(mollweide);
  }).raw = mollweide;
  function boggs(λ, φ) {
    var k = 2.00276,
        θ = mollweideθ(φ);
    return [k * λ / (1 / Math.cos(φ) + 1.11072 / Math.cos(θ)), (φ + Math.SQRT2 * Math.sin(θ)) / k];
  }
  boggs.invert = function (x, y) {
    var k = 2.00276,
        ky = k * y,
        θ = y < 0 ? -π / 4 : π / 4,
        i = 25,
        δ,
        φ;
    do {
      φ = ky - Math.SQRT2 * Math.sin(θ);
      θ -= δ = (Math.sin(2 * θ) + 2 * θ - π * Math.sin(φ)) / (2 * Math.cos(2 * θ) + 2 + π * Math.cos(φ) * Math.SQRT2 * Math.cos(θ));
    } while (Math.abs(δ) > ε && --i > 0);
    φ = ky - Math.SQRT2 * Math.sin(θ);
    return [x * (1 / Math.cos(φ) + 1.11072 / Math.cos(θ)) / k, φ];
  };
  (d3.geo.boggs = function () {
    return projection(boggs);
  }).raw = boggs;
  function parallel1Projection(projectAt) {
    var φ0 = 0,
        m = projectionMutator(projectAt),
        p = m(φ0);
    p.parallel = function (_) {
      if (!arguments.length) return φ0 / π * 180;
      return m(φ0 = _ * π / 180);
    };
    return p;
  }
  function sinusoidal(λ, φ) {
    return [λ * Math.cos(φ), φ];
  }
  sinusoidal.invert = function (x, y) {
    return [x / Math.cos(y), y];
  };
  (d3.geo.sinusoidal = function () {
    return projection(sinusoidal);
  }).raw = sinusoidal;
  function bonne(φ0) {
    if (!φ0) return sinusoidal;
    var cotφ0 = 1 / Math.tan(φ0);
    function forward(λ, φ) {
      var ρ = cotφ0 + φ0 - φ,
          E = ρ ? λ * Math.cos(φ) / ρ : ρ;
      return [ρ * Math.sin(E), cotφ0 - ρ * Math.cos(E)];
    }
    forward.invert = function (x, y) {
      var ρ = Math.sqrt(x * x + (y = cotφ0 - y) * y),
          φ = cotφ0 + φ0 - ρ;
      return [ρ / Math.cos(φ) * Math.atan2(x, y), φ];
    };
    return forward;
  }
  (d3.geo.bonne = function () {
    return parallel1Projection(bonne).parallel(45);
  }).raw = bonne;
  var bromley = mollweideBromley(1, 4 / π, π);
  (d3.geo.bromley = function () {
    return projection(bromley);
  }).raw = bromley;
  function chamberlin(points) {
    points = points.map(function (p) {
      return [p[0], p[1], Math.sin(p[1]), Math.cos(p[1])];
    });
    for (var a = points[2], b, i = 0; i < 3; ++i, a = b) {
      b = points[i];
      a.v = chamberlinDistanceAzimuth(b[1] - a[1], a[3], a[2], b[3], b[2], b[0] - a[0]);
      a.point = [0, 0];
    }
    var β0 = chamberlinAngle(points[0].v[0], points[2].v[0], points[1].v[0]),
        β1 = chamberlinAngle(points[0].v[0], points[1].v[0], points[2].v[0]),
        β2 = π - β0;
    points[2].point[1] = 0;
    points[0].point[0] = -(points[1].point[0] = .5 * points[0].v[0]);
    var mean = [points[2].point[0] = points[0].point[0] + points[2].v[0] * Math.cos(β0), 2 * (points[0].point[1] = points[1].point[1] = points[2].v[0] * Math.sin(β0))];
    function forward(λ, φ) {
      var sinφ = Math.sin(φ),
          cosφ = Math.cos(φ),
          v = new Array(3);
      for (var i = 0; i < 3; ++i) {
        var p = points[i];
        v[i] = chamberlinDistanceAzimuth(φ - p[1], p[3], p[2], cosφ, sinφ, λ - p[0]);
        if (!v[i][0]) return p.point;
        v[i][1] = chamberlinLongitude(v[i][1] - p.v[1]);
      }
      var point = mean.slice();
      for (var i = 0; i < 3; ++i) {
        var j = i == 2 ? 0 : i + 1;
        var a = chamberlinAngle(points[i].v[0], v[i][0], v[j][0]);
        if (v[i][1] < 0) a = -a;
        if (!i) {
          point[0] += v[i][0] * Math.cos(a);
          point[1] -= v[i][0] * Math.sin(a);
        } else if (i == 1) {
          a = β1 - a;
          point[0] -= v[i][0] * Math.cos(a);
          point[1] -= v[i][0] * Math.sin(a);
        } else {
          a = β2 - a;
          point[0] += v[i][0] * Math.cos(a);
          point[1] += v[i][0] * Math.sin(a);
        }
      }
      point[0] /= 3, point[1] /= 3;
      return point;
    }
    return forward;
  }
  function chamberlinProjection() {
    var points = [[0, 0], [0, 0], [0, 0]],
        m = projectionMutator(chamberlin),
        p = m(points),
        rotate = p.rotate;
    delete p.rotate;
    p.points = function (_) {
      if (!arguments.length) return points;
      points = _;
      var origin = d3.geo.centroid({
        type: "MultiPoint",
        coordinates: points
      }),
          r = [-origin[0], -origin[1]];
      rotate.call(p, r);
      return m(points.map(d3.geo.rotation(r)).map(chamberlinRadians));
    };
    return p.points([[-150, 55], [-35, 55], [-92.5, 10]]);
  }
  function chamberlinDistanceAzimuth(dφ, c1, s1, c2, s2, dλ) {
    var cosdλ = Math.cos(dλ),
        r;
    if (Math.abs(dφ) > 1 || Math.abs(dλ) > 1) {
      r = acos(s1 * s2 + c1 * c2 * cosdλ);
    } else {
      var sindφ = Math.sin(.5 * dφ),
          sindλ = Math.sin(.5 * dλ);
      r = 2 * asin(Math.sqrt(sindφ * sindφ + c1 * c2 * sindλ * sindλ));
    }
    if (Math.abs(r) > ε) {
      return [r, Math.atan2(c2 * Math.sin(dλ), c1 * s2 - s1 * c2 * cosdλ)];
    }
    return [0, 0];
  }
  function chamberlinAngle(b, c, a) {
    return acos(.5 * (b * b + c * c - a * a) / (b * c));
  }
  function chamberlinLongitude(λ) {
    return λ - 2 * π * Math.floor((λ + π) / (2 * π));
  }
  function chamberlinRadians(point) {
    return [point[0] * radians, point[1] * radians];
  }
  (d3.geo.chamberlin = chamberlinProjection).raw = chamberlin;
  function collignon(λ, φ) {
    var α = asqrt(1 - Math.sin(φ));
    return [2 / sqrtπ * λ * α, sqrtπ * (1 - α)];
  }
  collignon.invert = function (x, y) {
    var λ = (λ = y / sqrtπ - 1) * λ;
    return [λ > 0 ? x * Math.sqrt(π / λ) / 2 : 0, asin(1 - λ)];
  };
  (d3.geo.collignon = function () {
    return projection(collignon);
  }).raw = collignon;
  function craig(φ0) {
    var tanφ0 = Math.tan(φ0);
    function forward(λ, φ) {
      return [λ, (λ ? λ / Math.sin(λ) : 1) * (Math.sin(φ) * Math.cos(λ) - tanφ0 * Math.cos(φ))];
    }
    forward.invert = tanφ0 ? function (x, y) {
      if (x) y *= Math.sin(x) / x;
      var cosλ = Math.cos(x);
      return [x, 2 * Math.atan2(Math.sqrt(cosλ * cosλ + tanφ0 * tanφ0 - y * y) - cosλ, tanφ0 - y)];
    } : function (x, y) {
      return [x, asin(x ? y * Math.tan(x) / x : y)];
    };
    return forward;
  }
  (d3.geo.craig = function () {
    return parallel1Projection(craig);
  }).raw = craig;
  function craster(λ, φ) {
    var sqrt3 = Math.sqrt(3);
    return [sqrt3 * λ * (2 * Math.cos(2 * φ / 3) - 1) / sqrtπ, sqrt3 * sqrtπ * Math.sin(φ / 3)];
  }
  craster.invert = function (x, y) {
    var sqrt3 = Math.sqrt(3),
        φ = 3 * asin(y / (sqrt3 * sqrtπ));
    return [sqrtπ * x / (sqrt3 * (2 * Math.cos(2 * φ / 3) - 1)), φ];
  };
  (d3.geo.craster = function () {
    return projection(craster);
  }).raw = craster;
  function cylindricalEqualArea(φ0) {
    var cosφ0 = Math.cos(φ0);
    function forward(λ, φ) {
      return [λ * cosφ0, Math.sin(φ) / cosφ0];
    }
    forward.invert = function (x, y) {
      return [x / cosφ0, asin(y * cosφ0)];
    };
    return forward;
  }
  (d3.geo.cylindricalEqualArea = function () {
    return parallel1Projection(cylindricalEqualArea);
  }).raw = cylindricalEqualArea;
  function cylindricalStereographic(φ0) {
    var cosφ0 = Math.cos(φ0);
    function forward(λ, φ) {
      return [λ * cosφ0, (1 + cosφ0) * Math.tan(φ * .5)];
    }
    forward.invert = function (x, y) {
      return [x / cosφ0, Math.atan(y / (1 + cosφ0)) * 2];
    };
    return forward;
  }
  (d3.geo.cylindricalStereographic = function () {
    return parallel1Projection(cylindricalStereographic);
  }).raw = cylindricalStereographic;
  function eckert1(λ, φ) {
    var α = Math.sqrt(8 / (3 * π));
    return [α * λ * (1 - Math.abs(φ) / π), α * φ];
  }
  eckert1.invert = function (x, y) {
    var α = Math.sqrt(8 / (3 * π)),
        φ = y / α;
    return [x / (α * (1 - Math.abs(φ) / π)), φ];
  };
  (d3.geo.eckert1 = function () {
    return projection(eckert1);
  }).raw = eckert1;
  function eckert2(λ, φ) {
    var α = Math.sqrt(4 - 3 * Math.sin(Math.abs(φ)));
    return [2 / Math.sqrt(6 * π) * λ * α, sgn(φ) * Math.sqrt(2 * π / 3) * (2 - α)];
  }
  eckert2.invert = function (x, y) {
    var α = 2 - Math.abs(y) / Math.sqrt(2 * π / 3);
    return [x * Math.sqrt(6 * π) / (2 * α), sgn(y) * asin((4 - α * α) / 3)];
  };
  (d3.geo.eckert2 = function () {
    return projection(eckert2);
  }).raw = eckert2;
  function eckert3(λ, φ) {
    var k = Math.sqrt(π * (4 + π));
    return [2 / k * λ * (1 + Math.sqrt(1 - 4 * φ * φ / (π * π))), 4 / k * φ];
  }
  eckert3.invert = function (x, y) {
    var k = Math.sqrt(π * (4 + π)) / 2;
    return [x * k / (1 + asqrt(1 - y * y * (4 + π) / (4 * π))), y * k / 2];
  };
  (d3.geo.eckert3 = function () {
    return projection(eckert3);
  }).raw = eckert3;
  function eckert4(λ, φ) {
    var k = (2 + halfπ) * Math.sin(φ);
    φ /= 2;
    for (var i = 0, δ = Infinity; i < 10 && Math.abs(δ) > ε; i++) {
      var cosφ = Math.cos(φ);
      φ -= δ = (φ + Math.sin(φ) * (cosφ + 2) - k) / (2 * cosφ * (1 + cosφ));
    }
    return [2 / Math.sqrt(π * (4 + π)) * λ * (1 + Math.cos(φ)), 2 * Math.sqrt(π / (4 + π)) * Math.sin(φ)];
  }
  eckert4.invert = function (x, y) {
    var A = .5 * y * Math.sqrt((4 + π) / π),
        k = asin(A),
        c = Math.cos(k);
    return [x / (2 / Math.sqrt(π * (4 + π)) * (1 + c)), asin((k + A * (c + 2)) / (2 + halfπ))];
  };
  (d3.geo.eckert4 = function () {
    return projection(eckert4);
  }).raw = eckert4;
  function eckert5(λ, φ) {
    return [λ * (1 + Math.cos(φ)) / Math.sqrt(2 + π), 2 * φ / Math.sqrt(2 + π)];
  }
  eckert5.invert = function (x, y) {
    var k = Math.sqrt(2 + π),
        φ = y * k / 2;
    return [k * x / (1 + Math.cos(φ)), φ];
  };
  (d3.geo.eckert5 = function () {
    return projection(eckert5);
  }).raw = eckert5;
  function eckert6(λ, φ) {
    var k = (1 + halfπ) * Math.sin(φ);
    for (var i = 0, δ = Infinity; i < 10 && Math.abs(δ) > ε; i++) {
      φ -= δ = (φ + Math.sin(φ) - k) / (1 + Math.cos(φ));
    }
    k = Math.sqrt(2 + π);
    return [λ * (1 + Math.cos(φ)) / k, 2 * φ / k];
  }
  eckert6.invert = function (x, y) {
    var j = 1 + halfπ,
        k = Math.sqrt(j / 2);
    return [x * 2 * k / (1 + Math.cos(y *= k)), asin((y + Math.sin(y)) / j)];
  };
  (d3.geo.eckert6 = function () {
    return projection(eckert6);
  }).raw = eckert6;
  function eisenlohr(λ, φ) {
    var s0 = Math.sin(λ /= 2),
        c0 = Math.cos(λ),
        k = Math.sqrt(Math.cos(φ)),
        c1 = Math.cos(φ /= 2),
        t = Math.sin(φ) / (c1 + Math.SQRT2 * c0 * k),
        c = Math.sqrt(2 / (1 + t * t)),
        v = Math.sqrt((Math.SQRT2 * c1 + (c0 + s0) * k) / (Math.SQRT2 * c1 + (c0 - s0) * k));
    return [eisenlohrK * (c * (v - 1 / v) - 2 * Math.log(v)), eisenlohrK * (c * t * (v + 1 / v) - 2 * Math.atan(t))];
  }
  eisenlohr.invert = function (x, y) {
    var p = d3.geo.august.raw.invert(x / 1.2, y * 1.065);
    if (!p) return null;
    var λ = p[0],
        φ = p[1],
        i = 20;
    x /= eisenlohrK, y /= eisenlohrK;
    do {
      var _0 = λ / 2,
          _1 = φ / 2,
          s0 = Math.sin(_0),
          c0 = Math.cos(_0),
          s1 = Math.sin(_1),
          c1 = Math.cos(_1),
          cos1 = Math.cos(φ),
          k = Math.sqrt(cos1),
          t = s1 / (c1 + Math.SQRT2 * c0 * k),
          t2 = t * t,
          c = Math.sqrt(2 / (1 + t2)),
          v0 = Math.SQRT2 * c1 + (c0 + s0) * k,
          v1 = Math.SQRT2 * c1 + (c0 - s0) * k,
          v2 = v0 / v1,
          v = Math.sqrt(v2),
          vm1v = v - 1 / v,
          vp1v = v + 1 / v,
          fx = c * vm1v - 2 * Math.log(v) - x,
          fy = c * t * vp1v - 2 * Math.atan(t) - y,
          δtδλ = s1 && Math.SQRT1_2 * k * s0 * t2 / s1,
          δtδφ = (Math.SQRT2 * c0 * c1 + k) / (2 * (c1 + Math.SQRT2 * c0 * k) * (c1 + Math.SQRT2 * c0 * k) * k),
          δcδt = -.5 * t * c * c * c,
          δcδλ = δcδt * δtδλ,
          δcδφ = δcδt * δtδφ,
          A = (A = 2 * c1 + Math.SQRT2 * k * (c0 - s0)) * A * v,
          δvδλ = (Math.SQRT2 * c0 * c1 * k + cos1) / A,
          δvδφ = -(Math.SQRT2 * s0 * s1) / (k * A),
          δxδλ = vm1v * δcδλ - 2 * δvδλ / v + c * (δvδλ + δvδλ / v2),
          δxδφ = vm1v * δcδφ - 2 * δvδφ / v + c * (δvδφ + δvδφ / v2),
          δyδλ = t * vp1v * δcδλ - 2 * δtδλ / (1 + t2) + c * vp1v * δtδλ + c * t * (δvδλ - δvδλ / v2),
          δyδφ = t * vp1v * δcδφ - 2 * δtδφ / (1 + t2) + c * vp1v * δtδφ + c * t * (δvδφ - δvδφ / v2),
          denominator = δxδφ * δyδλ - δyδφ * δxδλ;
      if (!denominator) break;
      var δλ = (fy * δxδφ - fx * δyδφ) / denominator,
          δφ = (fx * δyδλ - fy * δxδλ) / denominator;
      λ -= δλ;
      φ = Math.max(-halfπ, Math.min(halfπ, φ - δφ));
    } while ((Math.abs(δλ) > ε || Math.abs(δφ) > ε) && --i > 0);
    return Math.abs(Math.abs(φ) - halfπ) < ε ? [0, φ] : i && [λ, φ];
  };
  var eisenlohrK = 3 + 2 * Math.SQRT2;
  (d3.geo.eisenlohr = function () {
    return projection(eisenlohr);
  }).raw = eisenlohr;
  function fahey(λ, φ) {
    var t = Math.tan(φ / 2);
    return [λ * faheyK * asqrt(1 - t * t), (1 + faheyK) * t];
  }
  fahey.invert = function (x, y) {
    var t = y / (1 + faheyK);
    return [x ? x / (faheyK * asqrt(1 - t * t)) : 0, 2 * Math.atan(t)];
  };
  var faheyK = Math.cos(35 * radians);
  (d3.geo.fahey = function () {
    return projection(fahey);
  }).raw = fahey;
  function foucaut(λ, φ) {
    var k = φ / 2,
        cosk = Math.cos(k);
    return [2 * λ / sqrtπ * Math.cos(φ) * cosk * cosk, sqrtπ * Math.tan(k)];
  }
  foucaut.invert = function (x, y) {
    var k = Math.atan(y / sqrtπ),
        cosk = Math.cos(k),
        φ = 2 * k;
    return [x * sqrtπ * .5 / (Math.cos(φ) * cosk * cosk), φ];
  };
  (d3.geo.foucaut = function () {
    return projection(foucaut);
  }).raw = foucaut;
  d3.geo.gilbert = function (projection) {
    var e = d3.geo.equirectangular().scale(degrees).translate([0, 0]);
    function gilbert(coordinates) {
      return projection([coordinates[0] * .5, asin(Math.tan(coordinates[1] * .5 * radians)) * degrees]);
    }
    if (projection.invert) gilbert.invert = function (coordinates) {
      coordinates = projection.invert(coordinates);
      coordinates[0] *= 2;
      coordinates[1] = 2 * Math.atan(Math.sin(coordinates[1] * radians)) * degrees;
      return coordinates;
    };
    gilbert.stream = function (stream) {
      stream = projection.stream(stream);
      var s = e.stream({
        point: function point(λ, φ) {
          stream.point(λ * .5, asin(Math.tan(-φ * .5 * radians)) * degrees);
        },
        lineStart: function lineStart() {
          stream.lineStart();
        },
        lineEnd: function lineEnd() {
          stream.lineEnd();
        },
        polygonStart: function polygonStart() {
          stream.polygonStart();
        },
        polygonEnd: function polygonEnd() {
          stream.polygonEnd();
        }
      });
      s.sphere = function () {
        stream.sphere();
      };
      s.valid = false;
      return s;
    };
    return gilbert;
  };
  var gingeryAzimuthalEquidistant = d3.geo.azimuthalEquidistant.raw;
  function gingery(ρ, n) {
    var k = 2 * π / n,
        ρ2 = ρ * ρ;
    function forward(λ, φ) {
      var p = gingeryAzimuthalEquidistant(λ, φ),
          x = p[0],
          y = p[1],
          r2 = x * x + y * y;
      if (r2 > ρ2) {
        var r = Math.sqrt(r2),
            θ = Math.atan2(y, x),
            θ0 = k * Math.round(θ / k),
            α = θ - θ0,
            ρcosα = ρ * Math.cos(α),
            k_ = (ρ * Math.sin(α) - α * Math.sin(ρcosα)) / (halfπ - ρcosα),
            s_ = arcLength_(α, k_),
            e = (π - ρ) / gingeryIntegrate(s_, ρcosα, π);
        x = r;
        var i = 50,
            δ;
        do {
          x -= δ = (ρ + gingeryIntegrate(s_, ρcosα, x) * e - r) / (s_(x) * e);
        } while (Math.abs(δ) > ε && --i > 0);
        y = α * Math.sin(x);
        if (x < halfπ) y -= k_ * (x - halfπ);
        var s = Math.sin(θ0),
            c = Math.cos(θ0);
        p[0] = x * c - y * s;
        p[1] = x * s + y * c;
      }
      return p;
    }
    forward.invert = function (x, y) {
      var r2 = x * x + y * y;
      if (r2 > ρ2) {
        var r = Math.sqrt(r2),
            θ = Math.atan2(y, x),
            θ0 = k * Math.round(θ / k),
            dθ = θ - θ0,
            x = r * Math.cos(dθ);
        y = r * Math.sin(dθ);
        var x_halfπ = x - halfπ,
            sinx = Math.sin(x),
            α = y / sinx,
            δ = x < halfπ ? Infinity : 0,
            i = 10;
        while (true) {
          var ρsinα = ρ * Math.sin(α),
              ρcosα = ρ * Math.cos(α),
              sinρcosα = Math.sin(ρcosα),
              halfπ_ρcosα = halfπ - ρcosα,
              k_ = (ρsinα - α * sinρcosα) / halfπ_ρcosα,
              s_ = arcLength_(α, k_);
          if (Math.abs(δ) < ε2 || ! --i) break;
          α -= δ = (α * sinx - k_ * x_halfπ - y) / (sinx - x_halfπ * 2 * (halfπ_ρcosα * (ρcosα + α * ρsinα * Math.cos(ρcosα) - sinρcosα) - ρsinα * (ρsinα - α * sinρcosα)) / (halfπ_ρcosα * halfπ_ρcosα));
        }
        r = ρ + gingeryIntegrate(s_, ρcosα, x) * (π - ρ) / gingeryIntegrate(s_, ρcosα, π);
        θ = θ0 + α;
        x = r * Math.cos(θ);
        y = r * Math.sin(θ);
      }
      return gingeryAzimuthalEquidistant.invert(x, y);
    };
    return forward;
  }
  function arcLength_(α, k) {
    return function (x) {
      var y_ = α * Math.cos(x);
      if (x < halfπ) y_ -= k;
      return Math.sqrt(1 + y_ * y_);
    };
  }
  function gingeryProjection() {
    var n = 6,
        ρ = 30 * radians,
        cρ = Math.cos(ρ),
        sρ = Math.sin(ρ),
        m = projectionMutator(gingery),
        p = m(ρ, n),
        stream_ = p.stream,
        ε = .01,
        cr = -Math.cos(ε * radians),
        sr = Math.sin(ε * radians);
    p.radius = function (_) {
      if (!arguments.length) return ρ * degrees;
      cρ = Math.cos(ρ = _ * radians);
      sρ = Math.sin(ρ);
      return m(ρ, n);
    };
    p.lobes = function (_) {
      if (!arguments.length) return n;
      return m(ρ, n = +_);
    };
    p.stream = function (stream) {
      var rotate = p.rotate(),
          rotateStream = stream_(stream),
          sphereStream = (p.rotate([0, 0]), stream_(stream));
      p.rotate(rotate);
      rotateStream.sphere = function () {
        sphereStream.polygonStart(), sphereStream.lineStart();
        for (var i = 0, δ = 2 * π / n, φ = 0; i < n; ++i, φ -= δ) {
          sphereStream.point(Math.atan2(sr * Math.cos(φ), cr) * degrees, Math.asin(sr * Math.sin(φ)) * degrees);
          sphereStream.point(Math.atan2(sρ * Math.cos(φ - δ / 2), cρ) * degrees, Math.asin(sρ * Math.sin(φ - δ / 2)) * degrees);
        }
        sphereStream.lineEnd(), sphereStream.polygonEnd();
      };
      return rotateStream;
    };
    return p;
  }
  function gingeryIntegrate(f, a, b) {
    var n = 50,
        h = (b - a) / n,
        s = f(a) + f(b);
    for (var i = 1, x = a; i < n; ++i) {
      s += 2 * f(x += h);
    }return s * .5 * h;
  }
  (d3.geo.gingery = gingeryProjection).raw = gingery;
  function ginzburgPolyconic(a, b, c, d, e, f, g, h) {
    if (arguments.length < 8) h = 0;
    function forward(λ, φ) {
      if (!φ) return [a * λ / π, 0];
      var φ2 = φ * φ,
          xB = a + φ2 * (b + φ2 * (c + φ2 * d)),
          yB = φ * (e - 1 + φ2 * (f - h + φ2 * g)),
          m = (xB * xB + yB * yB) / (2 * yB),
          α = λ * Math.asin(xB / m) / π;
      return [m * Math.sin(α), φ * (1 + φ2 * h) + m * (1 - Math.cos(α))];
    }
    forward.invert = function (x, y) {
      var λ = π * x / a,
          φ = y,
          δλ,
          δφ,
          i = 50;
      do {
        var φ2 = φ * φ,
            xB = a + φ2 * (b + φ2 * (c + φ2 * d)),
            yB = φ * (e - 1 + φ2 * (f - h + φ2 * g)),
            p = xB * xB + yB * yB,
            q = 2 * yB,
            m = p / q,
            m2 = m * m,
            dαdλ = Math.asin(xB / m) / π,
            α = λ * dαdλ;
        xB2 = xB * xB, dxBdφ = (2 * b + φ2 * (4 * c + φ2 * 6 * d)) * φ, dyBdφ = e + φ2 * (3 * f + φ2 * 5 * g), dpdφ = 2 * (xB * dxBdφ + yB * (dyBdφ - 1)), dqdφ = 2 * (dyBdφ - 1), dmdφ = (dpdφ * q - p * dqdφ) / (q * q), cosα = Math.cos(α), sinα = Math.sin(α), mcosα = m * cosα, msinα = m * sinα, dαdφ = λ / π * (1 / asqrt(1 - xB2 / m2)) * (dxBdφ * m - xB * dmdφ) / m2, fx = msinα - x, fy = φ * (1 + φ2 * h) + m - mcosα - y, δxδφ = dmdφ * sinα + mcosα * dαdφ, δxδλ = mcosα * dαdλ, δyδφ = 1 + dmdφ - (dmdφ * cosα - msinα * dαdφ), δyδλ = msinα * dαdλ, denominator = δxδφ * δyδλ - δyδφ * δxδλ;
        if (!denominator) break;
        λ -= δλ = (fy * δxδφ - fx * δyδφ) / denominator;
        φ -= δφ = (fx * δyδλ - fy * δxδλ) / denominator;
      } while ((Math.abs(δλ) > ε || Math.abs(δφ) > ε) && --i > 0);
      return [λ, φ];
    };
    return forward;
  }
  var ginzburg4 = ginzburgPolyconic(2.8284, -1.6988, .75432, -.18071, 1.76003, -.38914, .042555);
  (d3.geo.ginzburg4 = function () {
    return projection(ginzburg4);
  }).raw = ginzburg4;
  var ginzburg5 = ginzburgPolyconic(2.583819, -.835827, .170354, -.038094, 1.543313, -.411435, .082742);
  (d3.geo.ginzburg5 = function () {
    return projection(ginzburg5);
  }).raw = ginzburg5;
  var ginzburg6 = ginzburgPolyconic(5 / 6 * π, -.62636, -.0344, 0, 1.3493, -.05524, 0, .045);
  (d3.geo.ginzburg6 = function () {
    return projection(ginzburg6);
  }).raw = ginzburg6;
  function ginzburg8(λ, φ) {
    var λ2 = λ * λ,
        φ2 = φ * φ;
    return [λ * (1 - .162388 * φ2) * (.87 - 952426e-9 * λ2 * λ2), φ * (1 + φ2 / 12)];
  }
  ginzburg8.invert = function (x, y) {
    var λ = x,
        φ = y,
        i = 50,
        δ;
    do {
      var φ2 = φ * φ;
      φ -= δ = (φ * (1 + φ2 / 12) - y) / (1 + φ2 / 4);
    } while (Math.abs(δ) > ε && --i > 0);
    i = 50;
    x /= 1 - .162388 * φ2;
    do {
      var λ4 = (λ4 = λ * λ) * λ4;
      λ -= δ = (λ * (.87 - 952426e-9 * λ4) - x) / (.87 - .00476213 * λ4);
    } while (Math.abs(δ) > ε && --i > 0);
    return [λ, φ];
  };
  (d3.geo.ginzburg8 = function () {
    return projection(ginzburg8);
  }).raw = ginzburg8;
  var ginzburg9 = ginzburgPolyconic(2.6516, -.76534, .19123, -.047094, 1.36289, -.13965, .031762);
  (d3.geo.ginzburg9 = function () {
    return projection(ginzburg9);
  }).raw = ginzburg9;
  function quincuncialProjection(projectHemisphere) {
    var dx = projectHemisphere(halfπ, 0)[0] - projectHemisphere(-halfπ, 0)[0];
    function projection() {
      var quincuncial = false,
          m = projectionMutator(projectAt),
          p = m(quincuncial);
      p.quincuncial = function (_) {
        if (!arguments.length) return quincuncial;
        return m(quincuncial = !!_);
      };
      return p;
    }
    function projectAt(quincuncial) {
      var forward = quincuncial ? function (λ, φ) {
        var t = Math.abs(λ) < halfπ,
            p = projectHemisphere(t ? λ : λ > 0 ? λ - π : λ + π, φ);
        var x = (p[0] - p[1]) * Math.SQRT1_2,
            y = (p[0] + p[1]) * Math.SQRT1_2;
        if (t) return [x, y];
        var d = dx * Math.SQRT1_2,
            s = x > 0 ^ y > 0 ? -1 : 1;
        return [s * x - sgn(y) * d, s * y - sgn(x) * d];
      } : function (λ, φ) {
        var s = λ > 0 ? -.5 : .5,
            point = projectHemisphere(λ + s * π, φ);
        point[0] -= s * dx;
        return point;
      };
      if (projectHemisphere.invert) forward.invert = quincuncial ? function (x0, y0) {
        var x = (x0 + y0) * Math.SQRT1_2,
            y = (y0 - x0) * Math.SQRT1_2,
            t = Math.abs(x) < .5 * dx && Math.abs(y) < .5 * dx;
        if (!t) {
          var d = dx * Math.SQRT1_2,
              s = x > 0 ^ y > 0 ? -1 : 1,
              x1 = -s * (x0 + (y > 0 ? 1 : -1) * d),
              y1 = -s * (y0 + (x > 0 ? 1 : -1) * d);
          x = (-x1 - y1) * Math.SQRT1_2;
          y = (x1 - y1) * Math.SQRT1_2;
        }
        var p = projectHemisphere.invert(x, y);
        if (!t) p[0] += x > 0 ? π : -π;
        return p;
      } : function (x, y) {
        var s = x > 0 ? -.5 : .5,
            location = projectHemisphere.invert(x + s * dx, y),
            λ = location[0] - s * π;
        if (λ < -π) λ += 2 * π;else if (λ > π) λ -= 2 * π;
        location[0] = λ;
        return location;
      };
      return forward;
    }
    projection.raw = projectAt;
    return projection;
  }
  function gringorten(λ, φ) {
    var sλ = sgn(λ),
        sφ = sgn(φ),
        cosφ = Math.cos(φ),
        x = Math.cos(λ) * cosφ,
        y = Math.sin(λ) * cosφ,
        z = Math.sin(sφ * φ);
    λ = Math.abs(Math.atan2(y, z));
    φ = asin(x);
    if (Math.abs(λ - halfπ) > ε) λ %= halfπ;
    var point = gringortenHexadecant(λ > π / 4 ? halfπ - λ : λ, φ);
    if (λ > π / 4) z = point[0], point[0] = -point[1], point[1] = -z;
    return point[0] *= sλ, point[1] *= -sφ, point;
  }
  gringorten.invert = function (x, y) {
    var sx = sgn(x),
        sy = sgn(y),
        x0 = -sx * x,
        y0 = -sy * y,
        t = y0 / x0 < 1,
        p = gringortenHexadecantInvert(t ? y0 : x0, t ? x0 : y0),
        λ = p[0],
        φ = p[1];
    if (t) λ = -halfπ - λ;
    var cosφ = Math.cos(φ),
        x = Math.cos(λ) * cosφ,
        y = Math.sin(λ) * cosφ,
        z = Math.sin(φ);
    return [sx * (Math.atan2(y, -z) + π), sy * asin(x)];
  };
  function gringortenHexadecant(λ, φ) {
    if (φ === halfπ) return [0, 0];
    var sinφ = Math.sin(φ),
        r = sinφ * sinφ,
        r2 = r * r,
        j = 1 + r2,
        k = 1 + 3 * r2,
        q = 1 - r2,
        z = asin(1 / Math.sqrt(j)),
        v = q + r * j * z,
        p2 = (1 - sinφ) / v,
        p = Math.sqrt(p2),
        a2 = p2 * j,
        a = Math.sqrt(a2),
        h = p * q;
    if (λ === 0) return [0, -(h + r * a)];
    var cosφ = Math.cos(φ),
        secφ = 1 / cosφ,
        drdφ = 2 * sinφ * cosφ,
        dvdφ = (-3 * r + z * k) * drdφ,
        dp2dφ = (-v * cosφ - (1 - sinφ) * dvdφ) / (v * v),
        dpdφ = .5 * dp2dφ / p,
        dhdφ = q * dpdφ - 2 * r * p * drdφ,
        dra2dφ = r * j * dp2dφ + p2 * k * drdφ,
        μ = -secφ * drdφ,
        ν = -secφ * dra2dφ,
        ζ = -2 * secφ * dhdφ,
        Λ = 4 * λ / π;
    if (λ > .222 * π || φ < π / 4 && λ > .175 * π) {
      var x = (h + r * asqrt(a2 * (1 + r2) - h * h)) / (1 + r2);
      if (λ > π / 4) return [x, x];
      var x1 = x,
          x0 = .5 * x,
          i = 50;
      x = .5 * (x0 + x1);
      do {
        var g = Math.sqrt(a2 - x * x),
            f = x * (ζ + μ * g) + ν * asin(x / a) - Λ;
        if (!f) break;
        if (f < 0) x0 = x;else x1 = x;
        x = .5 * (x0 + x1);
      } while (Math.abs(x1 - x0) > ε && --i > 0);
    } else {
      var x = ε,
          i = 25,
          δ;
      do {
        var x2 = x * x,
            g = asqrt(a2 - x2),
            ζμg = ζ + μ * g,
            f = x * ζμg + ν * asin(x / a) - Λ,
            df = ζμg + (ν - μ * x2) / g;
        x -= δ = g ? f / df : 0;
      } while (Math.abs(δ) > ε && --i > 0);
    }
    return [x, -h - r * asqrt(a2 - x * x)];
  }
  function gringortenHexadecantInvert(x, y) {
    var x0 = 0,
        x1 = 1,
        r = .5,
        i = 50;
    while (true) {
      var r2 = r * r,
          sinφ = Math.sqrt(r),
          z = Math.asin(1 / Math.sqrt(1 + r2)),
          v = 1 - r2 + r * (1 + r2) * z,
          p2 = (1 - sinφ) / v,
          p = Math.sqrt(p2),
          a2 = p2 * (1 + r2),
          h = p * (1 - r2),
          g2 = a2 - x * x,
          g = Math.sqrt(g2),
          y0 = y + h + r * g;
      if (Math.abs(x1 - x0) < ε2 || --i === 0 || y0 === 0) break;
      if (y0 > 0) x0 = r;else x1 = r;
      r = .5 * (x0 + x1);
    }
    if (!i) return null;
    var φ = Math.asin(sinφ),
        cosφ = Math.cos(φ),
        secφ = 1 / cosφ,
        drdφ = 2 * sinφ * cosφ,
        dvdφ = (-3 * r + z * (1 + 3 * r2)) * drdφ,
        dp2dφ = (-v * cosφ - (1 - sinφ) * dvdφ) / (v * v),
        dpdφ = .5 * dp2dφ / p,
        dhdφ = (1 - r2) * dpdφ - 2 * r * p * drdφ,
        ζ = -2 * secφ * dhdφ,
        μ = -secφ * drdφ,
        ν = -secφ * (r * (1 + r2) * dp2dφ + p2 * (1 + 3 * r2) * drdφ);
    return [π / 4 * (x * (ζ + μ * g) + ν * Math.asin(x / Math.sqrt(a2))), φ];
  }
  d3.geo.gringorten = quincuncialProjection(gringorten);
  function ellipticJi(u, v, m) {
    if (!u) {
      var b = ellipticJ(v, 1 - m);
      return [[0, b[0] / b[1]], [1 / b[1], 0], [b[2] / b[1], 0]];
    }
    var a = ellipticJ(u, m);
    if (!v) return [[a[0], 0], [a[1], 0], [a[2], 0]];
    var b = ellipticJ(v, 1 - m),
        denominator = b[1] * b[1] + m * a[0] * a[0] * b[0] * b[0];
    return [[a[0] * b[2] / denominator, a[1] * a[2] * b[0] * b[1] / denominator], [a[1] * b[1] / denominator, -a[0] * a[2] * b[0] * b[2] / denominator], [a[2] * b[1] * b[2] / denominator, -m * a[0] * a[1] * b[0] / denominator]];
  }
  function ellipticJ(u, m) {
    var ai, b, φ, t, twon;
    if (m < ε) {
      t = Math.sin(u);
      b = Math.cos(u);
      ai = .25 * m * (u - t * b);
      return [t - ai * b, b + ai * t, 1 - .5 * m * t * t, u - ai];
    }
    if (m >= 1 - ε) {
      ai = .25 * (1 - m);
      b = cosh(u);
      t = tanh(u);
      φ = 1 / b;
      twon = b * sinh(u);
      return [t + ai * (twon - u) / (b * b), φ - ai * t * φ * (twon - u), φ + ai * t * φ * (twon + u), 2 * Math.atan(Math.exp(u)) - halfπ + ai * (twon - u) / b];
    }
    var a = [1, 0, 0, 0, 0, 0, 0, 0, 0],
        c = [Math.sqrt(m), 0, 0, 0, 0, 0, 0, 0, 0],
        i = 0;
    b = Math.sqrt(1 - m);
    twon = 1;
    while (Math.abs(c[i] / a[i]) > ε && i < 8) {
      ai = a[i++];
      c[i] = .5 * (ai - b);
      a[i] = .5 * (ai + b);
      b = asqrt(ai * b);
      twon *= 2;
    }
    φ = twon * a[i] * u;
    do {
      t = c[i] * Math.sin(b = φ) / a[i];
      φ = .5 * (asin(t) + φ);
    } while (--i);
    return [Math.sin(φ), t = Math.cos(φ), t / Math.cos(φ - b), φ];
  }
  function ellipticFi(φ, ψ, m) {
    var r = Math.abs(φ),
        i = Math.abs(ψ),
        sinhψ = sinh(i);
    if (r) {
      var cscφ = 1 / Math.sin(r),
          cotφ2 = 1 / (Math.tan(r) * Math.tan(r)),
          b = -(cotφ2 + m * sinhψ * sinhψ * cscφ * cscφ - 1 + m),
          c = (m - 1) * cotφ2,
          cotλ2 = .5 * (-b + Math.sqrt(b * b - 4 * c));
      return [ellipticF(Math.atan(1 / Math.sqrt(cotλ2)), m) * sgn(φ), ellipticF(Math.atan(asqrt((cotλ2 / cotφ2 - 1) / m)), 1 - m) * sgn(ψ)];
    }
    return [0, ellipticF(Math.atan(sinhψ), 1 - m) * sgn(ψ)];
  }
  function ellipticF(φ, m) {
    if (!m) return φ;
    if (m === 1) return Math.log(Math.tan(φ / 2 + π / 4));
    var a = 1,
        b = Math.sqrt(1 - m),
        c = Math.sqrt(m);
    for (var i = 0; Math.abs(c) > ε; i++) {
      if (φ % π) {
        var dφ = Math.atan(b * Math.tan(φ) / a);
        if (dφ < 0) dφ += π;
        φ += dφ + ~~(φ / π) * π;
      } else φ += φ;
      c = (a + b) / 2;
      b = Math.sqrt(a * b);
      c = ((a = c) - b) / 2;
    }
    return φ / (Math.pow(2, i) * a);
  }
  function guyou(λ, φ) {
    var k_ = (Math.SQRT2 - 1) / (Math.SQRT2 + 1),
        k = Math.sqrt(1 - k_ * k_),
        K = ellipticF(halfπ, k * k),
        f = -1;
    var ψ = Math.log(Math.tan(π / 4 + Math.abs(φ) / 2)),
        r = Math.exp(f * ψ) / Math.sqrt(k_),
        at = guyouComplexAtan(r * Math.cos(f * λ), r * Math.sin(f * λ)),
        t = ellipticFi(at[0], at[1], k * k);
    return [-t[1], (φ >= 0 ? 1 : -1) * (.5 * K - t[0])];
  }
  function guyouComplexAtan(x, y) {
    var x2 = x * x,
        y_1 = y + 1,
        t = 1 - x2 - y * y;
    return [.5 * ((x >= 0 ? halfπ : -halfπ) - Math.atan2(t, 2 * x)), -.25 * Math.log(t * t + 4 * x2) + .5 * Math.log(y_1 * y_1 + x2)];
  }
  function guyouComplexDivide(a, b) {
    var denominator = b[0] * b[0] + b[1] * b[1];
    return [(a[0] * b[0] + a[1] * b[1]) / denominator, (a[1] * b[0] - a[0] * b[1]) / denominator];
  }
  guyou.invert = function (x, y) {
    var k_ = (Math.SQRT2 - 1) / (Math.SQRT2 + 1),
        k = Math.sqrt(1 - k_ * k_),
        K = ellipticF(halfπ, k * k),
        f = -1;
    var j = ellipticJi(.5 * K - y, -x, k * k),
        tn = guyouComplexDivide(j[0], j[1]),
        λ = Math.atan2(tn[1], tn[0]) / f;
    return [λ, 2 * Math.atan(Math.exp(.5 / f * Math.log(k_ * tn[0] * tn[0] + k_ * tn[1] * tn[1]))) - halfπ];
  };
  d3.geo.guyou = quincuncialProjection(guyou);
  function hammerRetroazimuthal(φ0) {
    var sinφ0 = Math.sin(φ0),
        cosφ0 = Math.cos(φ0),
        rotate = hammerRetroazimuthalRotation(φ0);
    rotate.invert = hammerRetroazimuthalRotation(-φ0);
    function forward(λ, φ) {
      var p = rotate(λ, φ);
      λ = p[0], φ = p[1];
      var sinφ = Math.sin(φ),
          cosφ = Math.cos(φ),
          cosλ = Math.cos(λ),
          z = acos(sinφ0 * sinφ + cosφ0 * cosφ * cosλ),
          sinz = Math.sin(z),
          K = Math.abs(sinz) > ε ? z / sinz : 1;
      return [K * cosφ0 * Math.sin(λ), (Math.abs(λ) > halfπ ? K : -K) * (sinφ0 * cosφ - cosφ0 * sinφ * cosλ)];
    }
    forward.invert = function (x, y) {
      var ρ = Math.sqrt(x * x + y * y),
          sinz = -Math.sin(ρ),
          cosz = Math.cos(ρ),
          a = ρ * cosz,
          b = -y * sinz,
          c = ρ * sinφ0,
          d = asqrt(a * a + b * b - c * c),
          φ = Math.atan2(a * c + b * d, b * c - a * d),
          λ = (ρ > halfπ ? -1 : 1) * Math.atan2(x * sinz, ρ * Math.cos(φ) * cosz + y * Math.sin(φ) * sinz);
      return rotate.invert(λ, φ);
    };
    return forward;
  }
  function hammerRetroazimuthalRotation(φ0) {
    var sinφ0 = Math.sin(φ0),
        cosφ0 = Math.cos(φ0);
    return function (λ, φ) {
      var cosφ = Math.cos(φ),
          x = Math.cos(λ) * cosφ,
          y = Math.sin(λ) * cosφ,
          z = Math.sin(φ);
      return [Math.atan2(y, x * cosφ0 - z * sinφ0), asin(z * cosφ0 + x * sinφ0)];
    };
  }
  function hammerRetroazimuthalProjection() {
    var φ0 = 0,
        m = projectionMutator(hammerRetroazimuthal),
        p = m(φ0),
        rotate_ = p.rotate,
        stream_ = p.stream,
        circle = d3.geo.circle();
    p.parallel = function (_) {
      if (!arguments.length) return φ0 / π * 180;
      var r = p.rotate();
      return m(φ0 = _ * π / 180).rotate(r);
    };
    p.rotate = function (_) {
      if (!arguments.length) return _ = rotate_.call(p), _[1] += φ0 / π * 180, _;
      rotate_.call(p, [_[0], _[1] - φ0 / π * 180]);
      circle.origin([-_[0], -_[1]]);
      return p;
    };
    p.stream = function (stream) {
      stream = stream_(stream);
      stream.sphere = function () {
        stream.polygonStart();
        var ε = .01,
            ring = circle.angle(90 - ε)().coordinates[0],
            n = ring.length - 1,
            i = -1,
            p;
        stream.lineStart();
        while (++i < n) {
          stream.point((p = ring[i])[0], p[1]);
        }stream.lineEnd();
        ring = circle.angle(90 + ε)().coordinates[0];
        n = ring.length - 1;
        stream.lineStart();
        while (--i >= 0) {
          stream.point((p = ring[i])[0], p[1]);
        }stream.lineEnd();
        stream.polygonEnd();
      };
      return stream;
    };
    return p;
  }
  (d3.geo.hammerRetroazimuthal = hammerRetroazimuthalProjection).raw = hammerRetroazimuthal;
  var hammerAzimuthalEqualArea = d3.geo.azimuthalEqualArea.raw;
  function hammer(A, B) {
    if (arguments.length < 2) B = A;
    if (B === 1) return hammerAzimuthalEqualArea;
    if (B === Infinity) return hammerQuarticAuthalic;
    function forward(λ, φ) {
      var coordinates = hammerAzimuthalEqualArea(λ / B, φ);
      coordinates[0] *= A;
      return coordinates;
    }
    forward.invert = function (x, y) {
      var coordinates = hammerAzimuthalEqualArea.invert(x / A, y);
      coordinates[0] *= B;
      return coordinates;
    };
    return forward;
  }
  function hammerProjection() {
    var B = 2,
        m = projectionMutator(hammer),
        p = m(B);
    p.coefficient = function (_) {
      if (!arguments.length) return B;
      return m(B = +_);
    };
    return p;
  }
  function hammerQuarticAuthalic(λ, φ) {
    return [λ * Math.cos(φ) / Math.cos(φ /= 2), 2 * Math.sin(φ)];
  }
  hammerQuarticAuthalic.invert = function (x, y) {
    var φ = 2 * asin(y / 2);
    return [x * Math.cos(φ / 2) / Math.cos(φ), φ];
  };
  (d3.geo.hammer = hammerProjection).raw = hammer;
  function hatano(λ, φ) {
    var c = Math.sin(φ) * (φ < 0 ? 2.43763 : 2.67595);
    for (var i = 0, δ; i < 20; i++) {
      φ -= δ = (φ + Math.sin(φ) - c) / (1 + Math.cos(φ));
      if (Math.abs(δ) < ε) break;
    }
    return [.85 * λ * Math.cos(φ *= .5), Math.sin(φ) * (φ < 0 ? 1.93052 : 1.75859)];
  }
  hatano.invert = function (x, y) {
    var θ = Math.abs(θ = y * (y < 0 ? .5179951515653813 : .5686373742600607)) > 1 - ε ? θ > 0 ? halfπ : -halfπ : asin(θ);
    return [1.1764705882352942 * x / Math.cos(θ), Math.abs(θ = ((θ += θ) + Math.sin(θ)) * (y < 0 ? .4102345310814193 : .3736990601468637)) > 1 - ε ? θ > 0 ? halfπ : -halfπ : asin(θ)];
  };
  (d3.geo.hatano = function () {
    return projection(hatano);
  }).raw = hatano;
  var healpixParallel = 41 + 48 / 36 + 37 / 3600;
  function healpix(h) {
    var lambert = d3.geo.cylindricalEqualArea.raw(0),
        φ0 = healpixParallel * π / 180,
        dx0 = 2 * π,
        dx1 = d3.geo.collignon.raw(π, φ0)[0] - d3.geo.collignon.raw(-π, φ0)[0],
        y0 = lambert(0, φ0)[1],
        y1 = d3.geo.collignon.raw(0, φ0)[1],
        dy1 = d3.geo.collignon.raw(0, halfπ)[1] - y1,
        k = 2 * π / h;
    function forward(λ, φ) {
      var point,
          φ2 = Math.abs(φ);
      if (φ2 > φ0) {
        var i = Math.min(h - 1, Math.max(0, Math.floor((λ + π) / k)));
        λ += π * (h - 1) / h - i * k;
        point = d3.geo.collignon.raw(λ, φ2);
        point[0] = point[0] * dx0 / dx1 - dx0 * (h - 1) / (2 * h) + i * dx0 / h;
        point[1] = y0 + (point[1] - y1) * 4 * dy1 / dx0;
        if (φ < 0) point[1] = -point[1];
      } else {
        point = lambert(λ, φ);
      }
      point[0] /= 2;
      return point;
    }
    forward.invert = function (x, y) {
      x *= 2;
      var y2 = Math.abs(y);
      if (y2 > y0) {
        var i = Math.min(h - 1, Math.max(0, Math.floor((x + π) / k)));
        x = (x + π * (h - 1) / h - i * k) * dx1 / dx0;
        var point = d3.geo.collignon.raw.invert(x, .25 * (y2 - y0) * dx0 / dy1 + y1);
        point[0] -= π * (h - 1) / h - i * k;
        if (y < 0) point[1] = -point[1];
        return point;
      }
      return lambert.invert(x, y);
    };
    return forward;
  }
  function healpixProjection() {
    var n = 2,
        m = projectionMutator(healpix),
        p = m(n),
        stream_ = p.stream;
    p.lobes = function (_) {
      if (!arguments.length) return n;
      return m(n = +_);
    };
    p.stream = function (stream) {
      var rotate = p.rotate(),
          rotateStream = stream_(stream),
          sphereStream = (p.rotate([0, 0]), stream_(stream));
      p.rotate(rotate);
      rotateStream.sphere = function () {
        d3.geo.stream(sphere(), sphereStream);
      };
      return rotateStream;
    };
    function sphere() {
      var step = 180 / n;
      return {
        type: "Polygon",
        coordinates: [d3.range(-180, 180 + step / 2, step).map(function (x, i) {
          return [x, i & 1 ? 90 - 1e-6 : healpixParallel];
        }).concat(d3.range(180, -180 - step / 2, -step).map(function (x, i) {
          return [x, i & 1 ? -90 + 1e-6 : -healpixParallel];
        }))]
      };
    }
    return p;
  }
  (d3.geo.healpix = healpixProjection).raw = healpix;
  function hill(K) {
    var L = 1 + K,
        sinβ = Math.sin(1 / L),
        β = asin(sinβ),
        A = 2 * Math.sqrt(π / (B = π + 4 * β * L)),
        B,
        ρ0 = .5 * A * (L + Math.sqrt(K * (2 + K))),
        K2 = K * K,
        L2 = L * L;
    function forward(λ, φ) {
      var t = 1 - Math.sin(φ),
          ρ,
          ω;
      if (t && t < 2) {
        var θ = halfπ - φ,
            i = 25,
            δ;
        do {
          var sinθ = Math.sin(θ),
              cosθ = Math.cos(θ),
              β_β1 = β + Math.atan2(sinθ, L - cosθ),
              C = 1 + L2 - 2 * L * cosθ;
          θ -= δ = (θ - K2 * β - L * sinθ + C * β_β1 - .5 * t * B) / (2 * L * sinθ * β_β1);
        } while (Math.abs(δ) > ε2 && --i > 0);
        ρ = A * Math.sqrt(C);
        ω = λ * β_β1 / π;
      } else {
        ρ = A * (K + t);
        ω = λ * β / π;
      }
      return [ρ * Math.sin(ω), ρ0 - ρ * Math.cos(ω)];
    }
    forward.invert = function (x, y) {
      var ρ2 = x * x + (y -= ρ0) * y,
          cosθ = (1 + L2 - ρ2 / (A * A)) / (2 * L),
          θ = acos(cosθ),
          sinθ = Math.sin(θ),
          β_β1 = β + Math.atan2(sinθ, L - cosθ);
      return [asin(x / Math.sqrt(ρ2)) * π / β_β1, asin(1 - 2 * (θ - K2 * β - L * sinθ + (1 + L2 - 2 * L * cosθ) * β_β1) / B)];
    };
    return forward;
  }
  function hillProjection() {
    var K = 1,
        m = projectionMutator(hill),
        p = m(K);
    p.ratio = function (_) {
      if (!arguments.length) return K;
      return m(K = +_);
    };
    return p;
  }
  (d3.geo.hill = hillProjection).raw = hill;
  var sinuMollweideφ = .7109889596207567,
      sinuMollweideY = .0528035274542;
  function sinuMollweide(λ, φ) {
    return φ > -sinuMollweideφ ? (λ = mollweide(λ, φ), λ[1] += sinuMollweideY, λ) : sinusoidal(λ, φ);
  }
  sinuMollweide.invert = function (x, y) {
    return y > -sinuMollweideφ ? mollweide.invert(x, y - sinuMollweideY) : sinusoidal.invert(x, y);
  };
  (d3.geo.sinuMollweide = function () {
    return projection(sinuMollweide).rotate([-20, -55]);
  }).raw = sinuMollweide;
  function homolosine(λ, φ) {
    return Math.abs(φ) > sinuMollweideφ ? (λ = mollweide(λ, φ), λ[1] -= φ > 0 ? sinuMollweideY : -sinuMollweideY, λ) : sinusoidal(λ, φ);
  }
  homolosine.invert = function (x, y) {
    return Math.abs(y) > sinuMollweideφ ? mollweide.invert(x, y + (y > 0 ? sinuMollweideY : -sinuMollweideY)) : sinusoidal.invert(x, y);
  };
  (d3.geo.homolosine = function () {
    return projection(homolosine);
  }).raw = homolosine;
  function kavrayskiy7(λ, φ) {
    return [3 * λ / (2 * π) * Math.sqrt(π * π / 3 - φ * φ), φ];
  }
  kavrayskiy7.invert = function (x, y) {
    return [2 / 3 * π * x / Math.sqrt(π * π / 3 - y * y), y];
  };
  (d3.geo.kavrayskiy7 = function () {
    return projection(kavrayskiy7);
  }).raw = kavrayskiy7;
  function lagrange(n) {
    function forward(λ, φ) {
      if (Math.abs(Math.abs(φ) - halfπ) < ε) return [0, φ < 0 ? -2 : 2];
      var sinφ = Math.sin(φ),
          v = Math.pow((1 + sinφ) / (1 - sinφ), n / 2),
          c = .5 * (v + 1 / v) + Math.cos(λ *= n);
      return [2 * Math.sin(λ) / c, (v - 1 / v) / c];
    }
    forward.invert = function (x, y) {
      var y0 = Math.abs(y);
      if (Math.abs(y0 - 2) < ε) return x ? null : [0, sgn(y) * halfπ];
      if (y0 > 2) return null;
      x /= 2, y /= 2;
      var x2 = x * x,
          y2 = y * y,
          t = 2 * y / (1 + x2 + y2);
      t = Math.pow((1 + t) / (1 - t), 1 / n);
      return [Math.atan2(2 * x, 1 - x2 - y2) / n, asin((t - 1) / (t + 1))];
    };
    return forward;
  }
  function lagrangeProjection() {
    var n = .5,
        m = projectionMutator(lagrange),
        p = m(n);
    p.spacing = function (_) {
      if (!arguments.length) return n;
      return m(n = +_);
    };
    return p;
  }
  (d3.geo.lagrange = lagrangeProjection).raw = lagrange;
  function larrivee(λ, φ) {
    return [λ * (1 + Math.sqrt(Math.cos(φ))) / 2, φ / (Math.cos(φ / 2) * Math.cos(λ / 6))];
  }
  larrivee.invert = function (x, y) {
    var x0 = Math.abs(x),
        y0 = Math.abs(y),
        π_sqrt2 = π / Math.SQRT2,
        λ = ε,
        φ = halfπ;
    if (y0 < π_sqrt2) φ *= y0 / π_sqrt2;else λ += 6 * acos(π_sqrt2 / y0);
    for (var i = 0; i < 25; i++) {
      var sinφ = Math.sin(φ),
          sqrtcosφ = asqrt(Math.cos(φ)),
          sinφ_2 = Math.sin(φ / 2),
          cosφ_2 = Math.cos(φ / 2),
          sinλ_6 = Math.sin(λ / 6),
          cosλ_6 = Math.cos(λ / 6),
          f0 = .5 * λ * (1 + sqrtcosφ) - x0,
          f1 = φ / (cosφ_2 * cosλ_6) - y0,
          df0dφ = sqrtcosφ ? -.25 * λ * sinφ / sqrtcosφ : 0,
          df0dλ = .5 * (1 + sqrtcosφ),
          df1dφ = (1 + .5 * φ * sinφ_2 / cosφ_2) / (cosφ_2 * cosλ_6),
          df1dλ = φ / cosφ_2 * (sinλ_6 / 6) / (cosλ_6 * cosλ_6),
          denom = df0dφ * df1dλ - df1dφ * df0dλ,
          dφ = (f0 * df1dλ - f1 * df0dλ) / denom,
          dλ = (f1 * df0dφ - f0 * df1dφ) / denom;
      φ -= dφ;
      λ -= dλ;
      if (Math.abs(dφ) < ε && Math.abs(dλ) < ε) break;
    }
    return [x < 0 ? -λ : λ, y < 0 ? -φ : φ];
  };
  (d3.geo.larrivee = function () {
    return projection(larrivee);
  }).raw = larrivee;
  function laskowski(λ, φ) {
    var λ2 = λ * λ,
        φ2 = φ * φ;
    return [λ * (.975534 + φ2 * (-.119161 + λ2 * -.0143059 + φ2 * -.0547009)), φ * (1.00384 + λ2 * (.0802894 + φ2 * -.02855 + λ2 * 199025e-9) + φ2 * (.0998909 + φ2 * -.0491032))];
  }
  laskowski.invert = function (x, y) {
    var λ = sgn(x) * π,
        φ = y / 2,
        i = 50;
    do {
      var λ2 = λ * λ,
          φ2 = φ * φ,
          λφ = λ * φ,
          fx = λ * (.975534 + φ2 * (-.119161 + λ2 * -.0143059 + φ2 * -.0547009)) - x,
          fy = φ * (1.00384 + λ2 * (.0802894 + φ2 * -.02855 + λ2 * 199025e-9) + φ2 * (.0998909 + φ2 * -.0491032)) - y,
          δxδλ = .975534 - φ2 * (.119161 + 3 * λ2 * .0143059 + φ2 * .0547009),
          δxδφ = -λφ * (2 * .119161 + 4 * .0547009 * φ2 + 2 * .0143059 * λ2),
          δyδλ = λφ * (2 * .0802894 + 4 * 199025e-9 * λ2 + 2 * -.02855 * φ2),
          δyδφ = 1.00384 + λ2 * (.0802894 + 199025e-9 * λ2) + φ2 * (3 * (.0998909 - .02855 * λ2) - 5 * .0491032 * φ2),
          denominator = δxδφ * δyδλ - δyδφ * δxδλ,
          δλ = (fy * δxδφ - fx * δyδφ) / denominator,
          δφ = (fx * δyδλ - fy * δxδλ) / denominator;
      λ -= δλ, φ -= δφ;
    } while ((Math.abs(δλ) > ε || Math.abs(δφ) > ε) && --i > 0);
    return i && [λ, φ];
  };
  (d3.geo.laskowski = function () {
    return projection(laskowski);
  }).raw = laskowski;
  function littrow(λ, φ) {
    return [Math.sin(λ) / Math.cos(φ), Math.tan(φ) * Math.cos(λ)];
  }
  littrow.invert = function (x, y) {
    var x2 = x * x,
        y2 = y * y,
        y2_1 = y2 + 1,
        cosφ = x ? Math.SQRT1_2 * Math.sqrt((y2_1 - Math.sqrt(x2 * x2 + 2 * x2 * (y2 - 1) + y2_1 * y2_1)) / x2 + 1) : 1 / Math.sqrt(y2_1);
    return [asin(x * cosφ), sgn(y) * acos(cosφ)];
  };
  (d3.geo.littrow = function () {
    return projection(littrow);
  }).raw = littrow;
  function loximuthal(φ0) {
    var cosφ0 = Math.cos(φ0),
        tanφ0 = Math.tan(π / 4 + φ0 / 2);
    function forward(λ, φ) {
      var y = φ - φ0,
          x = Math.abs(y) < ε ? λ * cosφ0 : Math.abs(x = π / 4 + φ / 2) < ε || Math.abs(Math.abs(x) - halfπ) < ε ? 0 : λ * y / Math.log(Math.tan(x) / tanφ0);
      return [x, y];
    }
    forward.invert = function (x, y) {
      var λ,
          φ = y + φ0;
      return [Math.abs(y) < ε ? x / cosφ0 : Math.abs(λ = π / 4 + φ / 2) < ε || Math.abs(Math.abs(λ) - halfπ) < ε ? 0 : x * Math.log(Math.tan(λ) / tanφ0) / y, φ];
    };
    return forward;
  }
  (d3.geo.loximuthal = function () {
    return parallel1Projection(loximuthal).parallel(40);
  }).raw = loximuthal;
  function miller(λ, φ) {
    return [λ, 1.25 * Math.log(Math.tan(π / 4 + .4 * φ))];
  }
  miller.invert = function (x, y) {
    return [x, 2.5 * Math.atan(Math.exp(.8 * y)) - .625 * π];
  };
  (d3.geo.miller = function () {
    return projection(miller);
  }).raw = miller;
  function modifiedStereographic(C) {
    var m = C.length - 1;
    function forward(λ, φ) {
      var cosφ = Math.cos(φ),
          k = 2 / (1 + cosφ * Math.cos(λ)),
          zr = k * cosφ * Math.sin(λ),
          zi = k * Math.sin(φ),
          i = m,
          w = C[i],
          ar = w[0],
          ai = w[1],
          t;
      while (--i >= 0) {
        w = C[i];
        ar = w[0] + zr * (t = ar) - zi * ai;
        ai = w[1] + zr * ai + zi * t;
      }
      ar = zr * (t = ar) - zi * ai;
      ai = zr * ai + zi * t;
      return [ar, ai];
    }
    forward.invert = function (x, y) {
      var i = 20,
          zr = x,
          zi = y;
      do {
        var j = m,
            w = C[j],
            ar = w[0],
            ai = w[1],
            br = 0,
            bi = 0,
            t;
        while (--j >= 0) {
          w = C[j];
          br = ar + zr * (t = br) - zi * bi;
          bi = ai + zr * bi + zi * t;
          ar = w[0] + zr * (t = ar) - zi * ai;
          ai = w[1] + zr * ai + zi * t;
        }
        br = ar + zr * (t = br) - zi * bi;
        bi = ai + zr * bi + zi * t;
        ar = zr * (t = ar) - zi * ai - x;
        ai = zr * ai + zi * t - y;
        var denominator = br * br + bi * bi,
            δr,
            δi;
        zr -= δr = (ar * br + ai * bi) / denominator;
        zi -= δi = (ai * br - ar * bi) / denominator;
      } while (Math.abs(δr) + Math.abs(δi) > ε * ε && --i > 0);
      if (i) {
        var ρ = Math.sqrt(zr * zr + zi * zi),
            c = 2 * Math.atan(ρ * .5),
            sinc = Math.sin(c);
        return [Math.atan2(zr * sinc, ρ * Math.cos(c)), ρ ? asin(zi * sinc / ρ) : 0];
      }
    };
    return forward;
  }
  var modifiedStereographicCoefficients = {
    alaska: [[.9972523, 0], [.0052513, -.0041175], [.0074606, .0048125], [-.0153783, -.1968253], [.0636871, -.1408027], [.3660976, -.2937382]],
    gs48: [[.98879, 0], [0, 0], [-.050909, 0], [0, 0], [.075528, 0]],
    gs50: [[.984299, 0], [.0211642, .0037608], [-.1036018, -.0575102], [-.0329095, -.0320119], [.0499471, .1223335], [.026046, .0899805], [7388e-7, -.1435792], [.0075848, -.1334108], [-.0216473, .0776645], [-.0225161, .0853673]],
    miller: [[.9245, 0], [0, 0], [.01943, 0]],
    lee: [[.721316, 0], [0, 0], [-.00881625, -.00617325]]
  };
  function modifiedStereographicProjection() {
    var coefficients = modifiedStereographicCoefficients.miller,
        m = projectionMutator(modifiedStereographic),
        p = m(coefficients);
    p.coefficients = function (_) {
      if (!arguments.length) return coefficients;
      return m(coefficients = typeof _ === "string" ? modifiedStereographicCoefficients[_] : _);
    };
    return p;
  }
  (d3.geo.modifiedStereographic = modifiedStereographicProjection).raw = modifiedStereographic;
  function mtFlatPolarParabolic(λ, φ) {
    var sqrt6 = Math.sqrt(6),
        sqrt7 = Math.sqrt(7),
        θ = Math.asin(7 * Math.sin(φ) / (3 * sqrt6));
    return [sqrt6 * λ * (2 * Math.cos(2 * θ / 3) - 1) / sqrt7, 9 * Math.sin(θ / 3) / sqrt7];
  }
  mtFlatPolarParabolic.invert = function (x, y) {
    var sqrt6 = Math.sqrt(6),
        sqrt7 = Math.sqrt(7),
        θ = 3 * asin(y * sqrt7 / 9);
    return [x * sqrt7 / (sqrt6 * (2 * Math.cos(2 * θ / 3) - 1)), asin(Math.sin(θ) * 3 * sqrt6 / 7)];
  };
  (d3.geo.mtFlatPolarParabolic = function () {
    return projection(mtFlatPolarParabolic);
  }).raw = mtFlatPolarParabolic;
  function mtFlatPolarQuartic(λ, φ) {
    var k = (1 + Math.SQRT1_2) * Math.sin(φ),
        θ = φ;
    for (var i = 0, δ; i < 25; i++) {
      θ -= δ = (Math.sin(θ / 2) + Math.sin(θ) - k) / (.5 * Math.cos(θ / 2) + Math.cos(θ));
      if (Math.abs(δ) < ε) break;
    }
    return [λ * (1 + 2 * Math.cos(θ) / Math.cos(θ / 2)) / (3 * Math.SQRT2), 2 * Math.sqrt(3) * Math.sin(θ / 2) / Math.sqrt(2 + Math.SQRT2)];
  }
  mtFlatPolarQuartic.invert = function (x, y) {
    var sinθ_2 = y * Math.sqrt(2 + Math.SQRT2) / (2 * Math.sqrt(3)),
        θ = 2 * asin(sinθ_2);
    return [3 * Math.SQRT2 * x / (1 + 2 * Math.cos(θ) / Math.cos(θ / 2)), asin((sinθ_2 + Math.sin(θ)) / (1 + Math.SQRT1_2))];
  };
  (d3.geo.mtFlatPolarQuartic = function () {
    return projection(mtFlatPolarQuartic);
  }).raw = mtFlatPolarQuartic;
  function mtFlatPolarSinusoidal(λ, φ) {
    var A = Math.sqrt(6 / (4 + π)),
        k = (1 + π / 4) * Math.sin(φ),
        θ = φ / 2;
    for (var i = 0, δ; i < 25; i++) {
      θ -= δ = (θ / 2 + Math.sin(θ) - k) / (.5 + Math.cos(θ));
      if (Math.abs(δ) < ε) break;
    }
    return [A * (.5 + Math.cos(θ)) * λ / 1.5, A * θ];
  }
  mtFlatPolarSinusoidal.invert = function (x, y) {
    var A = Math.sqrt(6 / (4 + π)),
        θ = y / A;
    if (Math.abs(Math.abs(θ) - halfπ) < ε) θ = θ < 0 ? -halfπ : halfπ;
    return [1.5 * x / (A * (.5 + Math.cos(θ))), asin((θ / 2 + Math.sin(θ)) / (1 + π / 4))];
  };
  (d3.geo.mtFlatPolarSinusoidal = function () {
    return projection(mtFlatPolarSinusoidal);
  }).raw = mtFlatPolarSinusoidal;
  function naturalEarth(λ, φ) {
    var φ2 = φ * φ,
        φ4 = φ2 * φ2;
    return [λ * (.8707 - .131979 * φ2 + φ4 * (-.013791 + φ4 * (.003971 * φ2 - .001529 * φ4))), φ * (1.007226 + φ2 * (.015085 + φ4 * (-.044475 + .028874 * φ2 - .005916 * φ4)))];
  }
  naturalEarth.invert = function (x, y) {
    var φ = y,
        i = 25,
        δ;
    do {
      var φ2 = φ * φ,
          φ4 = φ2 * φ2;
      φ -= δ = (φ * (1.007226 + φ2 * (.015085 + φ4 * (-.044475 + .028874 * φ2 - .005916 * φ4))) - y) / (1.007226 + φ2 * (.015085 * 3 + φ4 * (-.044475 * 7 + .028874 * 9 * φ2 - .005916 * 11 * φ4)));
    } while (Math.abs(δ) > ε && --i > 0);
    return [x / (.8707 + (φ2 = φ * φ) * (-.131979 + φ2 * (-.013791 + φ2 * φ2 * φ2 * (.003971 - .001529 * φ2)))), φ];
  };
  (d3.geo.naturalEarth = function () {
    return projection(naturalEarth);
  }).raw = naturalEarth;
  function nellHammer(λ, φ) {
    return [λ * (1 + Math.cos(φ)) / 2, 2 * (φ - Math.tan(φ / 2))];
  }
  nellHammer.invert = function (x, y) {
    var p = y / 2;
    for (var i = 0, δ = Infinity; i < 10 && Math.abs(δ) > ε; i++) {
      var c = Math.cos(y / 2);
      y -= δ = (y - Math.tan(y / 2) - p) / (1 - .5 / (c * c));
    }
    return [2 * x / (1 + Math.cos(y)), y];
  };
  (d3.geo.nellHammer = function () {
    return projection(nellHammer);
  }).raw = nellHammer;
  var pattersonK1 = 1.0148,
      pattersonK2 = .23185,
      pattersonK3 = -.14499,
      pattersonK4 = .02406,
      pattersonC1 = pattersonK1,
      pattersonC2 = 5 * pattersonK2,
      pattersonC3 = 7 * pattersonK3,
      pattersonC4 = 9 * pattersonK4,
      pattersonYmax = 1.790857183;
  function patterson(λ, φ) {
    var φ2 = φ * φ;
    return [λ, φ * (pattersonK1 + φ2 * φ2 * (pattersonK2 + φ2 * (pattersonK3 + pattersonK4 * φ2)))];
  }
  patterson.invert = function (x, y) {
    if (y > pattersonYmax) y = pattersonYmax;else if (y < -pattersonYmax) y = -pattersonYmax;
    var yc = y,
        δ;
    do {
      var y2 = yc * yc;
      yc -= δ = (yc * (pattersonK1 + y2 * y2 * (pattersonK2 + y2 * (pattersonK3 + pattersonK4 * y2))) - y) / (pattersonC1 + y2 * y2 * (pattersonC2 + y2 * (pattersonC3 + pattersonC4 * y2)));
    } while (Math.abs(δ) > ε);
    return [x, yc];
  };
  (d3.geo.patterson = function () {
    return projection(patterson);
  }).raw = patterson;
  var peirceQuincuncialProjection = quincuncialProjection(guyou);
  (d3.geo.peirceQuincuncial = function () {
    return peirceQuincuncialProjection().quincuncial(true).rotate([-90, -90, 45]).clipAngle(180 - 1e-6);
  }).raw = peirceQuincuncialProjection.raw;
  function polyconic(λ, φ) {
    if (Math.abs(φ) < ε) return [λ, 0];
    var tanφ = Math.tan(φ),
        k = λ * Math.sin(φ);
    return [Math.sin(k) / tanφ, φ + (1 - Math.cos(k)) / tanφ];
  }
  polyconic.invert = function (x, y) {
    if (Math.abs(y) < ε) return [x, 0];
    var k = x * x + y * y,
        φ = y * .5,
        i = 10,
        δ;
    do {
      var tanφ = Math.tan(φ),
          secφ = 1 / Math.cos(φ),
          j = k - 2 * y * φ + φ * φ;
      φ -= δ = (tanφ * j + 2 * (φ - y)) / (2 + j * secφ * secφ + 2 * (φ - y) * tanφ);
    } while (Math.abs(δ) > ε && --i > 0);
    tanφ = Math.tan(φ);
    return [(Math.abs(y) < Math.abs(φ + 1 / tanφ) ? asin(x * tanφ) : sgn(x) * (acos(Math.abs(x * tanφ)) + halfπ)) / Math.sin(φ), φ];
  };
  (d3.geo.polyconic = function () {
    return projection(polyconic);
  }).raw = polyconic;
  function rectangularPolyconic(φ0) {
    var sinφ0 = Math.sin(φ0);
    function forward(λ, φ) {
      var A = sinφ0 ? Math.tan(λ * sinφ0 / 2) / sinφ0 : λ / 2;
      if (!φ) return [2 * A, -φ0];
      var E = 2 * Math.atan(A * Math.sin(φ)),
          cotφ = 1 / Math.tan(φ);
      return [Math.sin(E) * cotφ, φ + (1 - Math.cos(E)) * cotφ - φ0];
    }
    forward.invert = function (x, y) {
      if (Math.abs(y += φ0) < ε) return [sinφ0 ? 2 * Math.atan(sinφ0 * x / 2) / sinφ0 : x, 0];
      var k = x * x + y * y,
          φ = 0,
          i = 10,
          δ;
      do {
        var tanφ = Math.tan(φ),
            secφ = 1 / Math.cos(φ),
            j = k - 2 * y * φ + φ * φ;
        φ -= δ = (tanφ * j + 2 * (φ - y)) / (2 + j * secφ * secφ + 2 * (φ - y) * tanφ);
      } while (Math.abs(δ) > ε && --i > 0);
      var E = x * (tanφ = Math.tan(φ)),
          A = Math.tan(Math.abs(y) < Math.abs(φ + 1 / tanφ) ? asin(E) * .5 : acos(E) * .5 + π / 4) / Math.sin(φ);
      return [sinφ0 ? 2 * Math.atan(sinφ0 * A) / sinφ0 : 2 * A, φ];
    };
    return forward;
  }
  (d3.geo.rectangularPolyconic = function () {
    return parallel1Projection(rectangularPolyconic);
  }).raw = rectangularPolyconic;
  var robinsonConstants = [[.9986, -.062], [1, 0], [.9986, .062], [.9954, .124], [.99, .186], [.9822, .248], [.973, .31], [.96, .372], [.9427, .434], [.9216, .4958], [.8962, .5571], [.8679, .6176], [.835, .6769], [.7986, .7346], [.7597, .7903], [.7186, .8435], [.6732, .8936], [.6213, .9394], [.5722, .9761], [.5322, 1]];
  robinsonConstants.forEach(function (d) {
    d[1] *= 1.0144;
  });
  function robinson(λ, φ) {
    var i = Math.min(18, Math.abs(φ) * 36 / π),
        i0 = Math.floor(i),
        di = i - i0,
        ax = (k = robinsonConstants[i0])[0],
        ay = k[1],
        bx = (k = robinsonConstants[++i0])[0],
        by = k[1],
        cx = (k = robinsonConstants[Math.min(19, ++i0)])[0],
        cy = k[1],
        k;
    return [λ * (bx + di * (cx - ax) / 2 + di * di * (cx - 2 * bx + ax) / 2), (φ > 0 ? halfπ : -halfπ) * (by + di * (cy - ay) / 2 + di * di * (cy - 2 * by + ay) / 2)];
  }
  robinson.invert = function (x, y) {
    var yy = y / halfπ,
        φ = yy * 90,
        i = Math.min(18, Math.abs(φ / 5)),
        i0 = Math.max(0, Math.floor(i));
    do {
      var ay = robinsonConstants[i0][1],
          by = robinsonConstants[i0 + 1][1],
          cy = robinsonConstants[Math.min(19, i0 + 2)][1],
          u = cy - ay,
          v = cy - 2 * by + ay,
          t = 2 * (Math.abs(yy) - by) / u,
          c = v / u,
          di = t * (1 - c * t * (1 - 2 * c * t));
      if (di >= 0 || i0 === 1) {
        φ = (y >= 0 ? 5 : -5) * (di + i);
        var j = 50,
            δ;
        do {
          i = Math.min(18, Math.abs(φ) / 5);
          i0 = Math.floor(i);
          di = i - i0;
          ay = robinsonConstants[i0][1];
          by = robinsonConstants[i0 + 1][1];
          cy = robinsonConstants[Math.min(19, i0 + 2)][1];
          φ -= (δ = (y >= 0 ? halfπ : -halfπ) * (by + di * (cy - ay) / 2 + di * di * (cy - 2 * by + ay) / 2) - y) * degrees;
        } while (Math.abs(δ) > ε2 && --j > 0);
        break;
      }
    } while (--i0 >= 0);
    var ax = robinsonConstants[i0][0],
        bx = robinsonConstants[i0 + 1][0],
        cx = robinsonConstants[Math.min(19, i0 + 2)][0];
    return [x / (bx + di * (cx - ax) / 2 + di * di * (cx - 2 * bx + ax) / 2), φ * radians];
  };
  (d3.geo.robinson = function () {
    return projection(robinson);
  }).raw = robinson;
  function satelliteVertical(P) {
    function forward(λ, φ) {
      var cosφ = Math.cos(φ),
          k = (P - 1) / (P - cosφ * Math.cos(λ));
      return [k * cosφ * Math.sin(λ), k * Math.sin(φ)];
    }
    forward.invert = function (x, y) {
      var ρ2 = x * x + y * y,
          ρ = Math.sqrt(ρ2),
          sinc = (P - Math.sqrt(1 - ρ2 * (P + 1) / (P - 1))) / ((P - 1) / ρ + ρ / (P - 1));
      return [Math.atan2(x * sinc, ρ * Math.sqrt(1 - sinc * sinc)), ρ ? asin(y * sinc / ρ) : 0];
    };
    return forward;
  }
  function satellite(P, ω) {
    var vertical = satelliteVertical(P);
    if (!ω) return vertical;
    var cosω = Math.cos(ω),
        sinω = Math.sin(ω);
    function forward(λ, φ) {
      var coordinates = vertical(λ, φ),
          y = coordinates[1],
          A = y * sinω / (P - 1) + cosω;
      return [coordinates[0] * cosω / A, y / A];
    }
    forward.invert = function (x, y) {
      var k = (P - 1) / (P - 1 - y * sinω);
      return vertical.invert(k * x, k * y * cosω);
    };
    return forward;
  }
  function satelliteProjection() {
    var P = 1.4,
        ω = 0,
        m = projectionMutator(satellite),
        p = m(P, ω);
    p.distance = function (_) {
      if (!arguments.length) return P;
      return m(P = +_, ω);
    };
    p.tilt = function (_) {
      if (!arguments.length) return ω * 180 / π;
      return m(P, ω = _ * π / 180);
    };
    return p;
  }
  (d3.geo.satellite = satelliteProjection).raw = satellite;
  function times(λ, φ) {
    var t = Math.tan(φ / 2),
        s = Math.sin(π / 4 * t);
    return [λ * (.74482 - .34588 * s * s), 1.70711 * t];
  }
  times.invert = function (x, y) {
    var t = y / 1.70711,
        s = Math.sin(π / 4 * t);
    return [x / (.74482 - .34588 * s * s), 2 * Math.atan(t)];
  };
  (d3.geo.times = function () {
    return projection(times);
  }).raw = times;
  function twoPointEquidistant(z0) {
    if (!z0) return d3.geo.azimuthalEquidistant.raw;
    var λa = -z0 / 2,
        λb = -λa,
        z02 = z0 * z0,
        tanλ0 = Math.tan(λb),
        S = .5 / Math.sin(λb);
    function forward(λ, φ) {
      var za = acos(Math.cos(φ) * Math.cos(λ - λa)),
          zb = acos(Math.cos(φ) * Math.cos(λ - λb)),
          ys = φ < 0 ? -1 : 1;
      za *= za, zb *= zb;
      return [(za - zb) / (2 * z0), ys * asqrt(4 * z02 * zb - (z02 - za + zb) * (z02 - za + zb)) / (2 * z0)];
    }
    forward.invert = function (x, y) {
      var y2 = y * y,
          cosza = Math.cos(Math.sqrt(y2 + (t = x + λa) * t)),
          coszb = Math.cos(Math.sqrt(y2 + (t = x + λb) * t)),
          t,
          d;
      return [Math.atan2(d = cosza - coszb, t = (cosza + coszb) * tanλ0), (y < 0 ? -1 : 1) * acos(Math.sqrt(t * t + d * d) * S)];
    };
    return forward;
  }
  function twoPointEquidistantProjection() {
    var points = [[0, 0], [0, 0]],
        m = projectionMutator(twoPointEquidistant),
        p = m(0),
        rotate = p.rotate;
    delete p.rotate;
    p.points = function (_) {
      if (!arguments.length) return points;
      points = _;
      var interpolate = d3.geo.interpolate(_[0], _[1]),
          origin = interpolate(.5),
          p = d3.geo.rotation([-origin[0], -origin[1]])(_[0]),
          b = interpolate.distance * .5,
          γ = -asin(Math.sin(p[1] * radians) / Math.sin(b));
      if (p[0] > 0) γ = π - γ;
      rotate.call(p, [-origin[0], -origin[1], -γ * degrees]);
      return m(b * 2);
    };
    return p;
  }
  (d3.geo.twoPointEquidistant = twoPointEquidistantProjection).raw = twoPointEquidistant;
  function twoPointAzimuthal(d) {
    var cosd = Math.cos(d);
    function forward(λ, φ) {
      var coordinates = d3.geo.gnomonic.raw(λ, φ);
      coordinates[0] *= cosd;
      return coordinates;
    }
    forward.invert = function (x, y) {
      return d3.geo.gnomonic.raw.invert(x / cosd, y);
    };
    return forward;
  }
  function twoPointAzimuthalProjection() {
    var points = [[0, 0], [0, 0]],
        m = projectionMutator(twoPointAzimuthal),
        p = m(0),
        rotate = p.rotate;
    delete p.rotate;
    p.points = function (_) {
      if (!arguments.length) return points;
      points = _;
      var interpolate = d3.geo.interpolate(_[0], _[1]),
          origin = interpolate(.5),
          p = d3.geo.rotation([-origin[0], -origin[1]])(_[0]),
          b = interpolate.distance * .5,
          γ = -asin(Math.sin(p[1] * radians) / Math.sin(b));
      if (p[0] > 0) γ = π - γ;
      rotate.call(p, [-origin[0], -origin[1], -γ * degrees]);
      return m(b);
    };
    return p;
  }
  (d3.geo.twoPointAzimuthal = twoPointAzimuthalProjection).raw = twoPointAzimuthal;
  function vanDerGrinten(λ, φ) {
    if (Math.abs(φ) < ε) return [λ, 0];
    var sinθ = Math.abs(φ / halfπ),
        θ = asin(sinθ);
    if (Math.abs(λ) < ε || Math.abs(Math.abs(φ) - halfπ) < ε) return [0, sgn(φ) * π * Math.tan(θ / 2)];
    var cosθ = Math.cos(θ),
        A = Math.abs(π / λ - λ / π) / 2,
        A2 = A * A,
        G = cosθ / (sinθ + cosθ - 1),
        P = G * (2 / sinθ - 1),
        P2 = P * P,
        P2_A2 = P2 + A2,
        G_P2 = G - P2,
        Q = A2 + G;
    return [sgn(λ) * π * (A * G_P2 + Math.sqrt(A2 * G_P2 * G_P2 - P2_A2 * (G * G - P2))) / P2_A2, sgn(φ) * π * (P * Q - A * Math.sqrt((A2 + 1) * P2_A2 - Q * Q)) / P2_A2];
  }
  vanDerGrinten.invert = function (x, y) {
    if (Math.abs(y) < ε) return [x, 0];
    if (Math.abs(x) < ε) return [0, halfπ * Math.sin(2 * Math.atan(y / π))];
    var x2 = (x /= π) * x,
        y2 = (y /= π) * y,
        x2_y2 = x2 + y2,
        z = x2_y2 * x2_y2,
        c1 = -Math.abs(y) * (1 + x2_y2),
        c2 = c1 - 2 * y2 + x2,
        c3 = -2 * c1 + 1 + 2 * y2 + z,
        d = y2 / c3 + (2 * c2 * c2 * c2 / (c3 * c3 * c3) - 9 * c1 * c2 / (c3 * c3)) / 27,
        a1 = (c1 - c2 * c2 / (3 * c3)) / c3,
        m1 = 2 * Math.sqrt(-a1 / 3),
        θ1 = acos(3 * d / (a1 * m1)) / 3;
    return [π * (x2_y2 - 1 + Math.sqrt(1 + 2 * (x2 - y2) + z)) / (2 * x), sgn(y) * π * (-m1 * Math.cos(θ1 + π / 3) - c2 / (3 * c3))];
  };
  (d3.geo.vanDerGrinten = function () {
    return projection(vanDerGrinten);
  }).raw = vanDerGrinten;
  function vanDerGrinten2(λ, φ) {
    if (Math.abs(φ) < ε) return [λ, 0];
    var sinθ = Math.abs(φ / halfπ),
        θ = asin(sinθ);
    if (Math.abs(λ) < ε || Math.abs(Math.abs(φ) - halfπ) < ε) return [0, sgn(φ) * π * Math.tan(θ / 2)];
    var cosθ = Math.cos(θ),
        A = Math.abs(π / λ - λ / π) / 2,
        A2 = A * A,
        x1 = cosθ * (Math.sqrt(1 + A2) - A * cosθ) / (1 + A2 * sinθ * sinθ);
    return [sgn(λ) * π * x1, sgn(φ) * π * asqrt(1 - x1 * (2 * A + x1))];
  }
  vanDerGrinten2.invert = function (x, y) {
    if (!x) return [0, halfπ * Math.sin(2 * Math.atan(y / π))];
    var x1 = Math.abs(x / π),
        A = (1 - x1 * x1 - (y /= π) * y) / (2 * x1),
        A2 = A * A,
        B = Math.sqrt(A2 + 1);
    return [sgn(x) * π * (B - A), sgn(y) * halfπ * Math.sin(2 * Math.atan2(Math.sqrt((1 - 2 * A * x1) * (A + B) - x1), Math.sqrt(B + A + x1)))];
  };
  (d3.geo.vanDerGrinten2 = function () {
    return projection(vanDerGrinten2);
  }).raw = vanDerGrinten2;
  function vanDerGrinten3(λ, φ) {
    if (Math.abs(φ) < ε) return [λ, 0];
    var sinθ = φ / halfπ,
        θ = asin(sinθ);
    if (Math.abs(λ) < ε || Math.abs(Math.abs(φ) - halfπ) < ε) return [0, π * Math.tan(θ / 2)];
    var A = (π / λ - λ / π) / 2,
        y1 = sinθ / (1 + Math.cos(θ));
    return [π * (sgn(λ) * asqrt(A * A + 1 - y1 * y1) - A), π * y1];
  }
  vanDerGrinten3.invert = function (x, y) {
    if (!y) return [x, 0];
    var y1 = y / π,
        A = (π * π * (1 - y1 * y1) - x * x) / (2 * π * x);
    return [x ? π * (sgn(x) * Math.sqrt(A * A + 1) - A) : 0, halfπ * Math.sin(2 * Math.atan(y1))];
  };
  (d3.geo.vanDerGrinten3 = function () {
    return projection(vanDerGrinten3);
  }).raw = vanDerGrinten3;
  function vanDerGrinten4(λ, φ) {
    if (!φ) return [λ, 0];
    var φ0 = Math.abs(φ);
    if (!λ || φ0 === halfπ) return [0, φ];
    var B = φ0 / halfπ,
        B2 = B * B,
        C = (8 * B - B2 * (B2 + 2) - 5) / (2 * B2 * (B - 1)),
        C2 = C * C,
        BC = B * C,
        B_C2 = B2 + C2 + 2 * BC,
        B_3C = B + 3 * C,
        λ0 = λ / halfπ,
        λ1 = λ0 + 1 / λ0,
        D = sgn(Math.abs(λ) - halfπ) * Math.sqrt(λ1 * λ1 - 4),
        D2 = D * D,
        F = B_C2 * (B2 + C2 * D2 - 1) + (1 - B2) * (B2 * (B_3C * B_3C + 4 * C2) + 12 * BC * C2 + 4 * C2 * C2),
        x1 = (D * (B_C2 + C2 - 1) + 2 * asqrt(F)) / (4 * B_C2 + D2);
    return [sgn(λ) * halfπ * x1, sgn(φ) * halfπ * asqrt(1 + D * Math.abs(x1) - x1 * x1)];
  }
  vanDerGrinten4.invert = function (x, y) {
    if (!x || !y) return [x, y];
    y /= π;
    var x1 = sgn(x) * x / halfπ,
        D = (x1 * x1 - 1 + 4 * y * y) / Math.abs(x1),
        D2 = D * D,
        B = 2 * y,
        i = 50;
    do {
      var B2 = B * B,
          C = (8 * B - B2 * (B2 + 2) - 5) / (2 * B2 * (B - 1)),
          C_ = (3 * B - B2 * B - 10) / (2 * B2 * B),
          C2 = C * C,
          BC = B * C,
          B_C = B + C,
          B_C2 = B_C * B_C,
          B_3C = B + 3 * C,
          F = B_C2 * (B2 + C2 * D2 - 1) + (1 - B2) * (B2 * (B_3C * B_3C + 4 * C2) + C2 * (12 * BC + 4 * C2)),
          F_ = -2 * B_C * (4 * BC * C2 + (1 - 4 * B2 + 3 * B2 * B2) * (1 + C_) + C2 * (-6 + 14 * B2 - D2 + (-8 + 8 * B2 - 2 * D2) * C_) + BC * (-8 + 12 * B2 + (-10 + 10 * B2 - D2) * C_)),
          sqrtF = Math.sqrt(F),
          f = D * (B_C2 + C2 - 1) + 2 * sqrtF - x1 * (4 * B_C2 + D2),
          f_ = D * (2 * C * C_ + 2 * B_C * (1 + C_)) + F_ / sqrtF - 8 * B_C * (D * (-1 + C2 + B_C2) + 2 * sqrtF) * (1 + C_) / (D2 + 4 * B_C2);
      B -= δ = f / f_;
    } while (δ > ε && --i > 0);
    return [sgn(x) * (Math.sqrt(D * D + 4) + D) * π / 4, halfπ * B];
  };
  (d3.geo.vanDerGrinten4 = function () {
    return projection(vanDerGrinten4);
  }).raw = vanDerGrinten4;
  var wagner4 = function () {
    var A = 4 * π + 3 * Math.sqrt(3),
        B = 2 * Math.sqrt(2 * π * Math.sqrt(3) / A);
    return mollweideBromley(B * Math.sqrt(3) / π, B, A / 6);
  }();
  (d3.geo.wagner4 = function () {
    return projection(wagner4);
  }).raw = wagner4;
  function wagner6(λ, φ) {
    return [λ * Math.sqrt(1 - 3 * φ * φ / (π * π)), φ];
  }
  wagner6.invert = function (x, y) {
    return [x / Math.sqrt(1 - 3 * y * y / (π * π)), y];
  };
  (d3.geo.wagner6 = function () {
    return projection(wagner6);
  }).raw = wagner6;
  function wagner7(λ, φ) {
    var s = .90631 * Math.sin(φ),
        c0 = Math.sqrt(1 - s * s),
        c1 = Math.sqrt(2 / (1 + c0 * Math.cos(λ /= 3)));
    return [2.66723 * c0 * c1 * Math.sin(λ), 1.24104 * s * c1];
  }
  wagner7.invert = function (x, y) {
    var t1 = x / 2.66723,
        t2 = y / 1.24104,
        p = Math.sqrt(t1 * t1 + t2 * t2),
        c = 2 * asin(p / 2);
    return [3 * Math.atan2(x * Math.tan(c), 2.66723 * p), p && asin(y * Math.sin(c) / (1.24104 * .90631 * p))];
  };
  (d3.geo.wagner7 = function () {
    return projection(wagner7);
  }).raw = wagner7;
  function wiechel(λ, φ) {
    var cosφ = Math.cos(φ),
        sinφ = Math.cos(λ) * cosφ,
        sin1_φ = 1 - sinφ,
        cosλ = Math.cos(λ = Math.atan2(Math.sin(λ) * cosφ, -Math.sin(φ))),
        sinλ = Math.sin(λ);
    cosφ = asqrt(1 - sinφ * sinφ);
    return [sinλ * cosφ - cosλ * sin1_φ, -cosλ * cosφ - sinλ * sin1_φ];
  }
  wiechel.invert = function (x, y) {
    var w = -.5 * (x * x + y * y),
        k = Math.sqrt(-w * (2 + w)),
        b = y * w + x * k,
        a = x * w - y * k,
        D = Math.sqrt(a * a + b * b);
    return [Math.atan2(k * b, D * (1 + w)), D ? -asin(k * a / D) : 0];
  };
  (d3.geo.wiechel = function () {
    return projection(wiechel);
  }).raw = wiechel;
  function winkel3(λ, φ) {
    var coordinates = aitoff(λ, φ);
    return [(coordinates[0] + λ / halfπ) / 2, (coordinates[1] + φ) / 2];
  }
  winkel3.invert = function (x, y) {
    var λ = x,
        φ = y,
        i = 25;
    do {
      var cosφ = Math.cos(φ),
          sinφ = Math.sin(φ),
          sin_2φ = Math.sin(2 * φ),
          sin2φ = sinφ * sinφ,
          cos2φ = cosφ * cosφ,
          sinλ = Math.sin(λ),
          cosλ_2 = Math.cos(λ / 2),
          sinλ_2 = Math.sin(λ / 2),
          sin2λ_2 = sinλ_2 * sinλ_2,
          C = 1 - cos2φ * cosλ_2 * cosλ_2,
          E = C ? acos(cosφ * cosλ_2) * Math.sqrt(F = 1 / C) : F = 0,
          F,
          fx = .5 * (2 * E * cosφ * sinλ_2 + λ / halfπ) - x,
          fy = .5 * (E * sinφ + φ) - y,
          δxδλ = .5 * F * (cos2φ * sin2λ_2 + E * cosφ * cosλ_2 * sin2φ) + .5 / halfπ,
          δxδφ = F * (sinλ * sin_2φ / 4 - E * sinφ * sinλ_2),
          δyδλ = .125 * F * (sin_2φ * sinλ_2 - E * sinφ * cos2φ * sinλ),
          δyδφ = .5 * F * (sin2φ * cosλ_2 + E * sin2λ_2 * cosφ) + .5,
          denominator = δxδφ * δyδλ - δyδφ * δxδλ,
          δλ = (fy * δxδφ - fx * δyδφ) / denominator,
          δφ = (fx * δyδλ - fy * δxδλ) / denominator;
      λ -= δλ, φ -= δφ;
    } while ((Math.abs(δλ) > ε || Math.abs(δφ) > ε) && --i > 0);
    return [λ, φ];
  };
  (d3.geo.winkel3 = function () {
    return projection(winkel3);
  }).raw = winkel3;
};

;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _class = __webpack_require__(21);

var _class2 = _interopRequireDefault(_class);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _prefix = "";
var _deleteClasses = [];
var SVGHEADER = '<?xml version="1.0" encoding="utf-8"?>';

exports.default = _class2.default.extend({

  init: function init(context) {
    this.context = context;
    this.shapes = [];
    this.groups = [];
    this.counter = 0;
    this.name = "";
    this.label = "";
  },

  reset: function reset() {
    this.container.remove();
    this.context.element.selectAll(".vzb-export-redball").remove();
    this.context.element.selectAll(".vzb-export-counter").remove();
    this.counter = 0;
  },

  prefix: function prefix(arg) {
    if (!arguments.length) return _prefix;
    _prefix = arg;
    return this;
  },
  deleteClasses: function deleteClasses(arg) {
    if (!arguments.length) return _deleteClasses;
    _deleteClasses = arg;
    return this;
  },

  open: function open(element, name) {
    var _this = this;

    //reset if some exports exists on opening
    if (this.svg) this.reset();

    if (!element) element = this.context.element;
    if (!name) name = this.context.name;
    this.name = name;

    var width = parseInt(element.style("width"), 10) || 0;
    var height = parseInt(element.style("height"), 10) || 0;

    this.container = element.append("div").attr("class", "vzb-svg-export");
    this.svg = this.container.node().appendChild(element.select("svg").node().cloneNode(true));
    this.svg = d3.select(this.svg);
    this.svg.attr("viewBox", "0 0 " + width + " " + height).attr("version", "1.1").attr("param1", "http://www.w3.org/2000/svg").attr("param2", "http://www.w3.org/1999/xlink").attr("x", "0px").attr("y", "0px").attr("style", "enable-background:new " + "0 0 " + width + " " + height).attr("xml:space", "preserve");

    this.redBall = element.append("div").attr("class", "vzb-export-redball").style("position", "absolute").style("top", "20px").style("right", "20px").style("width", "20px").style("height", "20px").style("background", "red").style("color", "white").style("text-align", "center").style("border-radius", "10px").style("font-size", "14px").style("line-height", "20px").style("opacity", .8).style("cursor", "pointer").on("mouseover", function () {
      d3.select(this).style("opacity", 1).text("▼");
      _this.counterEl.text("Download");
    }).on("mouseout", function () {
      d3.select(this).style("opacity", .8).text("");
      _this.counterEl.text(_this.label);
    }).on("click", function () {
      _this.close();
    });

    this.counterEl = element.append("div").attr("class", "vzb-export-counter").style("position", "absolute").style("top", "20px").style("right", "45px").style("color", "red").style("opacity", .8).style("line-height", "20px").style("font-size", "14px").style("text-align", "center");

    this.root = this.svg.select("." + _prefix + "graph");

    this.root.selectAll("g, text, svg, line, rect").filter(function () {
      var view = d3.select(this);
      var result = false;
      _deleteClasses.forEach(function (one) {
        result = result || view.classed(one);
      });
      return result;
    }).remove();

    this.svg.selectAll(".tick line").attr("fill", "none").attr("stroke", "#999");
    this.svg.selectAll("." + _prefix + "axis-x path").attr("fill", "none").attr("stroke", "#999");
    this.svg.selectAll("." + _prefix + "axis-y path").attr("fill", "none").attr("stroke", "#999");
  },

  write: function write(me) {
    var groupBy = "time";

    if (!this.root) this.open();

    //avoid writing the same thing again
    if (this.shapes.indexOf(me.id + "_" + me.time) > -1) return;

    this.shapes.push(me.id + "_" + me.time);

    // check if need to create a new group and do so
    if (this.groups.indexOf(me[groupBy]) == -1) {
      this.root.append("g").attr("id", "g_" + me[groupBy]);
      this.groups.push(me[groupBy]);
    }

    // put a marker into the group
    if (me.opacity == null) me.opacity = .5;
    if (me.fill == null) me.fill = "#ff80dd";

    var marker = this.root.select("#g_" + me[groupBy]).append(me.type).attr("id", me.id + "_" + me.time).style("fill", me.fill).style("opacity", me.opacity);

    switch (me.type) {
      case "path":
        marker.attr("d", me.d);
        break;

      case "circle":
        marker.attr("cx", me.cx).attr("cy", me.cy).attr("r", me.r);
        break;
    }

    this.counter++;
    this.redBall.style("opacity", this.counter % 10 / 12 + .2);
    this.label = me.type + " shapes: " + this.counter;
    this.counterEl.text(this.label);
  },

  close: function close() {

    var result = SVGHEADER + " " + this.container.node().innerHTML.replace("param1", "xmlns").replace("param2", "xmlns:xlink")
    //round all numbers in SVG code
    .replace(/\d+(\.\d+)/g, function (x) {
      return Math.round(+x * 100) / 100 + "";
    });

    if (result.length / 1024 / 1024 > 2) {

      alert("The file size is " + Math.round(result.length / 1024) + "kB, which is too large to download. Will try to print it in the console instead...");
      console.log(result);
    } else {

      var link = document.createElement('a');
      link.download = this.name + " " + this.counter + " shapes" + ".svg";
      link.href = 'data:,' + result;
      link.click();
    }
  }

});

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _hook = __webpack_require__(48);

var _hook2 = _interopRequireDefault(_hook);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*!
 * VIZABI Color Model (hook)
 */

var defaultPalettes = {
  "_continuous": {
    "_default": "#ffb600",
    "0": "#B4DE79",
    "50": "#E1CE00",
    "100": "#F77481"
  },
  "_discrete": {
    "_default": "#ffb600",
    "0": "#bcfa83",
    "1": "#4cd843",
    "2": "#ff8684",
    "3": "#e83739",
    "4": "#ffb04b",
    "5": "#ff7f00",
    "6": "#f599f5",
    "7": "#c027d4",
    "8": "#f4f459",
    "9": "#d66425",
    "10": "#7fb5ed",
    "11": "#0ab8d8"
  },
  "_default": {
    "_default": "#93daec"
  }
};

var ColorModel = _hook2.default.extend({

  /**
   * Default values for this model
   */
  getClassDefaults: function getClassDefaults() {
    var defaults = {
      use: "constant",
      which: "_default",
      scaleType: "ordinal",
      syncModels: [],
      palette: {},
      paletteLabels: null,
      allow: {
        //this is almost everything, but not "nominal", so no random strings like "name"
        scales: ["linear", "log", "genericLog", "time", "pow", "ordinal"]
      }
    };
    return utils.deepExtend(this._super(), defaults);
  },

  /**
   * Initializes the color hook
   * @param {Object} values The initial values of this model
   * @param parent A reference to the parent model
   * @param {Object} bind Initial events to bind
   */
  init: function init(name, values, parent, bind) {
    var _this = this;
    this._type = "color";

    this._super(name, values, parent, bind);

    this._syncModelReferences = {};
    this._hasDefaultColor = false;

    this.on('hook_change', function () {
      if (_this._readyOnce) return;

      if (_this.palette && Object.keys(_this.palette._data).length !== 0) {
        var defaultPalette = _this.getDefaultPalette();
        var currentPalette = _this.getPalette(true);
        var palette = {};
        //extend partial current palette with default palette and
        //switch current palette elements which equals
        //default palette elments to nonpersistent state
        Object.keys(defaultPalette).map(function (key) {
          if (!currentPalette[key] || defaultPalette[key] == currentPalette[key]) palette[key] = defaultPalette[key];
        });
        _this.set("palette", palette, false, false);
      }
    });
  },

  setInterModelListeners: function setInterModelListeners() {
    this._super();
    this._setSyncModels();
  },

  // args: {colorID, shadeID}
  getColorShade: function getColorShade(args) {
    var palette = this.getPalette();

    if (!args) return utils.warn("getColorShade() is missing arguments");

    // if colorID is not given or not found in the palette, replace it with default color
    if (!args.colorID || !palette[args.colorID]) args.colorID = "_default";

    // if the resolved colr value is not an array (has only one shade) -- return it
    if (!utils.isArray(palette[args.colorID])) return palette[args.colorID];

    var conceptpropsColor = this.getConceptprops().color;
    var shade = args.shadeID && conceptpropsColor && conceptpropsColor.shades && conceptpropsColor.shades[args.shadeID] ? conceptpropsColor.shades[args.shadeID] : 0;

    return palette[args.colorID][shade];
  },

  /**
   * Get the above constants
   */
  isUserSelectable: function isUserSelectable() {
    var conceptpropsColor = this.getConceptprops().color;
    return conceptpropsColor == null || conceptpropsColor.selectable == null || conceptpropsColor.selectable;
  },

  setWhich: function setWhich(newValue) {
    this._super(newValue);
    if (this.palette) this.palette._data = {};
    this._setSyncModels();
  },

  _setSyncModels: function _setSyncModels() {
    var _this = this;
    this.syncModels.forEach(function (modelName) {
      //fetch the model to sync, it's marker and entities
      var model = _this.getClosestModel(modelName);
      var marker = model.isHook() ? model._parent : model;
      var entities = marker.getClosestModel(marker.space[0]);

      //save the references here locally
      _this._syncModelReferences[modelName] = { model: model, marker: marker, entities: entities };

      if (_this.isDiscrete()) _this._setSyncModel(model, marker, entities);
    });
  },

  _setSyncModel: function _setSyncModel(model, marker, entities) {
    if (model == marker) {
      var newFilter = {
        dim: this.which,
        show: {}
      };
      marker.setDataSourceForAllSubhooks(this.data);
      entities.set(newFilter, false, false);
    } else {
      if (model.isDiscrete() && model.use !== "constant") model.set({ which: this.which, data: this.data }, false, false);
    }
  },

  getColorlegendMarker: function getColorlegendMarker() {
    return (this._syncModelReferences["marker_colorlegend"] || {})["marker"];
  },

  getColorlegendEntities: function getColorlegendEntities() {
    return (this._syncModelReferences["marker_colorlegend"] || {})["entities"];
  },

  /**
   * set color
   */
  setColor: function setColor(value, pointer) {
    var temp = this.getPalette();
    temp[pointer] = value;
    this.scale.range(utils.values(temp));
    this.palette[pointer] = value;
  },

  /**
   * maps the value to this hook's specifications
   * @param value Original value
   * @returns hooked value
   */
  mapValue: function mapValue(value) {
    //if the property value does not exist, supply the _default
    // otherwise the missing value would be added to the domain
    if (this.scale != null && this.isDiscrete() && this._hasDefaultColor && this.scale.domain().indexOf(value) == -1) value = "_default";
    return this._super(value);
  },

  getDefaultPalette: function getDefaultPalette() {
    var conceptpropsColor = this.getConceptprops().color;
    var palette;

    this.discreteDefaultPalette = false;

    if (conceptpropsColor && conceptpropsColor.palette) {
      //specific color palette from hook concept properties
      palette = utils.clone(conceptpropsColor.palette);
    } else if (defaultPalettes[this.which]) {
      //color palette for this.which exists in palette defaults
      palette = utils.clone(defaultPalettes[this.which]);
    } else if (this.use === "constant") {
      //an explicit hex color constant #abc or #adcdef is provided
      if (/^#([0-9a-f]{3}|[0-9a-f]{6})$/.test(this.which)) {
        palette = { "_default": this.which };
      } else {
        palette = utils.clone(defaultPalettes["_default"]);
      }
    } else {
      palette = utils.clone(defaultPalettes[this.isDiscrete() ? "_discrete" : "_continuous"]);
      this.discreteDefaultPalette = true;
    }

    return palette;
  },

  _getPaletteLabels: function _getPaletteLabels() {
    var conceptpropsColor = this.getConceptprops().color;
    var paletteLabels = null;

    if (conceptpropsColor && conceptpropsColor.paletteLabels) {
      //specific color palette from hook concept properties
      paletteLabels = utils.clone(conceptpropsColor.paletteLabels);
    }
    return paletteLabels;
  },

  getPaletteLabels: function getPaletteLabels() {
    return this.paletteLabels.getPlainObject();
  },

  getPalette: function getPalette(includeDefault) {
    //rebuild palette if it's empty
    if (!this.palette || Object.keys(this.palette._data).length === 0) {
      var palette = this.getDefaultPalette();
      this.set("palette", palette, false, false);
      var paletteLabels = this._getPaletteLabels();
      this.set("paletteLabels", paletteLabels, false, false);
    }
    var palette = this.palette.getPlainObject();
    if (this.use === "indicator" && !includeDefault) {
      delete palette["_default"];
    }
    return palette;
  },

  /**
   * Gets the domain for this hook
   * @returns {Array} domain
   */
  buildScale: function buildScale() {
    var scaleType = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.scaleType;

    var _this = this;

    var paletteObject = _this.getPalette();
    var domain = Object.keys(paletteObject);
    var range = utils.values(paletteObject);

    this._hasDefaultColor = domain.indexOf("_default") > -1;

    if (scaleType == "time") {

      var timeMdl = this._space.time;
      var limits = timeMdl.splash ? { min: timeMdl.parse(timeMdl.startOrigin), max: timeMdl.parse(timeMdl.endOrigin) } : { min: timeMdl.start, max: timeMdl.end };

      var singlePoint = limits.max - limits.min == 0;

      domain = domain.sort(function (a, b) {
        return a - b;
      });
      range = domain.map(function (m) {
        return singlePoint ? paletteObject[domain[0]] : paletteObject[m];
      });
      domain = domain.map(function (m) {
        return limits.min.valueOf() + m / 100 * (limits.max.valueOf() - limits.min.valueOf());
      });

      this.scale = d3.time.scale.utc().domain(domain).range(range).interpolate(d3.interpolateRgb);
    } else if (!this.isDiscrete()) {

      var limits = this.getLimits(this.which);
      //default domain is based on limits
      limits = [limits.min, limits.max];
      //domain from concept properties can override it if defined
      limits = this.getConceptprops().domain ? this.getConceptprops().domain : limits;

      var singlePoint = limits[1] - limits[0] == 0;

      domain = domain.sort(function (a, b) {
        return a - b;
      });
      range = domain.map(function (m) {
        return singlePoint ? paletteObject[domain[0]] : paletteObject[m];
      });
      domain = domain.map(function (m) {
        return limits[0] + m / 100 * (limits[1] - limits[0]);
      });

      if (d3.min(domain) <= 0 && d3.max(domain) >= 0 && scaleType === "log") scaleType = "genericLog";

      if (scaleType == "log" || scaleType == "genericLog") {
        var s = d3.scale.genericLog().domain(limits).range(limits);
        domain = domain.map(function (d) {
          return s.invert(d);
        });
      }
      this.scale = d3.scale[scaleType]().domain(domain).range(range).interpolate(d3.interpolateRgb);
    } else {
      range = range.map(function (m) {
        return utils.isArray(m) ? m[0] : m;
      });

      scaleType = "ordinal";

      if (this.discreteDefaultPalette) domain = domain.concat(this.getUnique(this.which));
      this.scale = d3.scale[scaleType]().domain(domain).range(range);
    }

    this.scaleType = scaleType;
  }

});

exports.default = ColorModel;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _model = __webpack_require__(46);

var _model2 = _interopRequireDefault(_model);

var _reader = __webpack_require__(71);

var _reader2 = _interopRequireDefault(_reader);

var _events = __webpack_require__(45);

var _events2 = _interopRequireDefault(_events);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*
 * VIZABI Data Model (model.data)
 */

var DataModel = _model2.default.extend({

  /**
   * Default values for this model
   */
  getClassDefaults: function getClassDefaults() {
    var defaults = {
      reader: "csv"
    };
    return utils.deepExtend(this._super(), defaults);
  },

  trackInstances: true,

  /**
   * Initializes the data model.
   * @param {Object} values The initial values of this model
   * @param parent A reference to the parent model
   * @param {Object} bind Initial events to bind
   */
  init: function init(name, values, parent, bind) {

    this._type = "data";

    this.queryQueue = {};
    this._collection = {};
    this._collectionPromises = {}; // stores promises, making sure we don't do one calulation twice

    //same constructor as parent, with same arguments
    this._super(name, values, parent, bind);

    this.readerObject = this.getReader();
  },

  /**
   * Loads concept properties when all other models are also starting to load data
   * @return {Promise} Promise which resolves when concepts are loaded
   */
  preloadData: function preloadData() {
    return this.loadConceptProps();
  },

  /**
   * Loads resource from reader or cache
   * @param {Array} query Array with queries to be loaded
   * @param {Object} parsers An object with concepts as key and parsers as value
   * @param {*} evts ?
   */
  load: function load(query) {
    var _this2 = this;

    var parsers = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};


    // add waffle server specific query clauses if set
    if (this.dataset) query.dataset = this.dataset;
    if (this.version) query.version = this.version;

    var dataId = this.getDataId(query);

    if (dataId) {
      return Promise.resolve(dataId);
    } else {
      utils.timeStamp('Vizabi Data: Loading Data');
      _events2.default.freezeAll(['hook_change', 'resize']);
      return this.loadFromReader(query, parsers).then(function (dataId) {
        _events2.default.unfreezeAll();
        return dataId;
      }).catch(function (error) {
        return _this2.handleReaderError(error, query);
      });
    }
  },

  /**
   * Loads resource from reader
   * @param {Array} query Array with queries to be loaded
   * @param {Object} parsers An object with concepts as key and parsers as value
   */
  loadFromReader: function loadFromReader(query, parsers) {
    var _this = this;

    var dataId = utils.hashCode([query]);
    var queryMergeId = utils.hashCode([query.select.key, query.where, query.join]);

    if (this.queryQueue[queryMergeId]) {

      // add select to base query and return the base query promise
      Array.prototype.push.apply(this.queryQueue[queryMergeId].query.select.value, query.select.value);
      utils.extend(this.queryQueue[queryMergeId].parsers, parsers);
      return this.queryQueue[queryMergeId].promise;
    } else {

      // set up base query
      var promise = new Promise(function (resolve, reject) {

        // wait one execution round for the queue to fill up
        utils.defer(function () {
          // now the query queue is filled with all queries from one execution round

          // remove double columns from select (resulting from merging)
          // no double columns in formatter because it's an object, extend would've overwritten doubles
          query.select.value = utils.unique(query.select.value);

          // execute the query with this reader
          _this.readerObject.read(query, parsers).then(function (response) {

            //success reading
            _this.checkQueryResponse(query, response);

            _this._collection[dataId] = {};
            _this._collectionPromises[dataId] = {};
            var col = _this._collection[dataId];
            col.data = response;
            col.valid = {};
            col.nested = {};
            col.unique = {};
            col.limits = {};
            col.frames = {};
            col.haveNoDataPointsPerKey = {};
            col.query = query;
            // col.sorted = {}; // TODO: implement this for sorted data-sets, or is this for the server/(or file reader) to handle?

            // remove query from queue
            _this.queryQueue[queryMergeId] = null;
            resolve(dataId);
          }, //error reading
          function (err) {
            _this.queryQueue[queryMergeId] = null;
            reject(err);
          });
        });
      });

      this.queryQueue[queryMergeId] = {
        query: query,
        parsers: parsers,
        promise: promise
      };

      return this.queryQueue[queryMergeId].promise;
    }
  },

  getReader: function getReader() {
    // Create a new reader for this query
    var readerClass = _reader2.default.get(this.reader);
    if (!readerClass) {
      throw new Error('Unknown reader: ' + this.reader);
    }

    return new readerClass({
      path: this.path,
      delimiter: this.delimiter,
      keySize: this.keySize
    });
  },

  checkQueryResponse: function checkQueryResponse(query, response) {
    if (response.length == 0) utils.warn("Reader for data source '" + this._name + "' returned empty array for query:", JSON.stringify(query, null, 2));

    if (response.length > 0) {
      // search data for the entirely missing columns
      var columnsMissing = (query.select.key || []).concat(query.select.value || []);
      for (var i = response.length - 1; i >= 0; i--) {
        for (var c = columnsMissing.length - 1; c >= 0; c--) {
          // if found value for column c in row i then remove that column name from the list of missing columns
          if (response[i][columnsMissing[c]] || response[i][columnsMissing[c]] === 0) columnsMissing.splice(c, 1);
        }
        // all columns were found to have value in at least one of the rows then stop iterating
        if (!columnsMissing.length) break;
      }
      columnsMissing.forEach(function (d) {
        if (query.select.key.indexOf(d) == -1) {
          utils.warn('Reader result: Column "' + d + '" is missing from "' + query.from + '" data, but it might be ok');
        } else {
          utils.error('Reader result: Key column "' + d + '" is missing from "' + query.from + '" data for query:', JSON.stringify(query));
          console.log(response);
        }
      });
    }
  },

  /**
   * get data
   */
  getData: function getData(dataId, what, whatId, args) {
    // if not specified data from what query, return nothing
    if (!dataId) return utils.warn("Data.js 'get' method doesn't like the dataId you gave it: " + dataId);

    // if they want data, return the data
    if (!what || what == 'data') {
      return this._collection[dataId]['data'];
    }

    // if they didn't give an instruction, give them the whole thing
    // it's probably old code which modifies the data outside this class
    // TODO: move these methods inside (e.g. model.getNestedItems())
    if (!whatId) {
      return this._collection[dataId][what];
    }

    // if they want a certain processing of the data, see if it's already in cache
    var id = typeof whatId == "string" ? whatId : JSON.stringify(whatId);
    if (this._collection[dataId][what][id]) {
      return this._collection[dataId][what][id];
    }

    // if it's not cached, process the data and then return it
    switch (what) {
      case 'unique':
        this._collection[dataId][what][id] = this._getUnique(dataId, whatId);
        break;
      case 'valid':
        this._collection[dataId][what][id] = this._getValid(dataId, whatId);
        break;
      case 'limits':
        this._collection[dataId][what][id] = this._getLimits(dataId, whatId);
        break;
      case 'nested':
        this._collection[dataId][what][id] = this._getNested(dataId, whatId);
        break;
      case 'haveNoDataPointsPerKey':
        //do nothing. no caching is available for this option, served directly from collection
        break;
    }
    return this._collection[dataId][what][id];
  },

  loadConceptProps: function loadConceptProps() {
    var _this3 = this;

    var query = {
      select: {
        key: ['concept'],
        value: ['concept_type', 'domain', 'indicator_url', 'color', 'scales', 'interpolation', 'tags', 'name', 'unit', 'description']
      },
      from: 'concepts',
      where: {},
      language: this.getClosestModel('locale').id
    };

    return this.load(query).then(this.handleConceptPropsResponse.bind(this)).catch(function (error) {
      return _this3.handleReaderError(error, query);
    });
  },


  handleConceptPropsResponse: function handleConceptPropsResponse(dataId) {
    var _this4 = this;

    this.conceptDictionary = { _default: { concept_type: "string", use: "constant", scales: ["ordinal"], tags: "_root" } };
    this.conceptArray = [];

    this.getData(dataId).forEach(function (d) {
      var concept = {};

      if (d.concept_type) concept["use"] = d.concept_type == "measure" || d.concept_type == "time" ? "indicator" : "property";

      concept["concept_type"] = d.concept_type;
      concept["sourceLink"] = d.indicator_url;
      try {
        concept["color"] = d.color && d.color !== "" ? JSON.parse(d.color) : null;
      } catch (e) {
        concept["color"] = null;
      }
      try {
        concept["scales"] = d.scales ? JSON.parse(d.scales) : null;
      } catch (e) {
        concept["scales"] = null;
      }
      if (!concept.scales) {
        switch (d.concept_type) {
          case "measure":
            concept.scales = ["linear", "log"];break;
          case "string":
            concept.scales = ["nominal"];break;
          case "entity_domain":
            concept.scales = ["ordinal"];break;
          case "entity_set":
            concept.scales = ["ordinal"];break;
          case "time":
            concept.scales = ["time"];break;
        }
      }
      if (concept["scales"] == null) concept["scales"] = ["linear", "log"];
      if (d.interpolation) {
        concept["interpolation"] = d.interpolation;
      } else if (d.concept_type == "measure") {
        concept["interpolation"] = concept.scales && concept.scales[0] == "log" ? "exp" : "linear";
      } else if (d.concept_type == "time") {
        concept["interpolation"] = "linear";
      } else {
        concept["interpolation"] = "stepMiddle";
      }
      concept["concept"] = d.concept;
      concept["domain"] = d.domain;
      concept["tags"] = d.tags;
      concept["name"] = d.name || d.concept || "";
      concept["unit"] = d.unit || "";
      concept["description"] = d.description;
      _this4.conceptDictionary[d.concept] = concept;
      _this4.conceptArray.push(concept);
    });
  },

  getConceptprops: function getConceptprops(which) {
    if (which) {
      if (this.conceptDictionary[which]) {
        return this.conceptDictionary[which];
      } else {
        return utils.warn("The concept " + which + " is not found in the dictionary");
      }
    } else {
      return this.conceptDictionary;
    }
  },

  getConceptByIndex: function getConceptByIndex(index, type) {
    var concept = this.conceptArray.filter(function (f) {
      return !type || !f.concept_type || f.concept_type === type;
    })[index];
    if (!concept && type == "measure") concept = this.conceptArray.filter(function (f) {
      return f.concept_type === "time";
    })[0];
    return concept;
  },

  getDatasetName: function getDatasetName() {
    if (this.readerObject.getDatasetInfo) {
      var meta = this.readerObject.getDatasetInfo();
      return meta.name + (meta.version ? " " + meta.version : "");
    }
    return this._name;
  },

  _getCacheKey: function _getCacheKey(frames, keys) {
    var result = frames[0] + " - " + frames[frames.length - 1];
    if (keys) {
      result = result + "_" + keys.join();
    }
    return result;
  },

  getFrames: function getFrames(dataId, framesArray, keys) {
    var _this = this;
    var whatId = this._getCacheKey(framesArray, keys);
    if (!this._collectionPromises[dataId][whatId]) {
      this._collectionPromises[dataId][whatId] = {
        queue: this.framesQueue(framesArray, whatId),
        promise: null
      };
    }
    if (this._collectionPromises[dataId][whatId] && this._collectionPromises[dataId][whatId]["promise"] instanceof Promise) {
      return this._collectionPromises[dataId][whatId]["promise"];
    } else {
      this._collectionPromises[dataId][whatId]["promise"] = new Promise(function (resolve, reject) {
        if (!dataId) reject(utils.warn("Data.js 'get' method doesn't like the dataId you gave it: " + dataId));
        _this._getFrames(dataId, whatId, framesArray, keys).then(function (frames) {
          _this._collection[dataId]["frames"][whatId] = frames;
          resolve(_this._collection[dataId]["frames"][whatId]);
        });
      });
    }
    return this._collectionPromises[dataId][whatId]["promise"];
  },

  getFrame: function getFrame(dataId, framesArray, neededFrame, keys) {
    //can only be called after getFrames()
    var _this = this;
    var whatId = this._getCacheKey(framesArray, keys);
    return new Promise(function (resolve, reject) {
      if (_this._collection[dataId]["frames"][whatId] && _this._collection[dataId]["frames"][whatId][neededFrame]) {
        resolve(_this._collection[dataId]["frames"][whatId]);
      } else {
        _this._collectionPromises[dataId][whatId]["queue"].forceFrame(neededFrame, function () {
          resolve(_this._collection[dataId]["frames"][whatId]);
        });
      }
    });
  },

  listenFrame: function listenFrame(dataId, framesArray, keys, cb) {
    var _this = this;
    var whatId = this._getCacheKey(framesArray, keys);
    this._collectionPromises[dataId][whatId]["queue"].defaultCallbacks.push(function (time) {
      cb(dataId, time);
    });
    if (this._collection[dataId]["frames"][whatId]) {
      utils.forEach(this._collection[dataId]["frames"][whatId], function (frame, key) {
        cb(dataId, new Date(key));
      });
    }
  },

  _muteAllQueues: function _muteAllQueues(except) {
    utils.forEach(this._collectionPromises, function (queries, dataId) {
      utils.forEach(queries, function (promise, whatId) {
        if (promise.queue.isActive == true && promise.queue.whatId != except) {
          promise.queue.mute();
        }
      });
    });
  },

  _checkForcedQueuesExists: function _checkForcedQueuesExists() {
    utils.forEach(this._collectionPromises, function (queries, dataId) {
      utils.forEach(queries, function (promise, whatId) {
        if (promise.queue.forcedQueue.length > 0) {
          promise.queue.unMute();
        }
      });
    });
  },

  _unmuteQueue: function _unmuteQueue() {
    utils.forEach(this._collectionPromises, function (queries, dataId) {
      utils.forEach(queries, function (promise, whatId) {
        if (promise.queue.isActive == false) {
          promise.queue.unMute();
        }
      });
    });
  },
  /**
   * set priority for generate each year frame
   * @param framesArray
   * @returns {*}
   */
  framesQueue: function framesQueue(framesArray, whatId) {
    var _context = this;
    return new function () {
      this.defaultCallbacks = [];
      this.callbacks = {};
      this.forcedQueue = [];
      this.isActive = true;
      this.delayedAction = null;
      this.whatId = whatId;
      this.queue = framesArray.slice(0); //clone array
      var queue = this;
      //put the last element to the start of the queue because we are likely to need it first
      this.queue.splice(0, 0, this.queue.splice(this.queue.length - 1, 1)[0]);
      this.key = 0;
      this.mute = function () {
        var _this = this;
        this.isActive = false;
        new Promise(function (resolve, reject) {
          _this.delayedAction = resolve;
        });
      };

      this.unMute = function () {
        this.isActive = true;
        if (typeof this.delayedAction == "function") {
          this.delayedAction();
        }
        this.delayedAction = null;
        if (this.forcedQueue.length == 0 && this.queue.length == 0) {
          _context._unmuteQueue();
        }
      };
      this.frameComplete = function (frameName) {
        //function called after build each frame with name of frame build
        var i;
        if (queue.defaultCallbacks.length > 0) {
          for (i = 0; i < queue.defaultCallbacks.length; i++) {
            queue.defaultCallbacks[i](frameName);
          }
        }
        if (queue.callbacks[frameName] && queue.callbacks[frameName].length > 0) {
          for (i = 0; i < queue.callbacks[frameName].length; i++) {
            queue.callbacks[frameName][i]();
          }
        }
      };
      this._waitingForActivation = function () {
        var _this = this;
        return new Promise(function (resolve, reject) {
          if (_this.isActive) {
            return resolve();
          }
          _this.delayedAction = resolve;
        });
      };

      this._getNextFrameName = function () {
        var frameName = null;
        if (this.forcedQueue.length > 0 || this.queue.length > 0) {
          if (this.forcedQueue.length > 0) {
            frameName = this.forcedQueue.shift();
          } else {
            if (this.forcedQueue.length == 0 && this.key >= this.queue.length - 1) {
              this.key = 0;
            }
            frameName = this.queue.splice(this.key, 1).pop();
          }
        } else {
          _context._unmuteQueue();
        }
        return frameName;
      };
      this.checkForcedFrames = function () {
        if (this.forcedQueue.length > 0) return;
        _context._checkForcedQueuesExists();
      };

      // returns the next frame in a queue
      this.getNext = function () {
        var _this = this;
        return new Promise(function (resolve, reject) {
          _this.checkForcedFrames();
          if (_this.isActive) {
            resolve(_this._getNextFrameName());
          } else {
            _this._waitingForActivation().then(function () {
              resolve(_this._getNextFrameName());
            });
          }
        });
      };

      // force the particular frame up the queue
      this.forceFrame = function (frameName, cb) {
        var objIndexOf = function objIndexOf(obj, need) {
          var search = need.toString();
          var index = -1;
          for (var i = 0, len = obj.length; i < len; i++) {
            if (obj[i].toString() == search) {
              index = i;
              break;
            }
          }
          return index;
        };
        if (this.callbacks[frameName]) {

          this.callbacks[frameName].push(cb);
        } else {
          var newKey = objIndexOf(this.queue, frameName); //this.queue.indexOf(frameName.toString());
          if (newKey !== -1) {
            this.forcedQueue.unshift(this.queue.splice(newKey, 1).pop());
            _context._muteAllQueues(this.whatId);
            this.unMute();
            if (typeof cb === "function") {
              if (_typeof(this.callbacks[frameName]) != "object") {
                this.callbacks[frameName] = [];
              }
              this.callbacks[frameName].push(cb);
            }
            this.key = newKey; //set key to next year after gorced element (preload if user click play)
          } else {
            if (_typeof(this.callbacks[frameName]) === "object") {
              this.callbacks[frameName].push(cb);
            } else {
              this.callbacks[frameName] = [cb];
            }
          }
        }
      };
    }();
  },

  /**
   * Get regularised dataset (where gaps are filled)
   * @param {Number} dataId hash code for query
   * @param {String} whatId hash code for cache
   * @param {Array} framesArray -- array of keyframes across animatable
   * @param {Array} keys -- array of keys
   * @returns {Object} regularised dataset, nested by [animatable, column, key]
   */
  _getFrames: function _getFrames(dataId, whatId, framesArray, keys) {
    var _this = this;

    if (!_this._collection[dataId]["frames"][whatId]) {
      _this._collection[dataId]["frames"][whatId] = {};
    }
    return new Promise(function (resolve, reject) {

      //TODO: thses should come from state or from outside somehow
      // FramesArray in the input contains the array of keyframes in animatable dimension.
      // Example: array of years like [1800, 1801 … 2100]
      // these will be the points where we need data
      // (some of which might already exist in the set. in regular datasets all the points would exist!)

      // Check if query.where clause is missing a time field

      var indicatorsDB = _this.getConceptprops();

      if (!indicatorsDB) utils.warn("_getFrames in data.js is missing indicatorsDB, it's needed for gap filling");
      if (!framesArray) utils.warn("_getFrames in data.js is missing framesArray, it's needed so much");

      var KEY = _this._collection[dataId].query.select.key[0];
      var TIME = _this._collection[dataId].query.animatable;

      var filtered = {};
      var items, itemsIndex, oneFrame, method, use, next;

      // We _nest_ the flat dataset in two levels: first by “key” (example: geo), then by “animatable” (example: year)
      // See the _getNested function for more details
      var nested = _this.getData(dataId, 'nested', [KEY, TIME]);
      keys = keys ? keys : Object.keys(nested);
      // Get the list of columns that are in the dataset, exclude key column and animatable column
      // Example: [“lex”, “gdp”, “u5mr"]
      var query = _this._collection[dataId].query;
      var columns = query.select.value.filter(function (f) {
        return f !== "_default";
      });

      var cLength = columns.length;
      var key, k, column, c;

      for (k = 0; k < keys.length; k++) {
        filtered[keys[k]] = {};
        for (c = 0; c < cLength; c++) {
          filtered[keys[k]][columns[c]] = null;
        }
      }
      for (c = 0; c < cLength; c++) {
        _this._collection[dataId].haveNoDataPointsPerKey[columns[c]] = {};
      }var buildFrame = function buildFrame(frameName, keys, dataId, callback) {
        var frame = {};
        if (query.from !== "datapoints") {
          // we populate the regular set with a single value (unpack properties into constant time series)
          var dataset = _this._collection[dataId].data;
          for (c = 0; c < cLength; c++) {
            frame[columns[c]] = {};
          }for (var i = 0; i < dataset.length; i++) {
            var d = dataset[i];
            for (c = 0; c < cLength; c++) {
              frame[columns[c]][d[KEY]] = d[columns[c]];
              //check data for properties with missed data. If founded then write key to haveNoDataPointsPerKey with
              //count of broken datapoints
              if (d[columns[c]] == null) {
                _this._collection[dataId].haveNoDataPointsPerKey[columns[c]][d[KEY]] = dataset.length;
              }
            }
          }
        } else {
          // If there is a time field in query.where clause, then we are dealing with indicators in this request

          // Put together a template for cached filtered sets (see below what's needed)

          // Now we run a 3-level loop: across frames, then across keys, then and across data columns (lex, gdp)

          for (c = 0; c < cLength; c++) {
            frame[columns[c]] = {};
          }for (k = 0; k < keys.length; k++) {
            key = keys[k];

            for (c = 0; c < cLength; c++) {
              column = columns[c];

              //If there are some points in the array with valid numbers, then
              //interpolate the missing point and save it to the “clean regular set”
              method = indicatorsDB[column] ? indicatorsDB[column].interpolation : null;
              use = indicatorsDB[column] ? indicatorsDB[column].use : "indicator";

              // Inside of this 3-level loop is the following:
              if (nested[key] && nested[key][frameName] && (nested[key][frameName][0][column] || nested[key][frameName][0][column] === 0)) {

                // Check if the piece of data for [this key][this frame][this column] exists
                // and is valid. If so, then save it into a “clean regular set”
                frame[column][key] = nested[key][frameName][0][column];
              } else if (method === "none") {

                // the piece of data is not available and the interpolation is set to "none"
                frame[column][key] = null;
              } else {
                // If the piece of data doesn’t exist or is invalid, then we need to inter- or extapolate it

                // Let’s take a slice of the nested set, corresponding to the current key nested[key]
                // As you remember it has the data nested further by frames.
                // At every frame the data in the current column might or might not exist.
                // Thus, let’s filter out all the frames which don’t have the data for the current column.
                // Let’s cache it because we will most likely encounter another gap in the same column for the same key
                items = filtered[key][column];
                if (items === null) {
                  var givenFrames = Object.keys(nested[key]);
                  items = new Array(givenFrames.length);
                  itemsIndex = 0;

                  for (var z = 0, length = givenFrames.length; z < length; z++) {
                    oneFrame = nested[key][givenFrames[z]];
                    if (oneFrame[0][column] || oneFrame[0][column] === 0) items[itemsIndex++] = oneFrame[0];
                  }

                  //trim the length of the array
                  items.length = itemsIndex;

                  if (itemsIndex === 0) {
                    filtered[key][column] = [];
                  } else {
                    filtered[key][column] = items;
                  }

                  if (items.length == 0) _this._collection[dataId].haveNoDataPointsPerKey[column][key] = items.length;
                }

                // Now we are left with a fewer frames in the filtered array. Let's check its length.
                //If the array is empty, then the entire column is missing for the key
                //So we let the key have missing values in this column for all frames
                if (items && items.length > 0) {
                  next = null;
                  frame[column][key] = utils.interpolatePoint(items, use, column, next, TIME, frameName, method);
                }
              }
            } //loop across columns
          } //loop across keys
        }

        // save the calcualted frame to global datamanager cache
        _this._collection[dataId]["frames"][whatId][frameName] = frame;

        // fire the callback
        if (typeof callback === "function") {
          // runs the function frameComplete inside framesQueue.getNext()
          callback(frameName);
        }

        // recursively call the buildFrame again, this time for the next frame
        //QUESTION: FramesArray is probably not needed at this point. dataId and whatId is enough
        _this._collectionPromises[dataId][whatId]["queue"].getNext().then(function (nextFrame) {
          if (nextFrame) {
            utils.defer(function () {
              buildFrame(nextFrame, keys, dataId, _this._collectionPromises[dataId][whatId]["queue"].frameComplete);
            });
          } else {
            //this goes to marker.js as a "response"
            resolve(_this._collection[dataId]["frames"][whatId]);
          }
        });
      };
      _this._collectionPromises[dataId][whatId]["queue"].getNext().then(function (nextFrame) {
        if (nextFrame) {
          buildFrame(nextFrame, keys, dataId, _this._collectionPromises[dataId][whatId]["queue"].frameComplete);
        }
      });
    });
  },

  _getNested: function _getNested(dataId, order) {
    // Nests are objects of key-value pairs
    // Example:
    //
    // order = ["geo", "time"];
    //
    // original_data = [
    //   { geo: "afg", time: 1800, gdp: 23424, lex: 23}
    //   { geo: "afg", time: 1801, gdp: 23424, lex: null}
    //   { geo: "chn", time: 1800, gdp: 23587424, lex: 46}
    //   { geo: "chn", time: 1801, gdp: null, lex: null}
    // ];
    //
    // nested_data = {
    //   afg: {
    //     1800: {gdp: 23424, lex: 23},
    //     1801: {gdp: 23424, lex: null}
    //   }
    //   chn: {
    //     1800: {gdp: 23587424, lex: 46 },
    //     1801: {gdp: null, lex: null }
    //   }
    // };

    var nest = d3.nest();
    for (var i = 0; i < order.length; i++) {
      nest = nest.key(function (k) {
        return function (d) {
          return d[k];
        };
      }(order[i]));
    };

    return utils.nestArrayToObj(nest.entries(this._collection[dataId]['data']));
  },

  _getUnique: function _getUnique(dataId, attr) {
    var uniq;
    var items = this._collection[dataId].data;
    //if it's an array, it will return a list of unique combinations.
    if (utils.isArray(attr)) {
      var values = items.map(function (d) {
        return utils.clone(d, attr); //pick attrs
      });
      uniq = utils.unique(values, function (n) {
        return JSON.stringify(n);
      });
    } //if it's a string, it will return a list of values
    else {
        var values = items.map(function (d) {
          return d[attr];
        });
        uniq = utils.unique(values);
      }
    return uniq;
  },

  _getValid: function _getValid(dataId, column) {
    return this._collection[dataId].data.filter(function (f) {
      return f[column] || f[column] === 0;
    });
  },

  _getLimits: function _getLimits(dataId, attr) {

    var items = this._collection[dataId].data;
    // get only column attr and only rows with number or date
    var filtered = items.reduce(function (filtered, d) {

      // check for dates
      var f = utils.isDate(d[attr]) ? d[attr] : parseFloat(d[attr]);

      // if it is a number
      if (!isNaN(f)) {
        filtered.push(f);
      }

      //filter
      return filtered;
    }, []);

    // get min/max for the filtered rows
    var min;
    var max;
    var limits = {};
    for (var i = 0; i < filtered.length; i += 1) {
      var c = filtered[i];
      if (typeof min === 'undefined' || c < min) {
        min = c;
      }
      if (typeof max === 'undefined' || c > max) {
        max = c;
      }
    }
    limits.min = min || 0;
    limits.max = max || 100;
    return limits;
  },

  /**
   * checks whether this combination is cached or not
   */
  getDataId: function getDataId(query) {
    //encode in hashCode
    var q = utils.hashCode([query]);
    //simply check if we have this in internal data
    if (Object.keys(this._collection).indexOf(q) !== -1) {
      return q;
    }
    return false;
  },

  handleReaderError: function handleReaderError(error, query) {
    if ((0, _utils.isObject)(error)) {
      var locale = this.getClosestModel('locale');
      var translation = locale.getTFunction()(error.code, error.payload) || '';
      error = (translation + ' ' + (error.message || '')).trim();
    }

    utils.warn('Problem with query: ', query);
    throw error;
  }
});

exports.default = DataModel;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _dataconnected = __webpack_require__(59);

var _dataconnected2 = _interopRequireDefault(_dataconnected);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*!
 * VIZABI Entities Model
 */

var EntitiesModel = _dataconnected2.default.extend({

  /**
   * Default values for this model
   */
  getClassDefaults: function getClassDefaults() {
    var defaults = {
      show: {},
      dim: null
    };
    return utils.deepExtend(this._super(), defaults);
  },

  objectLeafs: ['show', 'autogenerate'],
  dataConnectedChildren: ['show', 'dim'],

  /**
   * Initializes the entities model.
   * @param {Object} values The initial values of this model
   * @param parent A reference to the parent model
   * @param {Object} bind Initial events to bind
   */
  init: function init(name, values, parent, bind) {

    this._type = "entities";

    this._super(name, values, parent, bind);
  },

  afterPreload: function afterPreload() {
    if (this.dim == null && this.autogenerate) {
      var dataSource = this.getClosestModel(this.autogenerate.data);
      this.dim = dataSource.getConceptByIndex(this.autogenerate.conceptIndex).concept;
    }
  },

  /**
   * Gets the dimensions in this entities
   * @returns {String} String with dimension
   */
  getDimension: function getDimension() {
    return this.dim;
  },

  /**
   * Gets the filter in this entities
   * @returns {Array} Array of unique values
   */
  getFilter: function getFilter() {
    return this.show;
  },

  /**
   * Shows or unshows an entity from the set
   */
  showEntity: function showEntity(d) {
    //clear selected countries when showing something new
    var newShow = utils.deepClone(this.show);
    var dimension = this.getDimension();
    var value = d[dimension];
    var showArray = [];

    // get array from show
    if (this.show[dimension] && this.show[dimension]['$in'] && utils.isArray(this.show[dimension]['$in'])) showArray = this.show[dimension]['$in'];

    if (this.isShown(d)) {
      showArray = showArray.filter(function (d) {
        return d !== value;
      });
    } else {
      showArray = showArray.concat(value);
    }

    if (showArray.length === 0) delete newShow[dimension];else newShow[dimension] = { '$in': showArray };

    this.show = newShow;
  },

  /**
   * Selects an entity from the set
   * @returns {Boolean} whether the item is shown or not
   */
  isShown: function isShown(d) {
    var dimension = this.getDimension();
    return this.show[dimension] && this.show[dimension]['$in'] && this.show[dimension]['$in'].indexOf(d[dimension]) !== -1;
  },

  /**
   * Clears showing of items
   */
  clearShow: function clearShow() {
    var dimension = this.getDimension();
    var show = utils.deepClone(this.show);
    delete show[dimension];
    this.show = show;
  }

});

exports.default = EntitiesModel;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _hook = __webpack_require__(48);

var _hook2 = _interopRequireDefault(_hook);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*
 * VIZABI Group Model
 */

var GroupModel = _hook2.default.extend({

  /**
   * Default values for this model
   */
  getClassDefaults: function getClassDefaults() {
    var defaults = {
      use: null,
      which: null,
      merge: false,
      manualSorting: null
    };
    return utils.deepExtend(this._super(), defaults);
  },

  /**
   * Initializes the group hook
   * @param {Object} values The initial values of this model
   * @param parent A reference to the parent model
   * @param {Object} bind Initial events to bind
   */
  init: function init(name, values, parent, bind) {
    this._type = "model";

    this._super(name, values, parent, bind);
  },

  /**
   * Validates a color hook
   */
  validate: function validate() {
    //there must be no scale
    if (this.scale) this.scale = null;

    //use must be "property"
    if (this.use != "property") {
      utils.warn("group model: use must be 'property'. Resetting...");
      this.use = "property";
    }
  }

});

exports.default = GroupModel;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _hook = __webpack_require__(48);

var _hook2 = _interopRequireDefault(_hook);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*
 * VIZABI Data Model (options.data)
 */

var LabelModel = _hook2.default.extend({

  /**
   * Default values for this model
   */

  getClassDefaults: function getClassDefaults() {
    var defaults = {
      use: null,
      which: null
    };
    return utils.deepExtend(this._super(), defaults);
  },

  /**
   * Initializes the size hook
   * @param {Object} values The initial values of this model
   * @param parent A reference to the parent model
   * @param {Object} bind Initial events to bind
   */
  init: function init(name, values, parent, bind) {

    this._type = "label";

    this._super(name, values, parent, bind);
  }

});

exports.default = LabelModel;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _dataconnected = __webpack_require__(59);

var _dataconnected2 = _interopRequireDefault(_dataconnected);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

// this and many other locale information should at some point be stored in an external file with locale information (rtl, date formats etc)
var rtlLocales = ['ar', 'ar-SA'];

var LocaleModel = _dataconnected2.default.extend({

  /**
   * Default values for this model
   */
  getClassDefaults: function getClassDefaults() {
    var defaults = {
      id: "en",
      filePath: "assets/translation/"
    };
    return utils.deepExtend(this._super(), defaults);
  },

  dataConnectedChildren: ["id"],
  strings: {},

  /**
   * Initializes the locale model.
   * @param {Object} values The initial values of this model
   * @param parent A reference to the parent model
   * @param {Object} bind Initial events to bind
   */
  init: function init(name, values, parent, bind) {
    this._type = "locale";

    //same constructor, with same arguments
    this._super(name, values, parent, bind);
  },

  _isLoading: function _isLoading() {
    return !this._loadedOnce || this._loadCall;
  },

  preloadData: function preloadData() {
    return this.loadData();
  },


  loadData: function loadData() {
    var _this = this;

    var promises;

    this.setReady(false);
    this._loadCall = true;

    // load new concept properties for each data source.
    // this should be done with listeners, but the load promise can't be returned
    // through the listeners

    promises = [];
    utils.forEach(this._root._data, function (mdl) {
      if (mdl._type === "data") promises.push(mdl.loadConceptProps());
    });
    promises.push(new Promise(function (resolve, reject) {
      d3.json(_this.filePath + _this.id + ".json", function (error, strings) {
        if (error) reject(error);
        _this.handleNewStrings(strings);
        resolve();
      });
    }));

    return Promise.all(promises).then(function () {
      return _this.trigger('translate');
    });
  },

  handleNewStrings: function handleNewStrings(receivedStrings) {
    this.strings[this.id] = this.strings[this.id] ? utils.extend(this.strings[this.id], receivedStrings) : receivedStrings;
  },

  /**
   * Gets a certain UI string
   * @param {String} id string identifier
   * @returns {string} translated string
   */
  getUIString: function getUIString(stringId) {
    if (this.strings && this.strings[this.id] && (this.strings[this.id][stringId] || this.strings[this.id][stringId] === "")) {
      return this.strings[this.id][stringId];
    } else {
      if (!this.strings || !this.strings[this.id]) utils.warn("Strings are not loaded for the " + this.id + " locale. Check if translation JSON is valid");
      return stringId;
    }
  },

  /**
   * Gets the translation function
   * @returns {string} translation function
   */
  getTFunction: function getTFunction() {
    var _this2 = this;

    return function (stringId) {
      var payload = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
      return Object.keys(payload).reduce(function (result, key) {
        var regexp = new RegExp('{{' + key + '}}', 'g');
        return result.replace(regexp, payload[key]);
      }, _this2.getUIString(stringId));
    };
  },


  isRTL: function isRTL() {
    return rtlLocales.indexOf(this.id) !== -1;
  }

});

exports.default = LocaleModel;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _model = __webpack_require__(46);

var _model2 = _interopRequireDefault(_model);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*!
 * HOOK MODEL
 */

var Marker = _model2.default.extend({

  getClassDefaults: function getClassDefaults() {
    var defaults = {
      select: [],
      highlight: [],
      opacityHighlightDim: 0.1,
      opacitySelectDim: 0.3,
      opacityRegular: 1,
      allowSelectMultiple: true
    };
    return utils.deepExtend(this._super(), defaults);
  },

  init: function init(name, value, parent, binds, persistent) {
    this._visible = [];

    this._super(name, value, parent, binds, persistent);
    this.on('ready', this.checkTimeLimits.bind(this));
  },

  setDataSourceForAllSubhooks: function setDataSourceForAllSubhooks(data) {
    var obj = {};
    this.getSubhooks().forEach(function (hook) {
      obj[hook._name] = { data: data };
    });
    this.set(obj, null, false);
  },

  /**
   * Validates the model
   */
  validate: function validate() {
    var _this = this;
    var dimension = this.getDimension();
    var visible_array = this._visible.map(function (d) {
      return d[dimension];
    });

    if (visible_array.length) {
      this.select = this.select.filter(function (f) {
        return visible_array.indexOf(f[dimension]) !== -1;
      });
      this.setHighlight(this.highlight.filter(function (f) {
        return visible_array.indexOf(f[dimension]) !== -1;
      }));
    }
  },

  /**
   * Sets the visible entities
   * @param {Array} arr
   */
  setVisible: function setVisible(arr) {
    this._visible = arr;
  },

  /**
   * Gets the visible entities
   * @returns {Array} visible
   */
  getVisible: function getVisible(arr) {
    return this._visible;
  },

  /**
   * Gets the selected items
   * @returns {Array} Array of unique selected values
   */
  getSelected: function getSelected(dim) {
    if (dim) return this.select.map(function (d) {
      return d[dim];
    });else return this.select;
  },

  selectMarker: function selectMarker(d) {
    var _this = this;
    var value = this._createValue(d);
    if (this.isSelected(d)) {
      this.select = this.select.filter(function (d) {
        return JSON.stringify(_this._createValue(d)) !== JSON.stringify(value);
      });
    } else {
      this.select = this.allowSelectMultiple ? this.select.concat(value) : [value];
    }
  },

  /**
   * Select all entities
   */
  selectAll: function selectAll(timeDim, timeFormatter) {
    if (!this.allowSelectMultiple) return;

    var added,
        dimension = this.getDimension();

    var select = this._visible.map(function (d) {
      added = {};
      added[dimension] = d[dimension];
      return added;
    });

    this.select = select;
  },

  isSelected: function isSelected(d) {
    var _this = this;
    var value = this._createValue(d);

    return this.select.map(function (d) {
      return JSON.stringify(_this._createValue(d)) === JSON.stringify(value);
    }).indexOf(true) !== -1;
  },

  _createValue: function _createValue(d) {
    var dims = this._getAllDimensions({ exceptType: 'time' });
    return dims.reduce(function (value, key) {
      value[key] = d[key];
      return value;
    }, {});
  },

  /**
   * Gets the highlighted items
   * @returns {Array} Array of unique highlighted values
   */
  getHighlighted: function getHighlighted(dim) {
    if (dim) return this.highlight.map(function (d) {
      return d[dim];
    });else return this.highlight;
  },

  setHighlight: function setHighlight(arg) {
    if (!utils.isArray(arg)) {
      this.setHighlight([].concat(arg));
      return;
    }
    this.getModelObject('highlight').set(arg, false, false); // highlights are always non persistent changes
  },

  setSelect: function setSelect(arg) {
    if (!utils.isArray(arg)) {
      this.setSelect([].concat(arg));
      return;
    }
    this.getModelObject('select').set(arg);
  },

  //TODO: join the following 3 methods with the previous 3

  /**
   * Highlights an entity from the set
   */
  highlightMarker: function highlightMarker(d) {
    var value = this._createValue(d);
    if (!this.isHighlighted(d)) {
      this.setHighlight(this.highlight.concat(value));
    }
  },

  /**
   * Unhighlights an entity from the set
   */
  unhighlightEntity: function unhighlightEntity(d) {
    var value = this._createValue(d);
    if (this.isHighlighted(d)) {
      this.setHighlight(this.highlight.filter(function (d) {
        return d[dimension] !== value;
      }));
    }
  },

  /**
   * Checks whether an entity is highlighted from the set
   * @returns {Boolean} whether the item is highlighted or not
   */
  isHighlighted: function isHighlighted(d) {
    var _this = this;
    var value = this._createValue(d);
    return this.highlight.map(function (d) {
      return JSON.stringify(_this._createValue(d)) === JSON.stringify(value);
    }).indexOf(true) !== -1;
  },

  /**
   * Clears selection of items
   */
  clearHighlighted: function clearHighlighted() {
    this.setHighlight([]);
  },
  clearSelected: function clearSelected() {
    this.select = [];
  },

  setLabelOffset: function setLabelOffset(d, xy) {
    if (xy[0] === 0 && xy[1] === 1) return;

    this.select.find(function (selectedMarker) {
      return utils.comparePlainObjects(selectedMarker, d);
    }).labelOffset = [Math.round(xy[0] * 1000) / 1000, Math.round(xy[1] * 1000) / 1000];

    //force the model to trigger events even if value is the same
    this.set("select", this.select, true);
  },

  checkTimeLimits: function checkTimeLimits() {

    var time = this._parent.time;

    if (!time) return;

    var tLimits = this.getTimeLimits();

    if (!tLimits) return;
    if (!utils.isDate(tLimits.min) || !utils.isDate(tLimits.max)) return utils.warn("checkTimeLimits(): min-max look wrong: " + tLimits.min + " " + tLimits.max + ". Expecting Date objects. Ensure that time is properly parsed in the data from reader");

    // change start and end (but keep startOrigin and endOrigin for furhter requests)
    var newTime = {};
    if (time.start - tLimits.min != 0 || !time.start && !this.startOrigin) newTime['start'] = d3.max([tLimits.min, time.parse(time.startOrigin)]);
    if (time.end - tLimits.max != 0 || !time.end && !this.endOrigin) newTime['end'] = d3.min([tLimits.max, time.parse(time.endOrigin)]);

    time.set(newTime, false, false);

    if (newTime.start || newTime.end) {
      utils.forEach(this.getSubhooks(), function (hook) {
        if (hook.which == "time") {
          hook.buildScale();
        }
      });
    }

    //force time validation because time.value might now fall outside of start-end
    time.validate();
  },

  /**
   * Gets the narrowest limits of the subhooks with respect to the provided data column
   * @param {String} attr parameter (data column)
   * @returns {Object} limits (min and max)
   * this function is only needed to route the "time" to some indicator,
   * to adjust time start and end to the max and min time available in data
   */
  getTimeLimits: function getTimeLimits() {
    var _this = this;
    var time = this._parent.time;
    var min,
        max,
        minArray = [],
        maxArray = [],
        items = {};
    if (!this.cachedTimeLimits) this.cachedTimeLimits = {};
    utils.forEach(this.getSubhooks(), function (hook) {

      //only indicators depend on time and therefore influence the limits
      if (hook.use !== "indicator" || !hook._important) return;

      var cachedLimits = _this.cachedTimeLimits[hook._dataId + hook.which];

      if (cachedLimits) {
        //if already calculated the limits then no ned to do it again
        min = cachedLimits.min;
        max = cachedLimits.max;
      } else {
        //otherwise calculate own date limits (a costly operation)
        items = hook.getValidItems().map(function (m) {
          return m[time.getDimension()];
        });
        if (items.length == 0) utils.warn("getTimeLimits() was unable to work with an empty array of valid datapoints");
        min = d3.min(items);
        max = d3.max(items);
      }
      _this.cachedTimeLimits[hook._dataId + hook.which] = { min: min, max: max };
      minArray.push(min);
      maxArray.push(max);
    });

    var resultMin = d3.max(minArray);
    var resultMax = d3.min(maxArray);
    if (resultMin > resultMax) {
      utils.warn("getTimeLimits(): Availability of the indicator's data has no intersection. I give up and just return some valid time range where you'll find no data points. Enjoy!");
      resultMin = d3.min(minArray);
      resultMax = d3.max(maxArray);
    }

    //return false for the case when neither of hooks was an "indicator" or "important"
    return !min && !max ? false : { min: resultMin, max: resultMax };
  },

  /**
   * Computes the intersection of keys in all hooks: a set of keys that have data in each hook
   * @returns array of keys that have data in all hooks of this._datacube
   */
  getKeys: function getKeys(KEY) {
    var _this = this;
    var resultKeys = [];

    KEY = KEY || this._getFirstDimension();
    var TIME = this._getFirstDimension({ type: "time" });

    utils.forEach(this._dataCube || this.getSubhooks(true), function (hook, name) {

      // If hook use is constant, then we can provide no additional info about keys
      // We can just hope that we have something else than constants =)
      if (hook.use === "constant") return;

      // Get keys in data of this hook
      var nested = hook.getNestedItems([KEY, TIME]);
      var noDataPoints = hook.getHaveNoDataPointsPerKey();

      if (nested["undefined"]) delete nested["undefined"];

      var keys = Object.keys(nested);
      var keysNoDP = Object.keys(noDataPoints || []);

      // If ain't got nothing yet, set the list of keys to result
      if (resultKeys.length == 0) resultKeys = keys;

      // Remove the keys from it that are not in this hook
      if (hook._important) resultKeys = resultKeys.filter(function (f) {
        return keys.indexOf(f) > -1 && keysNoDP.indexOf(f) == -1;
      });
    });
    return resultKeys.map(function (d) {
      var r = {};r[KEY] = d;return r;
    });
  },

  /**
   * @param {Array} entities array of entities
   * @return String
   */
  _getCachePath: function _getCachePath(keys) {
    //array of steps -- names of all frames
    var steps = this._parent.time.getAllSteps();
    var cachePath = steps[0] + " - " + steps[steps.length - 1];
    this._dataCube = this._dataCube || this.getSubhooks(true);
    var dataLoading = false;
    utils.forEach(this._dataCube, function (hook, name) {
      if (hook._loadCall) dataLoading = true;
      cachePath = cachePath + "_" + hook._dataId + hook.which;
    });
    if (dataLoading) {
      return null;
    }
    if (keys) {
      cachePath = cachePath + "_" + keys.join(",");
    }
    return cachePath;
  },

  _getAllDimensions: function _getAllDimensions(opts) {

    var models = [];
    var _this = this;
    utils.forEach(this.space, function (name) {
      models.push(_this.getClosestModel(name));
    });

    opts = opts || {};
    var dims = [];
    var dim;

    utils.forEach(models, function (m) {
      if (opts.exceptType && m.getType() === opts.exceptType) {
        return true;
      }
      if (opts.onlyType && m.getType() !== opts.onlyType) {
        return true;
      }
      if (dim = m.getDimension()) {
        dims.push(dim);
      }
    });

    return dims;
  },

  /**
   * gets first dimension that matches type
   * @param {Object} options
   * @returns {Array} all unique dimensions
   */
  _getFirstDimension: function _getFirstDimension(opts) {
    var models = [];
    var _this = this;
    utils.forEach(this.space, function (name) {
      models.push(_this.getClosestModel(name));
    });

    opts = opts || {};

    var dim = false;
    utils.forEach(models, function (m) {
      if (opts.exceptType && m.getType() !== opts.exceptType) {
        dim = m.getDimension();
        return false;
      } else if (opts.type && m.getType() === opts.type) {
        dim = m.getDimension();
        return false;
      } else if (!opts.exceptType && !opts.type) {
        dim = m.getDimension();
        return false;
      }
    });
    return dim;
  },

  framesAreReady: function framesAreReady() {
    var cachePath = this._getCachePath();
    if (!this.cachedFrames) return false;
    return Object.keys(this.cachedFrames[cachePath]).length == this._parent.time.getAllSteps().length;
  },

  /**
   *
   * @param {String|null} time of a particularly requested data frame. Null if all frames are requested
   * @param {function} cb
   * @param {Array} keys array of entities
   * @return null
   */
  getFrame: function getFrame(time, cb, keys) {
    //keys = null;
    var _this = this;
    if (!this.cachedFrames) this.cachedFrames = {};

    var steps = this._parent.time.getAllSteps();
    // try to get frame from cache without keys
    var cachePath = this._getCachePath();
    if (!cachePath) return cb(null, time);
    if (time && _this.cachedFrames[cachePath] && _this.cachedFrames[cachePath][time]) {
      // if it does, then return that frame directly and stop here
      //QUESTION: can we call the callback and return the frame? this will allow callbackless API too
      return cb(_this.cachedFrames[cachePath][time], time);
    }
    cachePath = this._getCachePath(keys);
    if (!cachePath) return cb(null, time);

    // check if the requested time point has a cached animation frame
    if (time && _this.cachedFrames[cachePath] && _this.cachedFrames[cachePath][time]) {
      // if it does, then return that frame directly and stop here
      //QUESTION: can we call the callback and return the frame? this will allow callbackless API too
      return cb(_this.cachedFrames[cachePath][time], time);
    } else {
      // if it doesn't (the requested time point falls between animation frames or frame is not cached yet)
      // check if interpolation makes sense: we've requested a particular time and we have more than one frame
      if (time && steps.length > 1) {

        //find the next frame after the requested time point
        var nextFrameIndex = d3.bisectLeft(steps, time);

        if (!steps[nextFrameIndex]) {
          utils.warn("The requested frame is out of range: " + time);
          cb(null, time);
          return null;
        }

        //if "time" doesn't hit the frame precisely
        if (steps[nextFrameIndex].toString() != time.toString()) {

          //interpolate between frames and fire the callback
          this._interpolateBetweenFrames(time, nextFrameIndex, steps, function (response) {
            cb(response, time);
          }, keys);
          return null;
        }
      }

      //QUESTION: we don't need any further execution after we called for interpolation, right?
      //request preparing the data, wait until it's done
      _this.getFrames(time, keys).then(function () {
        if (!time && _this.cachedFrames[cachePath]) {
          //time can be null: then return all frames
          return cb(_this.cachedFrames[cachePath], time);
        } else if (_this.cachedFrames[cachePath] && _this.cachedFrames[cachePath][time]) {
          //time can be !null: then a particular frame calculation was forced and now it's done
          return cb(_this.cachedFrames[cachePath][time], time);
        } else {
          utils.warn("marker.js getFrame: Data is not available for frame: " + time);
          return cb(null, time);
        }
      });
    }
  },

  _interpolateBetweenFrames: function _interpolateBetweenFrames(time, nextFrameIndex, steps, cb, keys) {
    var _this = this;

    if (nextFrameIndex == 0) {
      //getFrame makes sure the frane is ready because a frame with non-existing data might be adressed
      this.getFrame(steps[nextFrameIndex], function (values) {
        return cb(values);
      }, keys);
    } else {
      var prevFrameTime = steps[nextFrameIndex - 1];
      var nextFrameTime = steps[nextFrameIndex];

      //getFrame makes sure the frane is ready because a frame with non-existing data might be adressed
      this.getFrame(prevFrameTime, function (pValues) {
        _this.getFrame(nextFrameTime, function (nValues) {
          var fraction = (time - prevFrameTime) / (nextFrameTime - prevFrameTime);
          var dataBetweenFrames = {};

          //loop across the hooks
          utils.forEach(pValues, function (values, hook) {
            dataBetweenFrames[hook] = {};

            //loop across the entities
            utils.forEach(values, function (val1, key) {
              var val2 = nValues[hook][key];
              if (utils.isDate(val1)) {
                dataBetweenFrames[hook][key] = time;
              } else if (!utils.isNumber(val1)) {
                //we can be interpolating string values
                dataBetweenFrames[hook][key] = val1;
              } else {
                //interpolation between number and null should rerurn null, not a value in between (#1350)
                dataBetweenFrames[hook][key] = val1 == null || val2 == null ? null : val1 + (val2 - val1) * fraction;
              }
            });
          });
          cb(dataBetweenFrames);
        }, keys);
      }, keys);
    }
  },

  getFrames: function getFrames(forceFrame, selected) {
    var _this = this;
    if (!this.cachedFrames) this.cachedFrames = {};

    var KEY = this._getFirstDimension();
    var TIME = this._getFirstDimension({ type: "time" });

    if (!this.frameQueues) this.frameQueues = {}; //static queue of frames
    if (!this.partialResult) this.partialResult = {};

    //array of steps -- names of all frames
    var steps = this._parent.time.getAllSteps();

    var cachePath = this._getCachePath(selected);
    if (!cachePath) return new Promise(function (resolve, reject) {
      resolve();
    });
    //if the collection of frames for this data cube is not scheduled yet (otherwise no need to repeat calculation)
    if (!this.frameQueues[cachePath] || !this.frameQueues[cachePath] instanceof Promise) {

      //this is a promise nobody listens to - it prepares all the frames we need without forcing any
      this.frameQueues[cachePath] = new Promise(function (resolve, reject) {

        _this.partialResult[cachePath] = {};
        steps.forEach(function (t) {
          _this.partialResult[cachePath][t] = {};
        });

        // Assemble the list of keys as an intersection of keys in all queries of all hooks
        var keys = _this.getKeys();

        var deferredHooks = [];
        // Assemble data from each hook. Each frame becomes a vector containing the current configuration of hooks.
        // frame -> hooks -> entities: values
        utils.forEach(_this._dataCube, function (hook, name) {
          if (hook.use === "constant") {
            //special case: fill data with constant values
            steps.forEach(function (t) {
              _this.partialResult[cachePath][t][name] = {};
              keys.forEach(function (key) {
                _this.partialResult[cachePath][t][name][key[KEY]] = hook.which;
              });
            });
          } else if (hook.which === KEY) {
            //special case: fill data with keys to data itself
            steps.forEach(function (t) {
              _this.partialResult[cachePath][t][name] = {};
              keys.forEach(function (key) {
                _this.partialResult[cachePath][t][name][key[KEY]] = key[KEY];
              });
            });
          } else if (hook.which === TIME) {
            //special case: fill data with time points
            steps.forEach(function (t) {
              _this.partialResult[cachePath][t][name] = {};
              keys.forEach(function (key) {
                _this.partialResult[cachePath][t][name][key[KEY]] = new Date(t);
              });
            });
          } else {
            //calculation of async frames is taken outside the loop
            //hooks with real data that needs to be fetched from datamanager
            deferredHooks.push(hook);
          }
        });

        //check if we have any data to get from datamanager
        if (deferredHooks.length > 0) {
          var promises = [];
          utils.forEach(deferredHooks, function (hook) {
            promises.push(new Promise(function (res, rej) {
              // need to save the hook state before calling getFrames.
              // `hook` state might change between calling and resolving the call.
              // The result needs to be saved to the correct cache, so we need to save current hook state
              var currentHookState = {
                name: hook._name,
                which: hook.which
              };
              hook.getFrames(steps, selected).then(function (response) {
                utils.forEach(response, function (frame, t) {
                  _this.partialResult[cachePath][t][currentHookState.name] = frame[currentHookState.which];
                });
                res();
              });
            }));
          });
          Promise.all(promises).then(function () {
            _this.cachedFrames[cachePath] = _this.partialResult[cachePath];
            resolve();
          });
        } else {
          _this.cachedFrames[cachePath] = _this.partialResult[cachePath];
          resolve();
        }
      });
    }
    return new Promise(function (resolve, reject) {
      if (steps.length < 2 || !forceFrame) {
        //wait until the above promise is resolved, then resolve the current promise
        _this.frameQueues[cachePath].then(function () {
          resolve(); //going back to getFrame(), to ".then"
        });
      } else {
        var promises = [];
        utils.forEach(_this._dataCube, function (hook, name) {
          //exception: we know that these are knonwn, no need to calculate these
          if (hook.use !== "constant" && hook.which !== KEY && hook.which !== TIME) {
            (function (_hook, _name) {
              promises.push(new Promise(function (res, rej) {
                _hook.getFrame(steps, forceFrame, selected).then(function (response) {
                  _this.partialResult[cachePath][forceFrame][_name] = response[forceFrame][_hook.which];
                  res();
                });
              }));
            })(hook, name); //isolate this () code with its own hook and name
          }
        });
        if (promises.length > 0) {
          Promise.all(promises).then(function () {
            if (!_this.cachedFrames[cachePath]) {
              _this.cachedFrames[cachePath] = {};
            }
            _this.cachedFrames[cachePath][forceFrame] = _this.partialResult[cachePath][forceFrame];
            resolve();
          });
        }
      }
    });
  },

  listenFramesQueue: function listenFramesQueue(keys, cb) {
    var _this = this;
    var KEY = this._getFirstDimension();
    var TIME = this._getFirstDimension({ type: "time" });
    var steps = this._parent.time.getAllSteps();
    var preparedFrames = {};
    this.getFrames();
    var dataIds = [];
    utils.forEach(_this._dataCube, function (hook, name) {
      if (!(hook.use === "constant" || hook.which === KEY || hook.which === TIME)) {
        if (dataIds.indexOf(hook._dataId) == -1) {
          dataIds.push(hook._dataId);

          hook.dataSource.listenFrame(hook._dataId, steps, keys, function (dataId, time) {
            var keyName = time.toString();
            if (typeof preparedFrames[keyName] == "undefined") preparedFrames[keyName] = [];
            if (preparedFrames[keyName].indexOf(dataId) == -1) preparedFrames[keyName].push(dataId);
            if (preparedFrames[keyName].length == dataIds.length) {
              cb(time);
            }
          });
        }
      }
    });
  },

  /**
   * gets multiple values from the hook
   * @param {Object} filter Reference to the row. e.g: {geo: "swe", time: "1999", ... }
   * @param {Array} group_by How to nest e.g: ["geo"]
   * @param {Boolean} [previous = false] previous Append previous data points
   * @returns an array of values
   */
  getValues: function getValues(filter, group_by, previous) {
    var _this = this;

    if (this.isHook()) {
      return [];
    }

    var dimTime, time, filtered, next, method, u, w, value;
    this._dataCube = this._dataCube || this.getSubhooks(true);
    filter = utils.clone(filter, this._getAllDimensions());
    dimTime = this._getFirstDimension({
      type: 'time'
    });
    time = new Date(filter[dimTime]); //clone date
    filter = utils.clone(filter, null, dimTime);

    var response = {};
    var f_keys = Object.keys(filter);
    var f_values = f_keys.map(function (k) {
      return filter[k];
    });

    //if there's a filter, interpolate only that
    if (f_keys.length) {
      utils.forEach(this._dataCube, function (hook, name) {
        u = hook.use;
        w = hook.which;

        if (hook.use !== "property") next = next || d3.bisectLeft(hook.getUnique(dimTime), time);

        method = hook.getConceptprops ? hook.getConceptprops().interpolation : null;
        filtered = hook.getNestedItems(f_keys);
        utils.forEach(f_values, function (v) {
          filtered = filtered[v]; //get precise array (leaf)
        });
        value = utils.interpolatePoint(filtered, u, w, next, dimTime, time, method);
        response[name] = hook.mapValue(value);

        //concat previous data points
        if (previous) {
          var values = utils.filter(filtered, filter).filter(function (d) {
            return d[dimTime] <= time;
          }).map(function (d) {
            return hook.mapValue(d[w]);
          }).concat(response[name]);
          response[name] = values;
        }
      });
    }
    //else, interpolate all with time
    else {
        utils.forEach(this._dataCube, function (hook, name) {

          filtered = hook.getNestedItems(group_by);

          response[name] = {};
          //find position from first hook
          u = hook.use;
          w = hook.which;

          if (hook.use !== "property") next = typeof next === 'undefined' ? d3.bisectLeft(hook.getUnique(dimTime), time) : next;

          method = hook.getConceptprops ? hook.getConceptprops().interpolation : null;

          var interpolate = function interpolate(arr, result, id) {
            //TODO: this saves when geos have different data length. line can be optimised.
            next = d3.bisectLeft(arr.map(function (m) {
              return m[dimTime];
            }), time);

            value = utils.interpolatePoint(arr, u, w, next, dimTime, time, method);
            result[id] = hook.mapValue(value);

            //concat previous data points
            if (previous) {
              var values = utils.filter(arr, filter).filter(function (d) {
                return d[dimTime] <= time;
              }).map(function (d) {
                return hook.mapValue(d[w]);
              }).concat(result[id]);
              result[id] = values;
            }
          };

          var iterateGroupKeys = function iterateGroupKeys(data, deep, result, cb) {
            deep--;
            utils.forEach(data, function (d, id) {
              if (deep) {
                result[id] = {};
                iterateGroupKeys(d, deep, result[id], cb);
              } else {
                cb(d, result, id);
              }
            });
          };

          iterateGroupKeys(filtered, group_by.length, response[name], interpolate);
        });
      }

    return response;
  },

  getEntityLimits: function getEntityLimits(entity) {
    var _this = this;
    var timePoints = this._parent.time.getAllSteps();
    var selectedEdgeTimes = [];
    var hooks = [];
    utils.forEach(_this.getSubhooks(), function (hook) {
      if (hook.use == "constant") return;
      if (hook._important) hooks.push(hook._name);
    });

    var findEntityWithCompleteHooks = function findEntityWithCompleteHooks(values) {
      if (!values) return false;
      for (var i = 0, j = hooks.length; i < j; i++) {
        if (!(values[hooks[i]][entity] || values[hooks[i]][entity] === 0)) return false;
      }
      return true;
    };

    var findSelectedTime = function findSelectedTime(iterator, findCB) {
      var point = iterator();
      if (point == null) return;
      _this.getFrame(timePoints[point], function (values) {
        if (findEntityWithCompleteHooks(values)) {
          findCB(point);
        } else {
          findSelectedTime(iterator, findCB);
        }
      });
    };
    var promises = [];
    promises.push(new Promise(function (resolve, reject) {

      //find startSelected time
      findSelectedTime(function () {
        var max = timePoints.length;
        var i = 0;
        return function () {
          return i < max ? i++ : null;
        };
      }(), function (point) {
        selectedEdgeTimes[0] = timePoints[point];
        resolve();
      });
    }));

    promises.push(new Promise(function (resolve, reject) {

      //find endSelected time
      findSelectedTime(function () {
        var i = timePoints.length - 1;
        return function () {
          return i >= 0 ? i-- : null;
        };
      }(), function (point) {
        selectedEdgeTimes[1] = timePoints[point];
        resolve();
      });
    }));

    return Promise.all(promises).then(function () {
      return { "min": selectedEdgeTimes[0], "max": selectedEdgeTimes[1] };
    });
  },

  /**
   * Learn what this model should hook to
   * @returns {Array} space array
   */
  getSpace: function getSpace() {
    if (utils.isArray(this.space)) {
      return this.space;
    }

    utils.error('ERROR: space not found.\n You must specify the objects this hook will use under the "space" attribute in the state.\n Example:\n space: ["entities", "time"]');
  }

});

exports.default = Marker;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _axis = __webpack_require__(87);

var _axis2 = _interopRequireDefault(_axis);

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/*
 * VIZABI Size Model
 */

var SizeModel = _axis2.default.extend({

  /**
   * Default values for this model
   */
  getClassDefaults: function getClassDefaults() {
    var defaults = {
      use: "constant",
      which: "_default",
      domainMin: null,
      domainMax: null,
      zoomedMin: null,
      zoomedMax: null,
      extent: [0, 0.85],
      scaleType: "ordinal",
      allow: {
        scales: ["linear", "log", "genericLog", "pow"]
      }
    };
    return utils.deepExtend(this._super(), defaults);
  },

  _type: "size",

  buildScale: function buildScale() {
    //do whatever axis.buildScale does
    this._super();
    //but then also clamp a numeric scale
    if (this.scaleType !== 'ordinal') this.scale.clamp(true);
  }
});

exports.default = SizeModel;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _hook = __webpack_require__(48);

var _hook2 = _interopRequireDefault(_hook);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*
 * VIZABI Stack Model
 */

var palettes = {
  'ALL': "all",
  _default: "none"
};

var StackModel = _hook2.default.extend({

  /**
   * Default values for this model
   */
  getClassDefaults: function getClassDefaults() {
    var defaults = {
      use: null,
      which: null,
      merge: false
    };
    return utils.deepExtend(this._super(), defaults);
  },

  /**
   * Initializes the stack hook
   * @param {Object} values The initial values of this model
   * @param parent A reference to the parent model
   * @param {Object} bind Initial events to bind
   */
  init: function init(name, values, parent, bind) {

    this._type = "model";

    this._super(name, values, parent, bind);
  },

  /**
   * Validates a color hook
   */
  validate: function validate() {
    //there must be no scale
    if (this.scale) this.scale = null;

    //use must not be "indicator"
    if (this.use === "indicator") {
      utils.warn("stack model: use must not be 'indicator'. Resetting use to 'constant' and which to '" + palettes._default);
      this.use = "constant";
      this.which = palettes._default;
    }

    //if use is "constant"
    if (this.use === "constant" && utils.values(palettes).indexOf(this.which) == -1) {
      utils.warn("stack model: the requested value '" + this.which + "' is not allowed. resetting to '" + palettes._default);
      this.which == palettes._default;
    }
  },

  /**
   * Get the above constants
   */
  getPalettes: function getPalettes() {
    return palettes;
  },

  /**
   * There must be no scale
   */
  buildScale: function buildScale() {}

});

exports.default = StackModel;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _dataconnected = __webpack_require__(59);

var _dataconnected2 = _interopRequireDefault(_dataconnected);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*!
 * VIZABI Time Model
 */

// short-cut for developers to get UTC date strings
// not meant to be used in code!!!
Date.prototype.utc = Date.prototype.toUTCString;

/*
 * Time formats for internal data
 * all in UTC
 */
var formats = {
  'year': { data: d3.time.format.utc('%Y'), ui: d3.time.format.utc('%Y') },
  'month': { data: d3.time.format.utc('%Y-%m'), ui: d3.time.format.utc('%b %Y') }, // month needs separator according to ISO to not confuse YYYYMM with YYMMDD
  'day': { data: d3.time.format.utc('%Y%m%d'), ui: d3.time.format.utc('%c') },
  'hour': { data: d3.time.format.utc("%Y%m%dT%H"), ui: d3.time.format.utc('%b %d %Y, %H') },
  'minute': { data: d3.time.format.utc("%Y%m%dT%H%M"), ui: d3.time.format.utc('%b %d %Y, %H:%M') },
  'second': { data: d3.time.format.utc("%Y%m%dT%H%M%S"), ui: d3.time.format.utc('%b %d %Y, %H:%M:%S') },
  'week': { data: weekFormat(), ui: weekFormat() }, // %Yw%W d3 week format does not comply with ISO
  'quarter': { data: quarterFormat(), ui: quarterFormat() } // %Yq%Q d3 does not support quarters
};

var TimeModel = _dataconnected2.default.extend({

  objectLeafs: ['autogenerate'],

  /**
   * Default values for this model
   */
  getClassDefaults: function getClassDefaults() {
    var defaults = {
      dim: null,
      value: null,
      start: null,
      end: null,
      startOrigin: null,
      endOrigin: null,
      startSelected: null,
      endSelected: null,
      playable: true,
      playing: false,
      loop: false,
      round: 'round',
      delay: 150, //delay between animation frames
      delayThresholdX2: 90, //delay X2 boundary: if less -- then every other frame will be dropped and animation dely will be double the value
      delayThresholdX4: 45, //delay X4 boundary: if less -- then 3/4 frame will be dropped and animation dely will be 4x the value
      unit: "year",
      format: { data: null, ui: null }, // overwrite of default formats
      step: 1, //step must be integer, and expressed in units
      immediatePlay: true,
      record: false
    };
    return utils.deepExtend(this._super(), defaults);
  },

  dataConnectedChildren: ['startOrigin', 'endOrigin', 'dim'],

  /**
   * Initializes the locale model.
   * @param {String} name 
   * @param {Object} values The initial values of this model
   * @param parent A reference to the parent model
   * @param {Object} bind Initial events to bind
   */
  init: function init(name, values, parent, bind) {
    this._type = "time";

    //same constructor
    this._super(name, values, parent, bind);
    var _this = this;
    this.initFormatters();
    this.dragging = false;
    this.postponePause = false;
    this.allSteps = {};
    this.delayAnimations = this.delay;

    //bing play method to model change
    this.on({

      "change:playing": function changePlaying() {
        if (_this.playing === true) {
          _this._startPlaying();
        } else {
          _this._stopPlaying();
        }
      },

      "change:format": function changeFormat() {
        _this.initFormatters();
      }

    });
  },

  initFormatters: function initFormatters() {
    if (formats[this.unit]) {
      this.formatters = formats[this.unit];
    }
    // specifically set formats overwrite unit defaults
    if (typeof this.format == 'string') {
      this.formatters.data = this.formatters.ui = d3.time.format.utc(this.format);
    } else {
      if (this.format.data) {
        this.formatters.data = d3.time.format.utc(this.format.data);
      }
      if (this.format.ui) {
        this.formatters.ui = d3.time.format.utc(this.format.ui);
      }
    }
    this.validateFormatting();
  },

  afterPreload: function afterPreload() {
    if (this.dim == null && this.autogenerate) {
      var dataSource = this.getClosestModel(this.autogenerate.data);
      this.dim = dataSource.getConceptByIndex(this.autogenerate.conceptIndex, this.autogenerate.conceptType).concept;
    }
  },

  /**
   * Formats value, start and end dates to actual Date objects
   */
  _formatToDates: function _formatToDates() {
    var persistentValues = ["value"];
    var date_attr = ["value", "start", "end", "startSelected", "endSelected"];
    for (var i = 0; i < date_attr.length; i++) {
      var attr = date_attr[i];
      if (!utils.isDate(this[attr])) {
        var date = this.parse(this[attr]);
        this.set(attr, date, null, persistentValues.indexOf(attr) !== -1);
      }
    }
  },

  /*
   * Formatting and parsing functions
   * @param {Date} dateObject
   * @param {String} type Either data or ui.
   * @returns {String}
   */
  formatDate: function formatDate(dateObject) {
    var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'data';

    if (['data', 'ui'].indexOf(type) === -1) {
      utils.warn('Time.formatDate type parameter (' + type + ') invalid. Using "data".');
      type = data;
    }
    if (dateObject == null) return null;
    return this.formatters[type](dateObject);
  },
  /* parse to predefined unit */
  parse: function parse(timeString) {
    var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'data';

    if (timeString == null) return null;
    return this.formatters[type].parse(timeString.toString());
  },

  /* auto-determines unit from timestring */
  findFormat: function findFormat(timeString) {
    var keys = Object.keys(formats),
        i = 0;
    for (; i < keys.length; i++) {
      var dateObject = formats[keys[i]].data.parse(timeString);
      if (dateObject) return { unit: keys[i], time: dateObject, type: 'data' };
      var dateObject = formats[keys[i]].ui.parse(timeString);
      if (dateObject) return { unit: keys[i], time: dateObject, type: 'ui' };
    }
    return null;
  },

  /**
   * Validates the model
   */
  validate: function validate() {

    //check if time start and end are not defined but start and end origins are defined
    if (this.start == null && this.startOrigin) this.set("start", this.startOrigin, null, false);
    if (this.end == null && this.endOrigin) this.set("end", this.endOrigin, null, false);

    if (this.formatters) {
      this.validateFormatting();
    }

    //unit has to be one of the available_time_units
    if (!formats[this.unit]) {
      utils.warn(this.unit + ' is not a valid time unit, using "year" instead.');
      this.unit = "year";
    }

    if (this.step < 1) {
      this.step = 1;
    }

    //end has to be >= than start
    if (this.end < this.start && this.start != null) {
      this.set("end", new Date(this.start), null, false);
    }

    if (this.value < this.startSelected && this.startSelected != null) {
      this.value = new Date(this.startSelected);
    }

    if (this.value > this.endSelected && this.endSelected != null) {
      this.value = new Date(this.endSelected);
    }
    if (this.splash === false) {
      if (this.startSelected < this.start && this.start != null) {
        this.set({ startSelected: new Date(this.start) }, null, false /*make change non-persistent for URL and history*/);
      }

      if (this.endSelected > this.end && this.end != null) {
        this.set({ endSelected: new Date(this.end) }, null, false /*make change non-persistent for URL and history*/);
      }
    }

    //value has to be between start and end
    if (this.value < this.start && this.start != null) {
      this.value = new Date(this.start);
    } else if (this.value > this.end && this.end != null) {
      this.value = new Date(this.end);
    }

    if (this.playable === false && this.playing === true) {
      this.set("playing", false, null, false);
    }
  },

  validateFormatting: function validateFormatting() {
    // default to current date. Other option: newTime['start'] || newTime['end'] || time.start || time.end;
    if (this.value == null) this.set("value", this.parse(this.formatDate(new Date())), null, false);

    //make sure dates are transformed into dates at all times
    if (!utils.isDate(this.start) || !utils.isDate(this.end) || !utils.isDate(this.value) || !utils.isDate(this.startSelected) || !utils.isDate(this.endSelected)) {
      this._formatToDates();
    }
  },

  /**
   * Plays time
   */
  play: function play() {
    this._startPlaying();
  },

  /**
   * Pauses time
   */
  pause: function pause(soft) {
    if (soft) {
      this.postponePause = true;
    } else {
      this.set("playing", false, null, false);
    }
  },

  /**
   * Indicates dragging of time
   */
  dragStart: function dragStart() {
    this.dragging = true;
  },
  dragStop: function dragStop() {
    this.dragging = false;
  },

  /**
   * gets time range
   * @returns range between start and end
   */
  getRange: function getRange() {
    var is = this.getIntervalAndStep();
    return d3.time[is.interval].utc.range(this.start, this.end, is.step);
  },

  /** 
   * gets the d3 interval and stepsize for d3 time interval methods
   * D3's week-interval starts on sunday and d3 does not support a quarter interval
   **/
  getIntervalAndStep: function getIntervalAndStep() {
    var d3Interval, step;
    switch (this.unit) {
      case 'week':
        d3Interval = 'monday';step = this.step;break;
      case 'quarter':
        d3Interval = 'month';step = this.step * 3;break;
      default:
        d3Interval = this.unit;step = this.step;break;
    }
    return { interval: d3Interval, step: step };
  },

  /**
   * Gets filter for time
   * @param {Boolean} splash: get filter for current year only
   * @returns {Object} time filter
   */
  getFilter: function getFilter(splash) {
    var defaultStart = this.parse(this.startOrigin);
    var defaultEnd = this.parse(this.endOrigin);

    var dim = this.getDimension();
    var filter = null;

    if (splash) {
      if (this.value != null) {
        filter = {};
        filter[dim] = this.formatters.data(this.value);
      }
    } else {
      var gte, lte;
      if (defaultStart != null) {
        gte = this.formatters.data(defaultStart);
      }
      if (defaultEnd != null) {
        lte = this.formatters.data(defaultEnd);
      }
      if (gte || lte) {
        filter = {};
        filter[dim] = {};
        if (gte) filter[dim]["$gte"] = gte;
        if (lte) filter[dim]["$lte"] = lte;
      }
    }
    return filter;
  },

  /**
   * Gets parser for this model
   * @returns {Function} parser function 
   */
  getParser: function getParser() {
    var type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'data';

    return this.formatters[type].parse;
  },

  /**
  * Gets formatter for this model
  * @returns {Function} formatter function 
  */
  getFormatter: function getFormatter() {
    var type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'data';

    return this.formatters[type];
  },

  /**
   * Gets an array with all time steps for this model
   * @returns {Array} time array
   */
  getAllSteps: function getAllSteps() {
    if (!this.start || !this.end) {
      utils.warn("getAllSteps(): invalid start/end time is detected: " + this.start + ", " + this.end);
      return [];
    }
    var hash = "" + this.start + this.end + this.step;

    //return if cached
    if (this.allSteps[hash]) return this.allSteps[hash];

    this.allSteps[hash] = [];
    var curr = this.start;
    while (curr <= this.end) {
      var is = this.getIntervalAndStep();
      this.allSteps[hash].push(curr);
      curr = d3.time[is.interval].utc.offset(curr, is.step);
    }
    return this.allSteps[hash];
  },

  /**
   * Snaps the time to integer
   * possible inputs are "start", "end", "value". "value" is default
   */
  snap: function snap(what) {
    if (!this.round) return;
    if (what == null) what = "value";
    var op = 'round';
    if (this.round === 'ceil') op = 'ceil';
    if (this.round === 'floor') op = 'floor';
    var is = this.getIntervalAndStep();
    var time = d3.time[is.interval].utc[op](this[what]);
    this.set(what, time, true); //3rd argumennt forces update
  },

  /**
   * Starts playing the time, initializing the interval
   */
  _startPlaying: function _startPlaying() {
    //don't play if it's not playable
    if (!this.playable) return;

    var _this = this;

    //go to start if we start from end point
    if (this.value >= this.endSelected) {
      _this.getModelObject('value').set(_this.startSelected, null, false /*make change non-persistent for URL and history*/);
    } else {
        //the assumption is that the time is already snapped when we start playing
        //because only dragging the timeslider can un-snap the time, and it snaps on drag.end
        //so we don't need this line. let's see if we survive without.
        //as a consequence, the first time update in playing sequence will have this.playing flag up
        //so the bubble chart will zoom in smoothly. Closes #1213
        //this.snap();
      }
    this.set("playing", true, null, false);
    this.playInterval(this.immediatePlay);

    this.trigger("play");
  },

  playInterval: function playInterval(immediatePlay) {
    if (!this.playing) return;
    var _this = this;
    this.delayAnimations = this.delay;
    if (this.delay < this.delayThresholdX2) this.delayAnimations *= 2;
    if (this.delay < this.delayThresholdX4) this.delayAnimations *= 2;

    var delayAnimations = immediatePlay ? 1 : this.delayAnimations;

    this._intervals.setInterval('playInterval_' + this._id, function () {
      // when time is playing and it reached the end
      if (_this.value >= _this.endSelected) {
        // if looping
        if (_this.loop) {
          // reset time to start, silently
          _this.getModelObject('value').set(_this.startSelected, null, false /*make change non-persistent for URL and history*/);
        } else {
          _this.set("playing", false, null, false);
        }
        return;
      } else {

        _this._intervals.clearInterval('playInterval_' + _this._id);

        if (_this.postponePause || !_this.playing) {
          _this.set("playing", false, null, false);
          _this.postponePause = false;
          _this.getModelObject('value').set(_this.value, true, true /*force the change and make it persistent for URL and history*/);
        } else {
          var is = _this.getIntervalAndStep();
          if (_this.delay < _this.delayThresholdX2) is.step *= 2;
          if (_this.delay < _this.delayThresholdX4) is.step *= 2;
          var time = d3.time[is.interval].utc.offset(_this.value, is.step);
          if (time >= _this.endSelected) {
            // if no playing needed anymore then make the last update persistent and not overshooting
            _this.getModelObject('value').set(_this.endSelected, null, true /*force the change and make it persistent for URL and history*/);
          } else {
            _this.getModelObject('value').set(time, null, false /*make change non-persistent for URL and history*/);
          }
          _this.playInterval();
        }
      }
    }, delayAnimations);
  },

  incrementTime: function incrementTime(time) {
    var is = this.getIntervalAndStep();
    return d3.time[is.interval].utc.offset(time, is.step);
  },

  decrementTime: function decrementTime(time) {
    var is = this.getIntervalAndStep();
    return d3.time[is.interval].utc.offset(time, -is.step);
  },

  /**
   * Stops playing the time, clearing the interval
   */
  _stopPlaying: function _stopPlaying() {
    this._intervals.clearInterval('playInterval_' + this._id);
    //this.snap();
    this.trigger("pause");
  }

});

/*
 * Week Format to format and parse dates
 * Conforms with ISO8601
 * Follows format: YYYYwWW: 2015w04, 3845w34, 0020w53
 */
function weekFormat() {

  var format = function format(d) {
    return formatWeekYear(d) + 'w' + formatWeek(d);
  };

  format.parse = function parse(dateString) {
    var matchedDate = dateString.match(/^(\d{4})w(\d{2})$/);
    return matchedDate ? getDateFromWeek(matchedDate[1], matchedDate[2]) : null;
  };

  var formatWeekYear = function formatWeekYear(d) {
    var origin = +d;
    return new Date(origin + (4 - (d.getUTCDay() || 7)) * 86400000).getUTCFullYear();
  };

  var formatWeek = function formatWeek(d) {
    var origin = +d;
    var quote = new Date(origin + (4 - (d.getUTCDay() || 7)) * 86400000);
    var week = Math.ceil(((quote.getTime() - quote.setUTCMonth(0, 1)) / 86400000 + 1) / 7);
    return week < 10 ? '0' + week : week;
  };

  var getDateFromWeek = function getDateFromWeek(p1, p2) {
    var week = parseInt(p2);
    var year = p1;
    var startDateOfYear = new Date(); // always 4th of January (according to standard ISO 8601)
    startDateOfYear.setUTCFullYear(year);
    startDateOfYear.setUTCMonth(0);
    startDateOfYear.setUTCDate(4);
    var startDayOfWeek = startDateOfYear.getUTCDay() || 7;
    var dayOfWeek = 1; // Monday === 1
    var dayOfYear = week * 7 + dayOfWeek - (startDayOfWeek + 4);

    var date = formats['year'].parse(year);
    date = new Date(date.getTime() + dayOfYear * 24 * 60 * 60 * 1000);

    return date;
  };

  return format;
};

/*
 * Quarter Format to format and parse quarter dates
 * A quarter is the month%3
 * Follows format: YYYYqQ: 2015q4, 5847q1, 0040q2
 */
function quarterFormat() {

  var format = function format(d) {
    return formats['year'](d) + 'q' + formatQuarter(d);
  };

  format.parse = function (dateString) {
    var matchedDate = dateString.match(/^(\d{4})q(\d)$/);
    return matchedDate ? getDateFromQuarter(matchedDate[1], matchedDate[2]) : null;
  };

  var formatQuarter = function formatQuarter(d) {
    return (d.getUTCMonth() / 3 | 0) + 1;
  };

  var getDateFromQuarter = function getDateFromQuarter(p1, p2) {
    var quarter = parseInt(p2);
    var month = 3 * quarter - 2; // first month in quarter
    var year = p1;
    return formats['month'].parse([year, (month < 9 ? '0' : '') + month].join(''));
  };

  return format;
}

exports.default = TimeModel;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _model = __webpack_require__(46);

var _model2 = _interopRequireDefault(_model);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

//classes are vzb-portrait, vzb-landscape...
var class_prefix = 'vzb-';
var class_presentation = 'presentation';
var class_rtl = 'rtl';
var class_portrait = 'vzb-portrait';
var class_landscape = 'vzb-landscape';

var UI = _model2.default.extend({

  screen_profiles: {
    small: {
      min_width: 0,
      min_height: 0
    },
    medium: {
      min_width: 600,
      min_height: 400
    },
    large: {
      min_width: 900,
      min_height: 520
    }
  },

  getClassDefaults: function getClassDefaults() {
    var defaults = {
      presentation: false,
      buttons: [],
      dialogs: {
        popup: [],
        sidebar: [],
        moreoptions: []
      },
      splash: false
    };
    return utils.deepExtend(this._super(), defaults);
  },

  /**
   * Initializes the layout manager
   */
  init: function init(name, values, parent, bind) {

    this._type = 'ui';
    this._container = null;
    //dom element
    this._curr_profile = null;
    this._prev_size = {};

    //resize when window resizes
    this.resizeHandler = this.resizeHandler.bind(this);
    window.addEventListener('resize', this.resizeHandler);
    bind['change:presentation'] = this.updatePresentation.bind(this);

    this._super(name, values, parent, bind);
  },

  resizeHandler: function resizeHandler() {
    if (this._container) {
      this.setSize();
    }
  },

  /**
   * Calculates the size of the newly resized container
   */
  setSize: function setSize(force) {
    var _this = this;
    var width = this._container.clientWidth;
    var height = this._container.clientHeight;

    /**
     * issue #1118
     * check if device is iPhone then add top margin for searchbar if it visible
     */
    if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent) // browser is safari
    && navigator.userAgent.match(/iPhone/i) // checking device
    ) {
        this._container.style.top = 0;
        if (this._container.clientWidth > this._container.clientHeight // landscape mode
        && this._container.clientWidth < 700) {
          // small device
          var bodyHeight = this._container.clientHeight;
          var windowHeight = window.innerHeight;
          if (2 < bodyHeight - windowHeight && bodyHeight - windowHeight <= 45) {
            // check searchbar is visible
            this._container.style.top = 44 + "px";
            document.body.scrollTop = 44; // scrolling empty space
          }
        }
      }

    if (!force && this._prev_size && this._prev_size.width === width && this._prev_size.height === height) {
      return;
    }

    // choose profile depending on size
    utils.forEach(this.screen_profiles, function (range, size) {
      //remove class
      utils.removeClass(_this._container, class_prefix + size);
      //find best fit
      if (width >= range.min_width && height >= range.min_height) {
        _this._curr_profile = size;
      }
    });

    //update size class
    utils.addClass(this._container, class_prefix + this._curr_profile);

    //toggle, untoggle classes based on orientation
    utils.classed(this._container, class_portrait, width < height);
    utils.classed(this._container, class_landscape, !(width < height));

    this._prev_size.width = width;
    this._prev_size.height = height;
    this.trigger('resize');
  },

  /**
   * Sets the container for this layout
   * @param container DOM element
   */
  setContainer: function setContainer(container) {
    this._container = container;
    this.setSize();
    this.updatePresentation();
  },

  /**
   * Sets the presentation mode for this layout
   * @param {Bool} presentation mode on or off
   */
  updatePresentation: function updatePresentation() {
    utils.classed(this._container, class_prefix + class_presentation, this.presentation);
    this.trigger('resize');
  },

  getPresentationMode: function getPresentationMode() {
    return this.presentation;
  },

  setRTL: function setRTL(flag) {
    utils.classed(this._container, class_prefix + class_rtl, flag);
  },

  /**
   * Gets the current selected profile
   * @returns {String} name of current profile
   */
  currentProfile: function currentProfile() {
    return this._curr_profile;
  },

  clear: function clear() {
    window.removeEventListener('resize', this.resizeHandler);
  }

});

exports.default = UI;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _reader = __webpack_require__(71);

var _reader2 = _interopRequireDefault(_reader);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

var cached = {};

var CSVReader = _reader2.default.extend({

  QUERY_FROM_CONCEPTS: 'concepts',
  QUERY_FROM_DATAPOINTS: 'datapoints',
  QUERY_FROM_ENTITIES: 'entities',

  CONDITION_CALLBACKS: {
    $gt: function $gt(configValue, rowValue) {
      return rowValue > configValue;
    },
    $gte: function $gte(configValue, rowValue) {
      return rowValue >= configValue;
    },
    $lt: function $lt(configValue, rowValue) {
      return rowValue < configValue;
    },
    $lte: function $lte(configValue, rowValue) {
      return rowValue <= configValue;
    },
    $in: function $in(configValue, rowValue) {
      return configValue.includes(rowValue);
    }
  },

  ERRORS: {
    WRONG_TIME_COLUMN_OR_UNITS: 'reader/error/wrongTimeUnitsOrColumn',
    NOT_ENOUGH_ROWS_IN_FILE: 'reader/error/notEnoughRows',
    UNDEFINED_DELIMITER: 'reader/error/undefinedDelimiter',
    EMPTY_HEADERS: 'reader/error/emptyHeaders',
    GENERIC_ERROR: 'reader/error/generic'
  },

  _name: 'csv',

  /**
   * Initializes the reader.
   * @param {Object} readerInfo Information about the reader
   */
  init: function init(readerInfo) {
    this._data = [];
    this._basepath = readerInfo.path;
    this.delimiter = readerInfo.delimiter;
    this.keySize = readerInfo.keySize || 1;

    if (!this._basepath) {
      utils.error('Missing base path for csv reader');
    }
  },


  /**
   * Reads from source
   * @param {Object} query to be performed
   * @param parsers
   * @returns {Promise} a promise that will be resolved when data is read
   */
  read: function read(query) {
    var _this = this;

    var parsers = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

    query = this._normalizeQuery(query, parsers);

    var _query2 = query,
        select = _query2.select,
        from = _query2.from,
        _query2$order_by = _query2.order_by,
        order_by = _query2$order_by === undefined ? [] : _query2$order_by;

    var _order_by = _slicedToArray(order_by, 1),
        orderBy = _order_by[0];

    return this.load().then(function (result) {
      var data = result.data,
          columns = result.columns;

      _this.ensureDataIsCorrect(result, parsers);

      switch (true) {
        case from === _this.QUERY_FROM_CONCEPTS:
          return _this._getConcepts(columns, data.map(_this._getRowMapper(query, parsers)));

        case _this._isDataQuery(from) && select.key.length > 0:
          return data.reduce(_this._applyQuery(query, parsers), []).sort(function (prev, next) {
            return prev[orderBy] - next[orderBy];
          });

        default:
          return [];
      }
    }).catch(function (error) {
      throw {}.toString.call(error) === '[object Error]' ? _this.error(_this.ERRORS.GENERIC_ERROR, error) : error;
    });
  },
  ensureDataIsCorrect: function ensureDataIsCorrect(_ref, parsers) {
    var columns = _ref.columns,
        data = _ref.data;

    var timeKey = columns[this.keySize];

    var _data = _slicedToArray(data, 1),
        firstRow = _data[0];

    var parser = parsers[timeKey];

    var time = firstRow[timeKey];
    if (parser && !parser(time)) {
      throw this.error(this.ERRORS.WRONG_TIME_COLUMN_OR_UNITS, undefined, {
        currentYear: new Date().getFullYear(),
        foundYear: time
      });
    }

    if (!columns.length) {
      throw this.error(this.ERRORS.EMPTY_HEADERS);
    }
  },


  /**
   * This function returns info about the dataset
   * in case of CSV reader it's just the name of the file
   * @returns {object} object of info about the dataset
   */
  getDatasetInfo: function getDatasetInfo() {
    return { name: this._basepath.split('/').pop() };
  },
  load: function load() {
    var _this2 = this;

    var path = this._basepath;


    return new Promise(function (resolve, reject) {
      var cachedData = cached[path];

      if (cachedData) {
        resolve(cachedData);
      } else {
        d3.text(path).get(function (error, text) {
          if (!text) {
            return reject('No permissions or empty file: ' + path + '. ' + error);
          }

          if (error) {
            return reject('Error happened while loading csv file: ' + path + '. ' + error);
          }

          try {
            var _delimiter = _this2.delimiter,
                delimiter = _delimiter === undefined ? _this2._guessDelimiter(text) : _delimiter;

            var parser = d3.dsv(delimiter);

            var _getRows = _this2._getRows(text, 1),
                _getRows2 = _slicedToArray(_getRows, 1),
                header = _getRows2[0];

            var _parser$parseRows = parser.parseRows(header),
                _parser$parseRows2 = _slicedToArray(_parser$parseRows, 1),
                columns = _parser$parseRows2[0];

            var data = parser.parse(text);

            var result = { columns: columns, data: data };
            cached[path] = result;
            resolve(result);
          } catch (e) {
            return reject(e);
          }
        });
      }
    });
  },
  _guessDelimiter: function _guessDelimiter(text) {
    var stringsToCheck = 2;
    var rows = this._getRows(text, stringsToCheck);

    if (rows.length !== stringsToCheck) {
      throw this.error(this.ERRORS.NOT_ENOUGH_ROWS_IN_FILE);
    }

    var _rows = _slicedToArray(rows, 2),
        header = _rows[0],
        firstRow = _rows[1];

    var comma = ',',
        semicolon = ';';

    var commasCountInHeader = this._countCharsInLine(header, comma);
    var semicolonsCountInHeader = this._countCharsInLine(header, semicolon);
    var commasCountInFirstRow = this._countCharsInLine(firstRow, comma);
    var semicolonsCountInFirstRow = this._countCharsInLine(firstRow, semicolon);

    if (commasCountInHeader === commasCountInFirstRow && commasCountInHeader > 1 && (semicolonsCountInHeader !== semicolonsCountInFirstRow || !semicolonsCountInHeader && !semicolonsCountInFirstRow || commasCountInHeader > semicolonsCountInHeader && commasCountInFirstRow > semicolonsCountInFirstRow)) {
      return comma;
    } else if (semicolonsCountInHeader === semicolonsCountInFirstRow && semicolonsCountInHeader > 1 && (commasCountInHeader !== commasCountInFirstRow || !commasCountInHeader && !commasCountInFirstRow || semicolonsCountInHeader > commasCountInHeader && semicolonsCountInFirstRow > commasCountInFirstRow)) {
      return semicolon;
    }

    throw this.error(this.ERRORS.UNDEFINED_DELIMITER);
  },
  _getRows: function _getRows(text) {
    var count = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;

    var re = /([^\r\n]+)/g;
    var rows = [];
    var rowsCount = 0;

    var matches = true;
    while (matches && rowsCount !== count) {
      matches = re.exec(text);
      if (matches && matches.length > 1) {
        ++rowsCount;
        rows.push(matches[1]);
      }
    }

    return rows;
  },
  _countCharsInLine: function _countCharsInLine(text, char) {
    var re = new RegExp(char, 'g');
    var matches = text.match(re);
    return matches ? matches.length : 0;
  },
  _normalizeQuery: function _normalizeQuery(_query, parsers) {
    var query = Object.assign({}, _query);
    var where = query.where,
        join = query.join;


    if (where.$and) {
      where.$and = where.$and.reduce(function (whereResult, condition) {
        Object.keys(condition).forEach(function (rowKey) {
          var conditionValue = condition[rowKey];

          if (typeof conditionValue === 'string' && conditionValue.startsWith('$')) {
            (function () {
              var joinWhere = join[conditionValue].where;

              Object.keys(joinWhere).forEach(function (joinRowKey) {
                var value = joinWhere[joinRowKey];
                var parser = parsers[joinRowKey];

                whereResult[joinRowKey] = parser ? (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object' ? Object.keys(value).reduce(function (callbackConditions, callbackKey) {
                  callbackConditions[callbackKey] = parser(value[callbackKey]);
                  return callbackConditions;
                }, {}) : parser(value) : value;
              });
            })();
          } else {
            var parser = parsers[rowKey];
            whereResult[rowKey] = parser ? parser(conditionValue) : conditionValue;
          }
        });

        return whereResult;
      }, {});
    }

    return query;
  },
  _isDataQuery: function _isDataQuery(from) {
    return [this.QUERY_FROM_DATAPOINTS, this.QUERY_FROM_ENTITIES].includes(from);
  },
  _getRowMapper: function _getRowMapper(query, parsers) {
    var select = query.select;


    return function (row) {
      var correct = true;

      var result = Object.keys(row).reduce(function (result, key) {
        if (correct) {
          var value = row[key];
          var parser = parsers[key];
          var resultValue = void 0;

          if (parser) {
            resultValue = parser(value);
          } else {
            var numeric = parseFloat(value);
            resultValue = !isNaN(numeric) && isFinite(numeric) ? parseFloat(value.replace(',', '.')) : value;
          }

          if (!resultValue && resultValue !== 0) {
            if (select.key.includes(key)) {
              correct = false;
            }
          } else {
            result[key] = resultValue;
          }
        }

        return result;
      }, {});

      return correct && result;
    };
  },
  _getConcepts: function _getConcepts(columns, data) {
    var _this3 = this;

    return columns.map(function (concept, index) {
      var result = { concept: concept };

      if (index < _this3.keySize) {
        result.concept_type = 'entity_domain';
      } else if (index === _this3.keySize) {
        //the column after is expected to have time
        result.concept_type = 'time';
      } else {
        result.concept_type = 'measure';

        for (var i = data.length - 1; i >= 0; i--) {
          if (utils.isString(data[i][concept]) && data[i][concept] !== '') {
            result.concept_type = 'entity_set';

            var _columns = _slicedToArray(columns, 1);

            result.domain = _columns[0];

            break;
          }
        }
      }

      return result;
    });
  },
  _applyQuery: function _applyQuery(query, parsers) {
    var _this4 = this;

    var select = query.select,
        from = query.from;

    var _select$key = _slicedToArray(select.key, 1),
        uniqueKey = _select$key[0];

    var uniqueValues = [];
    var mapRow = this._getRowMapper(query, parsers);

    return function (result, row) {
      row = mapRow(row);

      if (row) {
        var unique = row[uniqueKey];
        var isUnique = from !== _this4.QUERY_FROM_ENTITIES || !uniqueValues.includes(unique);
        var isSuitable = _this4._isSuitableRow(query, row);

        if (isSuitable && isUnique) {
          if (from === _this4.QUERY_FROM_ENTITIES) {
            uniqueValues.push(unique);
          }

          var rowFilteredByKeys = Object.keys(row).reduce(function (resultRow, rowKey) {
            if (select.key.includes(rowKey) || select.value.includes(rowKey)) {
              resultRow[rowKey] = row[rowKey];
            }

            return resultRow;
          }, {});

          result.push(rowFilteredByKeys);
        }
      }

      return result;
    };
  },
  _isSuitableRow: function _isSuitableRow(query, row) {
    var _this5 = this;

    var where = query.where;


    return !where.$and || Object.keys(where.$and).every(function (conditionKey) {
      var condition = where.$and[conditionKey];
      var rowValue = row[conditionKey];

      // if the column is missing, then don't apply filter
      return rowValue === undefined || ((typeof condition === 'undefined' ? 'undefined' : _typeof(condition)) !== 'object' ? rowValue === condition
      //resolve booleans via strings
      || condition === true && utils.isString(rowValue) && rowValue.toLowerCase().trim() === 'true' || condition === false && utils.isString(rowValue) && rowValue.toLowerCase().trim() === 'false' : Object.keys(condition).every(function (callbackKey) {
        return _this5.CONDITION_CALLBACKS[callbackKey](condition[callbackKey], rowValue);
      }));
    });
  },
  error: function error(code, message, payload) {
    return {
      code: code,
      message: message,
      payload: payload
    };
  }
});

exports.default = CSVReader;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _d = __webpack_require__(40);

var _d2 = _interopRequireDefault(_d);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/*!
 * VIZABI POP BY AGE Component
 */

//POP BY AGE CHART COMPONENT
var AgePyramid = _component2.default.extend({

  /**
   * Initializes the component (Bar Chart).
   * Executed once before any template is rendered.
   * @param {Object} config The config passed to the component
   * @param {Object} context The component's parent
   */
  init: function init(config, context) {
    this.name = 'agepyramid';
    this.template = __webpack_require__(442);

    //define expected models for this component
    this.model_expects = [{
      name: "time",
      type: "time"
    }, {
      name: "marker",
      type: "model"
    }, {
      name: "locale",
      type: "locale"
    }, {
      name: "ui",
      type: "ui"
    }];

    var _this = this;
    this.model_binds = {
      "change:time.value": function changeTimeValue(evt) {
        if (!_this._readyOnce) return;
        if (_this.model.time.step != 1 && !_this.snapped && !_this.model.time.playing && !_this.model.time.dragging) {
          var next = d3.bisectLeft(_this.timeSteps, _this.model.time.value);
          if (next != 0 && _this.timeSteps[next] - _this.model.time.value) {
            _this.snapped = true;
            var time = _this.model.time.value;
            var prev = _this.timeSteps[next - 1];
            var next = _this.timeSteps[next];
            var snapTime = time - prev < next - time ? prev : next;
            _this.model.time.value = new Date(snapTime);
          }
        }
        if (!_this.snapped) {
          _this._updateEntities();
          _this.updateBarsOpacity();
        }
        _this.snapped = false;
      },
      "change:marker.select": function changeMarkerSelect(evt) {
        _this.someSelected = _this.model.marker.select.length > 0;
        _this.nonSelectedOpacityZero = false;
      },
      "change:marker.highlight": function changeMarkerHighlight(evt, path) {
        if (!_this._readyOnce) return;
        _this._highlightBars();
      },
      "change:marker.opacitySelectDim": function changeMarkerOpacitySelectDim() {
        _this.updateBarsOpacity();
      },
      "change:marker.opacityRegular": function changeMarkerOpacityRegular() {
        _this.updateBarsOpacity();
      },
      "change:marker.color.palette": function changeMarkerColorPalette(evt) {
        if (!_this._readyOnce) return;
        _this._updateEntities();
      },
      "change:marker.color.scaleType": function changeMarkerColorScaleType(evt) {
        if (!_this._readyOnce) return;
        _this._updateEntities();
      },
      "change:ui.chart.inpercent": function changeUiChartInpercent(evt) {
        if (!_this._readyOnce) return;
        _this._updateLimits();
        _this.resize();
        _this._updateEntities();
      },
      "change:ui.chart.flipSides": function changeUiChartFlipSides(evt) {
        if (!_this._readyOnce) return;
        _this._updateIndicators();
        _this.resize();
        _this._updateEntities();
      }
    };

    //contructor is the same as any component
    this._super(config, context);

    this.xScale = null;
    this.yScale = null;
    this.cScale = null;

    this.xAxis = (0, _d2.default)();
    this.xAxisLeft = (0, _d2.default)();
    this.yAxis = (0, _d2.default)();
    this.xScales = [];
    this.SHIFTEDAGEDIM = "s_age";

    this.totalFieldName = "Total";
  },

  // afterPreload: function() {
  //   var obj = {};
  //   obj["which"] = this.model.marker.axis_x.which;
  //   obj["use"] = this.model.marker.axis_x.use;
  //   this.model.marker_side.hook_total.set(obj);
  // },

  /**
   * DOM is ready
   */
  readyOnce: function readyOnce() {
    var _this = this;
    this.el = this.el ? this.el : d3.select(this.element);
    this.element = this.el;

    this.interaction = this._interaction();

    this.graph = this.element.select('.vzb-bc-graph');
    this.yAxisEl = this.graph.select('.vzb-bc-axis-y');
    this.xAxisEl = this.graph.select('.vzb-bc-axis-x');
    this.xAxisLeftEl = this.graph.select('.vzb-bc-axis-x-left');
    this.yTitleEl = this.graph.select('.vzb-bc-axis-y-title');
    this.barsCrop = this.graph.select('.vzb-bc-bars-crop');
    this.labelsCrop = this.graph.select('.vzb-bc-labels-crop');
    this.bars = this.graph.select('.vzb-bc-bars');
    this.labels = this.graph.select('.vzb-bc-labels');

    this.title = this.element.select('.vzb-bc-title');
    this.titleRight = this.element.select('.vzb-bc-title-right');
    this.year = this.element.select('.vzb-bc-year');

    var _this = this;
    this.on("resize", function () {
      _this._updateEntities();
    });

    this._attributeUpdaters = {
      _newWidth: function _newWidth(d, i) {
        d["x_"] = 0;
        d["width_"] = _this.xScale(_this.shiftedValues[d[_this.AGEDIM]] ? _this.shiftedValues[d[_this.AGEDIM]][d[_this.SIDEDIM]][d[_this.STACKDIM]] : 0);
        if (_this.ui.chart.inpercent) {
          d["width_"] /= _this.total[d[_this.SIDEDIM]];
        }
        return d.width_;
      },
      _newX: function _newX(d, i) {
        var prevSbl = this.previousSibling;
        if (prevSbl) {
          var prevSblDatum = d3.select(prevSbl).datum();
          d["x_"] = prevSblDatum.x_ + prevSblDatum.width_;
        } else {
          d["x_"] = 0;
        }
        return d.x_;
      }
    };
  },

  /*
   * Both model and DOM are ready
   */
  ready: function ready() {

    this.timeSteps = this.model.time.getAllSteps();

    this.shiftScale = d3.scale.linear().domain([this.timeSteps[0], this.timeSteps[this.timeSteps.length - 1]]).range([0, this.timeSteps.length - 1]);

    this.side = this.model.marker.label_side.getEntity();
    this.SIDEDIM = this.side.getDimension();
    this.stack = this.model.marker.label_stack.getEntity();
    this.STACKDIM = this.stack.getDimension() || this.model.marker.color.which;
    this.age = this.model.marker.axis_y.getEntity();
    this.AGEDIM = this.age.getDimension();
    this.TIMEDIM = this.model.time.getDimension();

    this.updateUIStrings();
    this._updateIndicators();
    this._updateLimits();
    this._createStepData(this.model.marker.axis_x);

    this.resize();
    this._updateEntities(true);
    this.updateBarsOpacity();
  },

  updateUIStrings: function updateUIStrings() {
    this.translator = this.model.locale.getTFunction();

    var titleStringY = this.translator("indicator/" + this.model.marker.axis_y.which);

    var yTitle = this.yTitleEl.selectAll("text").data([0]);
    yTitle.enter().append("text");
    yTitle.attr("y", "-6px").attr("x", "-9px").attr("dx", "-0.72em").text(titleStringY);
  },

  /**
   * Changes labels for indicators
   */
  _updateIndicators: function _updateIndicators() {
    var _this = this;
    this.duration = this.model.time.delayAnimations;
    this.yScale = this.model.marker.axis_y.getScale();
    this.xScale = this.model.marker.axis_x.getScale();
    this.yAxis.tickFormat(_this.model.marker.axis_y.getTickFormatter());
    this.xAxis.tickFormat(_this.model.marker.axis_x.getTickFormatter());
    this.xAxisLeft.tickFormat(_this.model.marker.axis_x.getTickFormatter());

    var sideDim = this.SIDEDIM;
    var stackDim = this.STACKDIM;
    var ageDim = this.AGEDIM;
    var group_by = this.age.grouping || 1;

    var ages = this.model.marker.getKeys(ageDim);
    var ageKeys = [];
    ageKeys = ages.map(function (m) {
      return m[ageDim];
    });
    this.ageKeys = ageKeys;

    this.shiftedAgeKeys = this.timeSteps.map(function (m, i) {
      return -i * group_by;
    }).slice(1).reverse().concat(ageKeys);

    var sides = this.model.marker.getKeys(sideDim);
    var sideKeys = [];
    sideKeys = sides.map(function (m) {
      return m[sideDim];
    });

    if (sideKeys.length > 1) {
      var sortFunc = this.ui.chart.flipSides ? d3.ascending : d3.descending;
      sideKeys.sort(sortFunc);
    }
    if (sideKeys.length > 2) sideKeys.length = 2;

    this.sideKeys = sideKeys;

    var stacks = this.model.marker.getKeys(stackDim);
    var stackKeys = [];
    var stackKeys = utils.without(stacks.map(function (m) {
      if (m[stackDim] == _this.totalFieldName) _this.dataWithTotal = true;
      return m[stackDim];
    }), this.totalFieldName);

    var sortedStackKeys = utils.keys(this.model.marker.color.getPalette()).reduce(function (arr, val) {
      if (stackKeys.indexOf(val) != -1) arr.push(val);
      return arr;
    }, []);

    if (sortedStackKeys.length != stackKeys.length) {
      sortedStackKeys = stackKeys.reduce(function (arr, val) {
        if (arr.indexOf(val) == -1) arr.push(val);
        return arr;
      }, sortedStackKeys);
    }
    this.stackKeys = sortedStackKeys;
    this.stackItems = this.model.marker.label_stack.getItems();

    this.stacked = this.ui.chart.stacked && this.model.marker.color.use != "constant" && this.stack.getDimension();

    var sideItems = this.model.marker.label_side.getItems();
    this.twoSided = this.sideKeys.length > 1;
    this.titleRight.classed("vzb-hidden", !this.twoSided);
    if (this.twoSided) {
      this.xScaleLeft = this.xScale.copy();
      this.title.text(sideItems[this.sideKeys[1]]);
      this.titleRight.text(sideItems[this.sideKeys[0]]);
    } else {
      var title = this.sideKeys.length ? sideItems[this.sideKeys[0]] : this.translator("indicator/" + this.model.marker.axis_x.which);
      this.title.text(title);
    }

    this.cScale = this.model.marker.color.getScale();

    var shiftedAgeDim = this.SHIFTEDAGEDIM;
    this.markers = this.model.marker.getKeys(ageDim);
  },

  _updateLimits: function _updateLimits() {
    var _this = this;
    var limits, domain;
    var axisX = this.model.marker.axis_x;
    if (this.ui.chart.inpercent) {
      limits = axisX.getLimitsByDimensions([this.TIMEDIM, this.SIDEDIM, this.AGEDIM, this.STACKDIM]);
      var totals = {};
      var totalCoeff = this.dataWithTotal ? .5 : 1;
      var timeKeys = axisX.getUnique();
      var maxLimits = [];
      utils.forEach(timeKeys, function (time) {
        totals[time] = {};
        utils.forEach(_this.sideKeys, function (side) {
          var ageSum = 0;
          var sideMaxLimits = [];
          utils.forEach(_this.ageKeys, function (age) {
            var stackSum = 0;
            utils.forEach(_this.stackKeys, function (stack) {
              if (limits[time][side][age] && limits[time][side][age][stack]) stackSum += limits[time][side][age][stack].max;
              ageSum += stackSum;
            });
            sideMaxLimits.push(stackSum);
          });
          totals[time][side] = ageSum;
          sideMaxLimits.map(function (v) {
            return maxLimits.push(v / ageSum);
          });
        });
        _this.totals = totals;
      });
      domain = [0, Math.max.apply(Math, maxLimits)];
    } else {
      limits = axisX.getLimitsByDimensions([this.TIMEDIM, this.SIDEDIM, this.AGEDIM, this.STACKDIM]);
      var timeKeys = axisX.getUnique();
      var maxLimits = [];
      utils.forEach(timeKeys, function (time) {
        utils.forEach(_this.sideKeys, function (side) {
          utils.forEach(_this.ageKeys, function (age) {
            var stackSum = 0;
            utils.forEach(_this.stackKeys, function (stack) {
              if (limits[time][side][age] && limits[time][side][age][stack]) stackSum += limits[time][side][age][stack].max;
            });
            maxLimits.push(stackSum);
          });
        });
      });

      domain = axisX.domainMin != null && axisX.domainMax != null ? [+axisX.domainMin, +axisX.domainMax] : [0, Math.max.apply(Math, maxLimits)];
    }
    this.xScale.domain(domain);
    if (this.xScaleLeft) this.xScaleLeft.domain(this.xScale.domain());
  },

  getShiftedValues: function getShiftedValues(hook, time, ageData) {
    var _this = this;
    var iterateGroupKeys = function iterateGroupKeys(data, deep, result, cb) {
      deep--;
      utils.forEach(data, function (d, id) {
        if (deep) {
          result[id] = {};
          iterateGroupKeys(d, deep, result[id], cb);
        } else {
          cb(d, result, id);
        }
      });
    };

    var which = hook.which;
    var use = hook.use;
    var dimTime = this.TIMEDIM;
    var response = {};
    var method = hook.getConceptprops ? hook.getConceptprops().interpolation : null;
    var ageDim = this.AGEDIM;
    var deep = this.stepDataDeep - 1;

    utils.forEach(ageData, function (d, id) {
      var age = d[ageDim];
      response[age] = {};
      iterateGroupKeys(_this.stepDataMoved[age], deep, response[age], function (arr, result, id) {
        var next = d3.bisectLeft(arr.map(function (m) {
          return m[dimTime];
        }), time);

        var value = utils.interpolatePoint(arr, use, which, next, dimTime, time, method);
        result[id] = hook.mapValue(value);
      });
    });

    return response;
  },

  _createStepData: function _createStepData(hook) {
    var _this = this;
    var timeDim = this.TIMEDIM;
    var sideDim = this.SIDEDIM;
    var stackDim = this.STACKDIM;
    var ageDim = this.AGEDIM;

    this.stepData = {};

    var ageShift = 0;
    var group_by = this.age.grouping || 1;

    var groupArray = [ageDim, sideDim, stackDim];
    this.stepDataDeep = groupArray.length;

    utils.forEach(this.timeSteps, function (time, i) {
      var filter = {};
      filter[timeDim] = time;
      var values = _this.model.marker.getValues(filter, groupArray).axis_x;
      var stepData = _this.stepData[time] = {};
      utils.forEach(_this.shiftedAgeKeys, function (key) {
        var shiftedKey = +key + ageShift;
        var value = values[shiftedKey];
        if (!value) {
          if (shiftedKey < 0) {
            value = values[0];
          } else {
            stepData["null"] = values[0];
          }
        }
        stepData[key] = value;
      });
      ageShift += group_by;
    });

    var stepData = this.stepData;
    var stepDataMoved = {};
    var which = hook.which;
    var use = hook.use;
    utils.forEach(stepData, function (time, timeKey) {
      utils.forEach(time, function (age, ageKey) {
        var allToNull = false;
        if (ageKey == "null") return;
        if (!age && age != 0) {
          age = stepData[timeKey]["null"];
          allToNull = true;
        }
        utils.forEach(age, function (side, sideKey) {
          utils.forEach(side, function (value, stackKey) {
            var age = stepDataMoved[ageKey] || {};
            var side = age[sideKey] || {};
            var stack = side[stackKey] || [];
            var point = {};
            point[timeDim] = new Date(timeKey);
            point[which] = allToNull || value == null ? 0 : value;
            stack.push(point);
            side[stackKey] = stack;
            age[sideKey] = side;
            stepDataMoved[ageKey] = age;
          });
        });
      });
    });

    this.stepDataMoved = stepDataMoved;
  },

  _interpolateBetweenTotals: function _interpolateBetweenTotals(timeSteps, totals, time) {
    var nextStep = d3.bisectLeft(timeSteps, time);
    var fraction = (time - timeSteps[nextStep - 1]) / (timeSteps[nextStep] - timeSteps[nextStep - 1]);
    var total = {};
    utils.forEach(this.sideKeys, function (side) {
      total[side] = totals[timeSteps[nextStep]][side] * fraction + totals[timeSteps[nextStep - 1]][side] * (1 - fraction);
    });
    return total;
  },

  /**
   * Updates entities
   */
  _updateEntities: function _updateEntities(reorder) {

    var _this = this;
    var time = this.model.time;
    var sideDim = this.SIDEDIM;
    var ageDim = this.AGEDIM;
    var stackDim = this.STACKDIM;
    var timeDim = this.TIMEDIM;
    var duration = time.playing ? time.delayAnimations : 0;
    var total;

    var group_by = this.age.grouping || 1;
    //var group_offset = this.model.marker.group_offset ? Math.abs(this.model.marker.group_offset % group_by) : 0;

    if (this.ui.chart.inpercent) {
      this.total = this.totals[time.value] ? this.totals[time.value] : this._interpolateBetweenTotals(this.timeSteps, this.totals, time.value);
    }

    // this.model.marker.getFrame(time.value, function(frame) {
    //   _this.frame = frame;
    // })

    var domain = this.yScale.domain();

    //this.model.age.setVisible(markers);

    var nextStep = d3.bisectLeft(this.timeSteps, time.value);

    var shiftedAgeDim = this.SHIFTEDAGEDIM;

    var markers = this.markers.map(function (data) {
      var o = {};
      o[ageDim] = o[shiftedAgeDim] = +data[ageDim];
      o[ageDim] -= nextStep * group_by;
      return o;
    });

    var ageBars = markers.slice(0);

    var outAge = {};
    outAge[shiftedAgeDim] = markers.length * group_by;
    outAge[ageDim] = outAge[shiftedAgeDim] - nextStep * group_by;

    if (nextStep) ageBars.push(outAge);

    this.shiftedValues = this.stepData[time.value];
    if (!this.shiftedValues) this.shiftedValues = this.getShiftedValues(this.model.marker.axis_x, time.value, ageBars);
    var shiftedValues = this.shiftedValues;

    this.entityBars = this.bars.selectAll('.vzb-bc-bar').data(ageBars, function (d) {
      return d[ageDim];
    });

    this.entityLabels = this.labels.selectAll('.vzb-bc-label').data(markers);

    //exit selection
    this.entityBars.exit().remove();
    this.entityLabels.exit().remove();

    var oneBarHeight = this.oneBarHeight;
    var barHeight = this.barHeight;
    var firstBarOffsetY = this.firstBarOffsetY;

    //enter selection -- init bars
    this.entityBars.enter().append("g").attr("class", function (d) {
      return "vzb-bc-bar " + "vzb-bc-bar-" + d[ageDim];
    });

    this.entityBars.attr("class", function (d) {
      return "vzb-bc-bar " + "vzb-bc-bar-" + d[ageDim];
    });

    this.sideBars = this.entityBars.selectAll('.vzb-bc-side').data(function (d) {
      return _this.sideKeys.map(function (m) {
        var r = {};
        r[ageDim] = d[ageDim];
        r[shiftedAgeDim] = d[shiftedAgeDim];
        r[sideDim] = m;
        return r;
      });
    }, function (d) {
      return d[sideDim];
    });

    this.sideBars.exit().remove();
    this.sideBars.enter().append("g").attr("class", function (d, i) {
      return "vzb-bc-side " + "vzb-bc-side-" + (!i != !_this.twoSided ? "right" : "left");
    });
    this.sideBars.attr("transform", function (d, i) {
      return i ? "scale(-1,1) translate(" + _this.activeProfile.centerWidth + ",0)" : "";
    });

    if (reorder) {
      this.sideBars.attr("transform", function (d, i) {
        return i ? "scale(-1,1) translate(" + _this.activeProfile.centerWidth + ",0)" : "";
      });
    }

    this.stackBars = this.sideBars.selectAll('.vzb-bc-stack').data(function (d, i) {
      var stacks = _this.stacked ? _this.stackKeys : [_this.totalFieldName];
      return stacks.map(function (m) {
        var r = {};
        r[ageDim] = d[ageDim];
        r[shiftedAgeDim] = d[shiftedAgeDim];
        r[sideDim] = d[sideDim];
        r[stackDim] = m;
        return r;
      });
    }, function (d) {
      return d[stackDim];
    });

    this.stackBars.exit().remove();
    this.stackBars.enter().append("rect").attr("class", function (d, i) {
      return "vzb-bc-stack " + "vzb-bc-stack-" + i + (_this.highlighted ? " vzb-dimmed" : "");
    }).attr("y", 0).attr("height", barHeight).attr("fill", function (d) {
      return _this.cScale(d[stackDim]);
    }).on("mouseover", _this.interaction.mouseover).on("mouseout", _this.interaction.mouseout).on("click", _this.interaction.click).onTap(_this.interaction.tap);

    if (reorder) this.stackBars.order();

    // this.stackBars = this.bars.selectAll('.vzb-bc-bar')
    //   .selectAll('.vzb-bc-side')
    //     .attr("transform", function(d, i) {
    //       return i ? ("scale(-1,1) translate(" + _this.activeProfile.centerWidth + ",0)") : "";
    //     })
    //   .selectAll('.vzb-bc-stack')
    //     .attr("height", barHeight)
    //     .attr("fill", function(d) {
    //       //return _this._temporaryBarsColorAdapter(values, d, ageDim);
    //       //return _this.cScale(values.color[d[ageDim]]);
    //       return _this.cScale(d[stackDim]);
    //     })
    //     //.attr("shape-rendering", "crispEdges") // this makes sure there are no gaps between the bars, but also disables anti-aliasing
    //     .each(function(d, i) {
    //       var total = _this.ui.chart.inpercent ? _this.totalValues[d[sideDim]] : 1;
    //       var sum = 0;
    //       if(shiftedValues[d[ageDim]]) {
    //         if(_this.stacked) {
    //           sum = shiftedValues[d[ageDim]][d[sideDim]][d[stackDim]];
    //         } else {
    //           var stacksData = shiftedValues[d[ageDim]][d[sideDim]];
    //           utils.forEach(stacksData, function(val) {
    //             sum += val;
    //           });
    //         }
    //       }
    //       //var prevWidth = +this.getAttribute("width");
    //       d["width_"] = _this.xScale(sum / total);
    //       //d3.select(this).classed("vzb-hidden", d["width_"] < 1 && prevWidth < 1);

    //       var prevSbl = this.previousSibling;
    //       if(prevSbl) {
    //         var prevSblDatum = d3.select(prevSbl).datum();
    //         d["x_"] = prevSblDatum.x_ + prevSblDatum.width_;
    //       } else {
    //         d["x_"] = 0;
    //       }
    //     });

    var stepShift = ageBars[0][shiftedAgeDim] - ageBars[0][ageDim] - this.shiftScale(time.value) * group_by;

    this.entityBars.attr("transform", function (d, i) {
      return "translate(0," + (firstBarOffsetY - (d[shiftedAgeDim] - group_by - domain[0]) * oneBarHeight) + ")";
    }).transition('age').duration(duration).ease("linear").attr("transform", function (d, i) {
      return "translate(0," + (firstBarOffsetY - (d[shiftedAgeDim] - domain[0] - stepShift) * oneBarHeight) + ")";
    });

    var _attributeUpdaters = this._attributeUpdaters;
    if (duration) {
      this.stackBars.transition().duration(duration * .95).ease("linear").attr("width", _attributeUpdaters._newWidth).attr("x", _attributeUpdaters._newX);
    } else {
      this.stackBars.interrupt().attr("width", _attributeUpdaters._newWidth).attr("x", _attributeUpdaters._newX).transition();
    }

    this.entityLabels.enter().append("g").attr("class", "vzb-bc-label").attr("id", function (d) {
      return "vzb-bc-label-" + d[shiftedAgeDim] + "-" + _this._id;
    }).append('text').attr("class", "vzb-bc-age");

    this.labels.selectAll('.vzb-bc-label > .vzb-bc-age').each(function (d, i) {
      var yearOlds = _this.translator("agepyramid/yearOlds");

      var age = parseInt(d[ageDim], 10);

      if (group_by > 1) {
        age = age + "-to-" + (age + group_by - 1);
      }

      d["text"] = age + yearOlds;
    }).attr("y", function (d, i) {
      return firstBarOffsetY - (d[shiftedAgeDim] - domain[0]) * oneBarHeight - 10;
    });
    // .style("fill", function(d) {
    //   var color = _this.cScale(values.color[d[ageDim]]);
    //   return d3.rgb(color).darker(2);
    // });

    if (duration) {
      this.year.transition().duration(duration).ease("linear").each("end", this._setYear(time.value));
    } else {
      this.year.interrupt().text(time.formatDate(time.value)).transition();
    }
  },

  _setYear: function _setYear(timeValue) {
    var formattedTime = this.model.time.formatDate(timeValue);
    return function () {
      d3.select(this).text(formattedTime);
    };
  },

  _interaction: function _interaction() {
    var _this = this;
    return {
      mouseover: function mouseover(d, i) {
        if (utils.isTouchDevice()) return;
        _this.model.marker.highlightMarker(d);
        _this._showLabel(d);
      },
      mouseout: function mouseout(d, i) {
        if (utils.isTouchDevice()) return;
        _this.model.marker.clearHighlighted();
      },
      click: function click(d, i) {
        if (utils.isTouchDevice()) return;
        _this.model.marker.selectMarker(d);
      },
      tap: function tap(d) {
        d3.event.stopPropagation();
        _this.model.marker.selectMarker(d);
      }
    };
  },

  _highlightBars: function _highlightBars(d) {
    var _this = this;

    _this.someHighlighted = _this.model.marker.highlight.length > 0;

    _this.updateBarsOpacity();

    if (!_this.someHighlighted) {
      //hide labels
      _this.labels.selectAll('.vzb-hovered').classed('vzb-hovered', false);
    }
  },

  _showLabel: function _showLabel(d) {
    var _this = this;
    var formatter = _this.ui.chart.inpercent ? d3.format(".1%") : _this.model.marker.axis_x.getTickFormatter();
    var sideDim = _this.SIDEDIM;
    var ageDim = _this.AGEDIM;
    var stackDim = _this.STACKDIM;
    var shiftedAgeDim = "s_age";

    var left = _this.sideKeys.indexOf(d[sideDim]);
    var label = _this.labels.select("#vzb-bc-label-" + d[shiftedAgeDim] + "-" + _this._id);
    label.selectAll('.vzb-bc-age').text(function (textData) {
      //var total = _this.ui.chart.inpercent ? _this.totalValues[d[sideDim]] : 1;
      var text = _this.stackKeys.length > 1 ? _this.stackItems[d[stackDim]] : textData.text;
      text = _this.twoSided ? text : textData.text + " " + _this.stackItems[d[stackDim]];
      var value = _this.xScale.invert(d["width_"]);
      //var value = (_this.dataWithTotal || _this.stacked) ? _this.values1.axis_x[d[shiftedAgeDim]][d[sideDim]][d[stackDim]] / total : _this.xScale.invert(d["width_"]);
      return text + ": " + formatter(value);
    }).attr("x", (left ? -1 : 1) * (_this.activeProfile.centerWidth * .5 + 7)).classed("vzb-text-left", left);

    label.classed('vzb-hovered', true);
  },

  /**
   * Executes everytime the container or vizabi is resized
   * Ideally,it contains only operations related to size
   */

  presentationProfileChanges: {
    medium: {
      margin: { right: 80, bottom: 80 },
      infoElHeight: 32
    },
    large: {
      margin: { top: 100, right: 100, left: 100, bottom: 80 },
      infoElHeight: 32
    }
  },

  profiles: {
    "small": {
      margin: {
        top: 70,
        right: 20,
        left: 40,
        bottom: 40
      },
      minRadius: 2,
      maxRadius: 40,
      centerWidth: 2,
      titlesSpacing: 5
    },
    "medium": {
      margin: {
        top: 80,
        right: 60,
        left: 60,
        bottom: 40
      },
      minRadius: 3,
      maxRadius: 60,
      centerWidth: 2,
      titlesSpacing: 10
    },
    "large": {
      margin: {
        top: 100,
        right: 60,
        left: 60,
        bottom: 40
      },
      minRadius: 4,
      maxRadius: 80,
      centerWidth: 2,
      titlesSpacing: 20
    }
  },

  resize: function resize() {

    var _this = this;

    this.activeProfile = this.getActiveProfile(this.profiles, this.presentationProfileChanges);

    //this.activeProfile = this.profiles[this.getLayoutProfile()];
    var margin = this.activeProfile.margin;

    //stage
    this.height = parseInt(this.element.style("height"), 10) - margin.top - margin.bottom || 0;
    this.width = parseInt(this.element.style("width"), 10) - margin.left - margin.right || 0;

    if (this.height <= 0 || this.width <= 0) return utils.warn("Pop by age resize() abort: vizabi container is too little or has display:none");

    this.graph.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    this.barsCrop.attr("width", this.width).attr("height", Math.max(0, this.height));

    this.labelsCrop.attr("width", this.width).attr("height", Math.max(0, this.height));

    var group_by = this.age.grouping || 1;

    var domain = this.yScale.domain();
    this.oneBarHeight = this.height / (domain[1] - domain[0]);
    var barHeight = this.barHeight = this.oneBarHeight * group_by; // height per bar is total domain height divided by the number of possible markers in the domain
    this.firstBarOffsetY = this.height - this.barHeight;

    if (this.stackBars) this.stackBars.attr("height", barHeight);

    if (this.sideBars) this.sideBars.attr("transform", function (d, i) {
      return i ? "scale(-1,1) translate(" + _this.activeProfile.centerWidth + ",0)" : "";
    });

    //update scales to the new range
    if (this.model.marker.axis_y.scaleType !== "ordinal") {
      this.yScale.range([this.height, 0]);
    } else {
      this.yScale.rangePoints([this.height, 0]).range();
    }

    var maxRange = this.twoSided ? (this.width - this.activeProfile.centerWidth) * .5 : this.width;

    if (this.model.marker.axis_x.scaleType !== "ordinal") {
      this.xScale.range([0, maxRange]);
    } else {
      this.xScale.rangePoints([0, maxRange]).range();
    }

    //apply scales to axes and redraw
    this.yAxis.scale(this.yScale).orient("left").tickSize(-this.width, 0).tickPadding(6).tickSizeMinor(-this.width, 0).labelerOptions({
      scaleType: this.model.marker.axis_y.scaleType,
      toolMargin: margin,
      limitMaxTickNumber: 19
    });

    var format = this.ui.chart.inpercent ? d3.format((group_by > 3 ? "" : ".1") + "%") : this.model.marker.axis_x.getTickFormatter();

    this.xAxis.scale(this.xScale).orient("bottom").tickFormat(format).tickSize(-this.height, 0).tickPadding(6).tickSizeMinor(-this.height, 0).labelerOptions({
      scaleType: this.model.marker.axis_x.scaleType,
      toolMargin: margin,
      limitMaxTickNumber: 6
    });

    var translateX = this.twoSided ? (this.width + _this.activeProfile.centerWidth) * .5 : 0;

    this.xAxisEl.attr("transform", "translate(" + translateX + "," + this.height + ")").call(this.xAxis);

    this.yAxisEl.attr("transform", "translate(" + 0 + ",0)").call(this.yAxis);
    //this.xAxisEl.call(this.xAxis);
    this.xAxisLeftEl.classed("vzb-hidden", !this.twoSided);
    if (this.twoSided) {
      if (this.model.marker.axis_x.scaleType !== "ordinal") {
        this.xScaleLeft.range([(this.width - this.activeProfile.centerWidth) * .5, 0]);
      } else {
        this.xScaleLeft.rangePoints([(this.width - this.activeProfile.centerWidth) * .5, 0]).range();
      }

      this.xAxisLeft.scale(this.xScaleLeft).orient("bottom").tickFormat(format).tickSize(-this.height, 0).tickPadding(6).tickSizeMinor(-this.height, 0).labelerOptions({
        scaleType: this.model.marker.axis_x.scaleType,
        toolMargin: margin,
        limitMaxTickNumber: 6
      });

      this.xAxisLeftEl.attr("transform", "translate(0," + this.height + ")").call(this.xAxisLeft);
      var zeroTickEl = this.xAxisEl.select(".tick text");
      if (!zeroTickEl.empty()) {
        var zeroTickWidth = zeroTickEl.node().getBBox().width;
        zeroTickEl.attr("dx", -(this.activeProfile.centerWidth + zeroTickWidth) * .5);
      }
    }

    this.bars.attr("transform", "translate(" + translateX + ",0)");
    this.labels.attr("transform", "translate(" + translateX + ",0)");

    this.title.attr('x', margin.left + (this.twoSided ? translateX - this.activeProfile.titlesSpacing : 0)).style('text-anchor', this.twoSided ? "end" : "").attr('y', margin.top / 2);
    this.titleRight.attr('x', margin.left + translateX + this.activeProfile.titlesSpacing).attr('y', margin.top / 2);

    this.year.attr('x', this.width + margin.left).attr('y', margin.top / 2);
  },

  updateBarsOpacity: function updateBarsOpacity(duration) {
    var _this = this;
    //if(!duration)duration = 0;

    var OPACITY_HIGHLT = 1.0;
    var OPACITY_HIGHLT_DIM = this.model.marker.opacityHighlightDim;
    var OPACITY_SELECT = this.model.marker.opacityRegular;
    var OPACITY_REGULAR = this.model.marker.opacityRegular;
    var OPACITY_SELECT_DIM = this.model.marker.opacitySelectDim;

    this.stackBars
    //.transition().duration(duration)
    .style("opacity", function (d) {

      if (_this.someHighlighted) {
        //highlight or non-highlight
        if (_this.model.marker.isHighlighted(d)) return OPACITY_HIGHLT;
      }

      if (_this.someSelected) {
        //selected or non-selected
        return _this.model.marker.isSelected(d) ? OPACITY_SELECT : OPACITY_SELECT_DIM;
      }

      if (_this.someHighlighted) return OPACITY_HIGHLT_DIM;

      return OPACITY_REGULAR;
    });

    var nonSelectedOpacityZero = _this.model.marker.opacitySelectDim < .01;

    // when pointer events need update...
    if (nonSelectedOpacityZero != this.nonSelectedOpacityZero) {
      this.stackBars.style("pointer-events", function (d) {
        return !_this.someSelected || !nonSelectedOpacityZero || _this.model.marker.isSelected(d) ? "visible" : "none";
      });
    }

    this.nonSelectedOpacityZero = _this.model.marker.opacitySelectDim < .01;
  }

});

exports.default = AgePyramid;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _labels = __webpack_require__(86);

var _labels2 = _interopRequireDefault(_labels);

var _iconset = __webpack_require__(10);

var _d3Geo = __webpack_require__(135);

var _d3Geo2 = _interopRequireDefault(_d3Geo);

var _d = __webpack_require__(66);

var _d2 = _interopRequireDefault(_d);

var _globals = __webpack_require__(44);

var _globals2 = _interopRequireDefault(_globals);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

//import Selectlist from 'bubblemap-selectlist';

//BUBBLE MAP CHART COMPONENT
var CartogramComponent = _component2.default.extend({
  /**
   * Initializes the component (Bubble Map Chart).
   * Executed once before any template is rendered.
   * @param {Object} config The config passed to the component
   * @param {Object} context The component's parent
   */
  init: function init(config, context) {
    this.name = 'cartogram';
    this.template = __webpack_require__(448);

    //http://stackoverflow.com/questions/11381673/detecting-a-mobile-browser
    var mobileAndTabletcheck = function mobileAndTabletcheck() {
      var check = false;
      (function (a) {
        if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) check = true;
      })(navigator.userAgent || navigator.vendor || window.opera);
      return check;
    };
    this.isMobile = mobileAndTabletcheck();

    //define expected models for this component
    this.model_expects = [{
      name: "time",
      type: "time"
    }, {
      name: "entities",
      type: "entities"
    }, {
      name: "marker",
      type: "model"
    }, {
      name: "locale",
      type: "locale"
    }, {
      name: "ui",
      type: "ui"
    }];

    var _this = this;
    this.model_binds = {
      "change:time.value": function changeTimeValue(evt) {
        if (!_this._readyOnce) return;
        if (!_this.calculationQueue) {
          // collect timestamp that we request
          _this.calculationQueue = [_this.model.time.value.toString()];
        } else {
          _this.calculationQueue.push(_this.model.time.value.toString());
        }
        (function (time) {
          // isolate timestamp
          _this.model.marker.getFrame(time, function (frame, time) {
            var index = _this.calculationQueue.indexOf(time.toString()); //
            if (index == -1) {
              // we was receive more recent frame before so we pass this frame
              return;
            } else {
              _this.calculationQueue.splice(0, index + 1); // remove timestamps that added to queue before current timestamp
            }
            _this.frameChanged(frame, time);
          });
        })(_this.model.time.value);
      },
      'change:marker.size.extent': function changeMarkerSizeExtent(evt, path) {
        //console.log("EVENT change:marker:size:max");
        if (!_this._readyOnce) return;
        _this.updateMarkerSizeLimits();
        _this.updateEntities();
      },
      "change:marker.color.scaleType": function changeMarkerColorScaleType(evt, path) {
        _this.updateIndicators();
        _this.updateEntitityColor();
      },

      'change:marker.size.use': function changeMarkerSizeUse(evt, path) {
        _this.model.ui.chart.lockActive = _this.model.marker.size.use != "constant";
      },
      "change:marker.color.palette": function changeMarkerColorPalette(evt, path) {
        _this.updateEntitityColor();
      },
      "change:ui.chart.lockNonSelected": function changeUiChartLockNonSelected(evt) {
        _this.updateEntities(900);
      },
      "change:entities.select": function changeEntitiesSelect() {
        if (!_this._readyOnce) return;
        _this.updateLandOpacity();
      },
      "change:entities.highlight": function changeEntitiesHighlight() {
        if (!_this._readyOnce) return;
        //console.log("EVENT change:entities:highlight");
        _this.updateLandOpacity();
      },
      'change:entities.opacitySelectDim': function changeEntitiesOpacitySelectDim() {
        _this.updateLandOpacity();
      },
      'change:entities.opacityRegular': function changeEntitiesOpacityRegular() {
        _this.updateLandOpacity();
      }
    };
    //this._selectlist = new Selectlist(this);

    //contructor is the same as any component
    this._super(config, context);

    _this.COLOR_LAND_DEFAULT = "#fdfdfd";

    this.lands = null;
    this.features = null;
    this.topo_features = null;
    this.borderArcs = null;
    this.defaultWidth = 700;
    this.defaultHeight = 550;
    this.updateEntitiesQueue = [];
    this.boundBox = [[0.05, 0.0], [0.95, 1.0]]; // two points to set box bound on 960 * 500 image;
    (0, _d3Geo2.default)();
    this.cached = [];
    this.projection = d3.geo.mercator().center([25, -29]).scale(1900).translate([this.defaultWidth / 2, this.defaultHeight / 2]).precision(.1);

    this.cartogram = d3.cartogram().projection(this.projection).properties(function (d) {
      return d.properties;
    });

    this._labels = new _labels2.default(this);
    this._labels.config({
      CSS_PREFIX: 'vzb-ct',
      LABELS_CONTAINER_CLASS: 'vzb-ct-labels',
      LINES_CONTAINER_CLASS: 'vzb-ct-lines'
    });
  },

  afterPreload: function afterPreload() {
    var _this = this;
    if (!this.world) utils.warn("cartogram afterPreload: missing country shapes " + this.world);
    if (!this.geometries) utils.warn("cartogram afterPreload: missing country shapes " + this.geometries);

    // http://bl.ocks.org/mbostock/d4021aa4dccfd65edffd patterson
    // http://bl.ocks.org/mbostock/3710566 robinson
    // map background

    this.borderArcs = _this.cartogram.meshArcs(this.world, this.world.objects.topo, function (a, b) {
      return a.properties.MN_NAME && a.properties.PR_NAME !== b.properties.PR_NAME;
    });
  },
  _getKey: function _getKey(d) {
    return d.properties[this.id_lookup] ? d.properties[this.id_lookup].toString() : d.id.toString();
  },
  /**
   * DOM is ready
   */
  readyOnce: function readyOnce() {

    this.element = d3.select(this.element);

    this.graph = this.element.select('.vzb-ct-graph');
    this.mapSvg = this.element.select('.vzb-ct-map-background');

    this.labelsContainerCrop = this.graph.select('.vzb-ct-labels-crop');
    this.labelsContainer = this.graph.select('.vzb-ct-labels');

    this.yTitleEl = this.graph.select(".vzb-ct-axis-y-title");
    this.sTitleEl = this.graph.select(".vzb-ct-axis-c-title");
    this.yInfoEl = this.graph.select(".vzb-ct-axis-y-info");
    this.sInfoEl = this.graph.select(".vzb-ct-axis-c-info");
    this.dataWarningEl = this.graph.select(".vzb-data-warning");
    this.entityBubbles = null;
    this.tooltip = this.element.select('.vzb-ct-tooltip');

    // year background
    this.yearEl = this.graph.select('.vzb-ct-year');
    this.year = new _d2.default(this.yearEl);
    this.year.setConditions({ xAlign: 'left', yAlign: 'bottom', bottomOffset: 5 });
    this.mapGraph = this.element.select(".vzb-ct-map-graph").attr("width", this.defaultWidth).attr("height", this.defaultHeight);
    this.mapGraph.html('');

    this.KEY = this.model.entities.getDimension();
    this.TIMEDIM = this.model.time.getDimension();

    var _this = this;
    this.updateUIStrings();
    this.on("resize", function () {
      if (_this.updateSize()) return;
    });
    this.wScale = d3.scale.linear().domain(this.model.ui.datawarning.doubtDomain).range(this.model.ui.datawarning.doubtRange);

    this.cartogram.iterations(0);
    this.redrawInProgress = true;

    this.cartogram(this.world, this.geometries).then(function (response) {
      _this.redrawInProgress = false;

      _this.features = _this.topo_features = response.features;
      _this.lands = _this.mapGraph.selectAll(".land").data(_this.topo_features).enter().append("path").attr("class", function (d) {
        return "land " + (d.properties[_this.id_lookup] ? d.properties[_this.id_lookup] : d.id);
      }).attr("d", _this.cartogram.path).on("mouseover", function (d, i) {
        if (utils.isTouchDevice()) return;
        _this._interact()._mouseover(d, i);
      }).on("mouseout", function (d, i) {
        if (utils.isTouchDevice()) return;
        _this._interact()._mouseout(d, i);
      }).on("click", function (d, i) {
        if (utils.isTouchDevice()) return;
        _this._interact()._click(d, i);
      }).each(function (d) {
        d[_this.KEY] = _this._getKey(d);
      });

      if (_this.borderArcs) {
        var data = _this.cartogram.stitchArcs(response, _this.borderArcs);
        _this.borders = _this.mapGraph.append("path").datum(data).attr("class", "boundary").attr("d", _this.cartogram.path);
      }
    });
  },

  frameChanged: function frameChanged(frame, time) {
    if (time.toString() != this.model.time.value.toString()) return; // frame is outdated
    if (!frame) return;
    this.values = frame;
    this.updateTime();
    this.updateTitleNumbers();
    this.updateEntities(this.duration);
  },

  /*
   * Both model and DOM are ready
   */
  ready: function ready() {
    var _this = this;
    this.cached = [];
    this.updateIndicators();
    this.updateUIStrings();
    this.updateMarkerSizeLimits();
    this.updateSize();
    this.model.marker.getFrame(_this.model.time.value, _this.frameChanged.bind(_this));
  },

  /**
   * Changes labels for indicators
   */
  updateIndicators: function updateIndicators() {
    this.sScale = this.model.marker.size.getScale();
    this.cScale = this.model.marker.color.getScale();
  },

  updateMarkerSizeLimits: function updateMarkerSizeLimits() {
    var _this = this;
    var extent = this.model.marker.size.extent || [0, 1];
    this.minRadius = Math.max(100 * extent[0], 0);
    this.maxRadius = Math.max(100 * extent[1], 0);

    this.sScale.domain([0, this.sScale.domain()[1]]);
    if (this.model.marker.size.scaleType !== "ordinal") {
      this.sScale.range([this.minRadius, this.maxRadius]);
    } else {
      this.sScale.rangePoints([this.minRadius, this.maxRadius], 0).range();
    }
  },

  _calculateTotalSize: function _calculateTotalSize(year, frame) {
    if (this.cached[year]) {
      return this.cached[year];
    }
    var _this = this;
    this.cached[year] = 0;
    utils.forEach(frame, function (val) {
      _this.cached[year] += _this.sScale(val);
    });
    return this.cached[year];
  },

  _redrawEntities: function _redrawEntities() {
    var _this = this;
    if (this.updateEntitiesQueue.length == 0) return;
    if (this.redrawInProgress) {
      setTimeout(function () {
        _this._redrawEntities();
      }, 100);
      return;
    }
    this.redrawInProgress = true;
    var time = this.updateEntitiesQueue[this.updateEntitiesQueue.length - 1].time;
    var duration = this.updateEntitiesQueue[this.updateEntitiesQueue.length - 1].duration;
    this.updateEntitiesQueue = [];
    if (this.model.ui.chart.lockNonSelected) {
      time = this.model.time.parse("" + this.model.ui.chart.lockNonSelected);
    }
    this.model.marker.getFrame(time, function (lockedFrame) {
      var totValue = null;
      if (_this.model.marker.size.use == "constant") {
        _this.cartogram.iterations(0);
      } else {
        _this.cartogram.iterations(8);
        //var areas = _this.topo_features.map(d3.geo.path().projection(null).area);
        _this.cartogram.value(function (d) {
          if (_this.model.ui.chart.lockNonSelected) {
            var size1 = _this.sScale(lockedFrame.size[_this._getKey(d)]) /* * _this._calculateTotalSize(_this.model.time.value, _this.values.size)*/
            ,
                size2 = _this.sScale(_this.values.size[_this._getKey(d)]) /* * _this._calculateTotalSize(time, lockedFrame.size)*/;
            return d3.geo.path().projection(null).area(d) * Math.pow(size2 / size1, 2);
          } else {
            return _this.sScale(_this.values.size[_this._getKey(d)]);
          }
        });
        /*
         if (_this.model.ui.chart.lockNonSelected) {
         totValue = d3.sum(areas);
         }
         */
      }
      var calcDuration = 0;
      var start = new Date().getTime();
      _this.cartogram(_this.world, _this.geometries, totValue).then(function (response) {
        var end = new Date().getTime();
        if (duration) {
          // increale duration for prevent gaps between frames
          duration = Math.max(duration, end - start);
        }
        _this.features = response.features;
        if (_this.borderArcs) {
          var data = _this.cartogram.stitchArcs(response, _this.borderArcs);
          _this.borders.datum(data).transition().duration(duration).ease("linear").attr("d", _this.cartogram.path);
        }
        _this.lands.data(_this.features).each(function (d) {
          d[_this.KEY] = _this._getKey(d);
        });
        if (duration) {
          _this.lands.interrupt().transition().duration(duration).ease("linear").style("fill", function (d) {
            return _this.values.color[_this._getKey(d)] != null ? _this.cScale(_this.values.color[_this._getKey(d)]) : _this.COLOR_LAND_DEFAULT;
          }).attr("d", _this.cartogram.path);
          if (_this.borderArcs) {
            _this.borders.interrupt().transition().duration(duration).ease("linear").attr("d", _this.cartogram.path);
          }
        } else {
          _this.borders.attr("d", _this.cartogram.path);

          _this.lands.style("fill", function (d) {
            return _this.values.color[_this._getKey(d)] != null ? _this.cScale(_this.values.color[_this._getKey(d)]) : _this.COLOR_LAND_DEFAULT;
          }).attr("d", _this.cartogram.path);
        }
        _this.updateLandOpacity();
        _this.redrawInProgress = false;
        _this._redrawEntities();
      });
    });
  },

  updateEntities: function updateEntities(duration) {
    var time = this.model.time.value;

    this.updateEntitiesQueue.push({ time: time, duration: duration });
    this._redrawEntities();
  },

  updateEntitityColor: function updateEntitityColor() {
    var _this = this;
    this.lands.transition().duration(_this.duration).ease("linear").style("fill", function (d) {
      return _this.values.color[_this._getKey(d)] != null ? _this.cScale(_this.values.color[_this._getKey(d)]) : _this.COLOR_LAND_DEFAULT;
    });
  },
  updateUIStrings: function updateUIStrings() {
    var _this = this;

    this.translator = this.model.locale.getTFunction();
    var sizeConceptprops = this.model.marker.size.getConceptprops();
    this.strings = {
      title: {
        C: (_this.model.marker.size.use !== "constant" ? this.translator("buttons/color") + ": " : "") + this.translator("indicator/" + _this.model.marker.color.which),
        S: this.translator("buttons/size") + ": " + this.translator("indicator/" + _this.model.marker.size.which)
      }
    };

    this.yTitleEl.select("text")
    //don't show "Color:" when the size is constant and we are only showing color
    .text(this.strings.title.C).on("click", function () {
      _this.parent.findChildByName("gapminder-treemenu").markerID("color").alignX("left").alignY("top").updateView().toggle();
    });

    this.sTitleEl.select("text").text(this.strings.title.S).on("click", function () {
      _this.parent.findChildByName("gapminder-treemenu").markerID("size").alignX("left").alignY("top").updateView().toggle();
    });

    utils.setIcon(this.dataWarningEl, _iconset.warn).select("svg").attr("width", "0px").attr("height", "0px");
    this.dataWarningEl.append("text").attr("text-anchor", "end").text(this.translator("hints/dataWarning"));

    this.dataWarningEl.on("click", function () {
      _this.parent.findChildByName("gapminder-datawarning").toggle();
    }).on("mouseover", function () {
      _this.updateDoubtOpacity(1);
    }).on("mouseout", function () {
      _this.updateDoubtOpacity();
    });

    this.yInfoEl.html(_iconset.question).select("svg").attr("width", "0px").attr("height", "0px");

    //TODO: move away from UI strings, maybe to ready or ready once
    this.yInfoEl.on("click", function () {
      _this.parent.findChildByName("gapminder-datanotes").pin();
    });
    this.yInfoEl.on("mouseover", function () {
      var rect = this.getBBox();
      var coord = utils.makeAbsoluteContext(this, this.farthestViewportElement)(rect.x - 10, rect.y + rect.height + 10);
      _this.parent.findChildByName("gapminder-datanotes").setHook('size').show().setPos(coord.x, coord.y);
    });
    this.yInfoEl.on("mouseout", function () {
      _this.parent.findChildByName("gapminder-datanotes").hide();
    });

    this.sInfoEl.html(_iconset.question).select("svg").attr("width", "0px").attr("height", "0px");

    //TODO: move away from UI strings, maybe to ready or ready once
    this.sInfoEl.on("click", function () {
      _this.parent.findChildByName("gapminder-datanotes").pin();
    });
    this.sInfoEl.on("mouseover", function () {
      var rect = this.getBBox();
      var coord = utils.makeAbsoluteContext(this, this.farthestViewportElement)(rect.x - 10, rect.y + rect.height + 10);
      _this.parent.findChildByName("gapminder-datanotes").setHook('color').show().setPos(coord.x, coord.y);
    });
    this.sInfoEl.on("mouseout", function () {
      _this.parent.findChildByName("gapminder-datanotes").hide();
    });
  },

  updateDoubtOpacity: function updateDoubtOpacity(opacity) {
    if (opacity == null) opacity = this.wScale(+this.time.getUTCFullYear().toString());
    if (this.someSelected) opacity = 1;
    this.dataWarningEl.style("opacity", opacity);
  },

  /*
   * UPDATE TIME:
   * Ideally should only update when time or data changes
   */
  updateTime: function updateTime() {
    var _this = this;
    this.time_1 = this.time == null ? this.model.time.value : this.time;
    this.time = this.model.time.value;
    this.duration = this.model.time.playing && this.time - this.time_1 > 0 ? this.model.time.delayAnimations : 0;
    this.year.setText(this.model.time.formatDate(this.time), this.duration);
  },

  /**
   * Executes everytime the container or vizabi is resized
   * Ideally,it contains only operations related to size
   */
  updateSize: function updateSize() {

    var _this = this;
    var margin, infoElHeight;

    var profiles = {
      small: {
        margin: { top: 10, right: 10, left: 10, bottom: 0 },
        infoElHeight: 16
      },
      medium: {
        margin: { top: 20, right: 20, left: 20, bottom: 30 },
        infoElHeight: 20
      },
      large: {
        margin: { top: 30, right: 30, left: 30, bottom: 35 },
        infoElHeight: 22
      }
    };

    var presentationProfileChanges = {
      medium: {
        infoElHeight: 26
      },
      large: {
        infoElHeight: 32
      }
    };

    this.activeProfile = this.getActiveProfile(profiles, presentationProfileChanges);
    margin = this.activeProfile.margin;
    infoElHeight = this.activeProfile.infoElHeight;

    //stage
    var height = this.height = parseInt(this.element.style("height"), 10) - margin.top - margin.bottom || 0;
    var width = this.width = parseInt(this.element.style("width"), 10) - margin.left - margin.right || 0;

    if (this.height <= 0 || this.width <= 0) return utils.warn("Bubble map updateSize() abort: vizabi container is too little or has display:none");

    var boundBox = this.boundBox;
    var viewBox = [boundBox[0][0] * this.defaultWidth, boundBox[0][1] * this.defaultHeight, Math.abs(boundBox[1][0] - boundBox[0][0]) * this.defaultWidth, Math.abs(boundBox[1][1] - boundBox[0][1]) * this.defaultHeight];

    this.graph.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    this.year.resize(this.width, this.height);

    this.mapSvg.attr('width', width).attr('height', height).attr('viewBox', viewBox.join(' ')).attr('preserveAspectRatio', 'xMidYMid').attr('x', margin.left).attr('y', margin.top).style("transform", "translate3d(" + margin.left + "px," + margin.top + "px,0)");

    this.yTitleEl.style("font-size", infoElHeight).attr("transform", "translate(0," + margin.top + ")");

    var yTitleBB = this.yTitleEl.select("text").node().getBBox();

    this.sTitleEl.attr("transform", "translate(" + 0 + "," + (margin.top + yTitleBB.height) + ")").classed("vzb-hidden", this.model.marker.size.use == "constant");

    var warnBB = this.dataWarningEl.select("text").node().getBBox();
    this.dataWarningEl.select("svg").attr("width", warnBB.height * 0.75).attr("height", warnBB.height * 0.75).attr("x", -warnBB.width - warnBB.height * 1.2).attr("y", -warnBB.height * 0.65);

    this.dataWarningEl.attr("transform", "translate(" + this.width + "," + (this.height - warnBB.height * 0.5) + ")").select("text");

    if (this.yInfoEl.select('svg').node()) {
      var titleBBox = this.yTitleEl.node().getBBox();
      var translate = d3.transform(this.yTitleEl.attr('transform')).translate;

      this.yInfoEl.select('svg').attr("width", infoElHeight).attr("height", infoElHeight);
      this.yInfoEl.attr('transform', 'translate(' + (titleBBox.x + translate[0] + titleBBox.width + infoElHeight * .4) + ',' + (translate[1] - infoElHeight * 0.8) + ')');
    }

    this.sInfoEl.classed("vzb-hidden", this.sTitleEl.classed("vzb-hidden"));

    if (!this.sInfoEl.classed("vzb-hidden") && this.sInfoEl.select('svg').node()) {
      var titleBBox = this.sTitleEl.node().getBBox();
      var translate = d3.transform(this.sTitleEl.attr('transform')).translate;

      this.sInfoEl.select('svg').attr("width", infoElHeight).attr("height", infoElHeight);
      this.sInfoEl.attr('transform', 'translate(' + (titleBBox.x + translate[0] + titleBBox.width + infoElHeight * .4) + ',' + (translate[1] - infoElHeight * 0.8) + ')');
    }
  },

  fitSizeOfTitles: function fitSizeOfTitles() {

    //reset font sizes first to make the measurement consistent
    var yTitleText = this.yTitleEl.select("text").style("font-size", null);
    var sTitleText = this.sTitleEl.select("text").style("font-size", null);

    var yTitleBB = yTitleText.node().getBBox();
    var sTitleBB = this.sTitleEl.classed('vzb-hidden') ? yTitleBB : sTitleText.node().getBBox();

    var font = Math.max(parseInt(yTitleText.style("font-size")), parseInt(sTitleText.style("font-size"))) * this.width / Math.max(yTitleBB.width, sTitleBB.width);

    if (Math.max(yTitleBB.width, sTitleBB.width) > this.width) {
      yTitleText.style("font-size", font + "px");
      sTitleText.style("font-size", font + "px");
    } else {
      // Else - reset the font size to default so it won't get stuck
      yTitleText.style("font-size", null);
      sTitleText.style("font-size", null);
    }
  },
  _interact: function _interact() {
    var _this = this;

    return {
      _mouseover: function _mouseover(d, i) {
        if (_this.model.time.dragging) return;

        _this.model.entities.highlightEntity(d);

        _this.hovered = d;
        //put the exact value in the size title
        _this.updateTitleNumbers();
        _this.fitSizeOfTitles();

        if (_this.model.entities.isSelected(d)) {
          // if selected, not show hover tooltip
          _this._setTooltip();
        } else {
          //position tooltip
          _this._setTooltip(d);
        }
      },
      _mouseout: function _mouseout(d, i) {
        if (_this.model.time.dragging) return;
        _this._setTooltip();
        _this.hovered = null;
        _this.updateTitleNumbers();
        _this.fitSizeOfTitles();
        _this.model.entities.clearHighlighted();
      },
      _click: function _click(d, i) {
        _this.model.entities.selectEntity(d);
      }
    };
  },

  // show size number on title when hovered on a bubble
  updateTitleNumbers: function updateTitleNumbers() {
    var _this = this;

    var mobile; // if is mobile device and only one bubble is selected, update the ytitle for the bubble
    if (_this.isMobile && _this.model.entities.select && _this.model.entities.select.length === 1) {
      mobile = _this.model.entities.select[0];
    }

    if (_this.hovered || mobile) {
      var hovered = _this.hovered || mobile;
      var formatterC = _this.model.marker.color.getTickFormatter();

      var unitC = _this.translator("unit/" + _this.model.marker.color.which);
      //suppress unit strings that found no translation (returns same thing as requested)
      if (unitC === "unit/" + _this.model.marker.color.which) unitC = "";

      var valueC = _this.values.color[_this._getKey(hovered)];
      _this.yTitleEl.select("text").text(this.strings.title.C + ": " + (valueC || valueC === 0 ? formatterC(valueC) + " " + unitC : _this.translator("hints/nodata")));

      if (this.model.marker.size.use !== "constant") {
        var formatterS = _this.model.marker.size.getTickFormatter();

        var unitS = _this.translator("unit/" + _this.model.marker.size.which);
        //suppress unit strings that found no translation (returns same thing as requested)
        if (unitS === "unit/" + _this.model.marker.size.which) unitS = "";

        var valueS = _this.values.size[_this._getKey(hovered)];
        _this.sTitleEl.select("text").text(this.strings.title.S + ": " + formatterS(valueS) + " " + unitS);
      }

      this.yInfoEl.classed("vzb-hidden", true);
      this.sInfoEl.classed("vzb-hidden", true);
    } else {
      this.yTitleEl.select("text").text(this.strings.title.C);
      this.sTitleEl.select("text").text(this.strings.title.S);

      this.yInfoEl.classed("vzb-hidden", false);
      this.sInfoEl.classed("vzb-hidden", false);
    }
  },

  _setTooltip: function _setTooltip(d) {
    var _this = this;
    if (d) {
      var tooltipText = this.values.label[this._getKey(d)] ? this.values.label[this._getKey(d)] : d.properties.MN_NAME;
      var offset = 10;
      var mouse = d3.mouse(this.graph.node()).map(function (d) {
        return parseInt(d);
      });
      var x = mouse[0];
      var y = mouse[1];
      var xPos,
          yPos,
          xSign = -1,
          ySign = -1,
          xOffset = 0,
          yOffset = 0;

      if (offset) {
        xOffset = offset * .71; // .71 - sin and cos for 315
        yOffset = offset * .71;
      }
      //position tooltip
      this.tooltip.classed("vzb-hidden", false)
      //.attr("style", "left:" + (mouse[0] + 50) + "px;top:" + (mouse[1] + 50) + "px")
      .selectAll("text").text(tooltipText);

      var contentBBox = this.tooltip.select('text')[0][0].getBBox();
      if (x - xOffset - contentBBox.width < 0) {
        xSign = 1;
        x += contentBBox.width + 5; // corrective to the block Radius and text padding
      } else {
        x -= 5; // corrective to the block Radius and text padding
      }
      if (y - yOffset - contentBBox.height < 0) {
        ySign = 1;
        y += contentBBox.height;
      } else {
        y -= 11; // corrective to the block Radius and text padding
      }
      if (offset) {
        xPos = x + xOffset * xSign;
        yPos = y + yOffset * ySign; // 5 and 11 - corrective to the block Radius and text padding
      } else {
        xPos = x + xOffset * xSign; // .71 - sin and cos for 315
        yPos = y + yOffset * ySign; // 5 and 11 - corrective to the block Radius and text padding
      }
      this.tooltip.attr("transform", "translate(" + (xPos ? xPos : mouse[0]) + "," + (yPos ? yPos : mouse[1]) + ")");

      this.tooltip.select('rect').attr("width", contentBBox.width + 8).attr("height", contentBBox.height * 1.2).attr("x", -contentBBox.width - 4).attr("y", -contentBBox.height * .85).attr("rx", contentBBox.height * .2).attr("ry", contentBBox.height * .2);
    } else {

      this.tooltip.classed("vzb-hidden", true);
    }
  },

  updateLandOpacity: function updateLandOpacity() {
    var _this = this;
    //if(!duration)duration = 0;

    var OPACITY_HIGHLT = 0.8;
    var OPACITY_HIGHLT_DIM = .3;
    var OPACITY_SELECT = this.model.entities.opacityRegular;
    var OPACITY_REGULAR = this.model.entities.opacityRegular;
    var OPACITY_SELECT_DIM = this.model.entities.opacitySelectDim;
    this.someHighlighted = this.model.entities.highlight.length > 0;
    this.someSelected = this.model.entities.select.length > 0;
    this.lands.style("opacity", function (d) {

      if (_this.someHighlighted) {
        //highlight or non-highlight
        if (_this.model.entities.isHighlighted(d)) return OPACITY_HIGHLT;
      }

      if (_this.someSelected) {
        //selected or non-selected
        return _this.model.entities.isSelected(d) ? OPACITY_SELECT : OPACITY_SELECT_DIM;
      }

      if (_this.someHighlighted) return OPACITY_HIGHLT_DIM;

      return OPACITY_REGULAR;
    });

    var someSelectedAndOpacityZero = _this.someSelected && _this.model.entities.opacitySelectDim < .01;

    // when pointer events need update...
    if (someSelectedAndOpacityZero != this.someSelectedAndOpacityZero_1) {
      this.lands.style("pointer-events", function (d) {
        return !someSelectedAndOpacityZero || _this.model.entities.isSelected(d) ? "visible" : "none";
      });
    }

    this.someSelectedAndOpacityZero_1 = _this.someSelected && _this.model.entities.opacitySelectDim < .01;
  },

  preload: function preload() {
    var _this = this;
    var shape_path = _globals2.default.ext_resources.shapePath ? _globals2.default.ext_resources.shapePath : _globals2.default.ext_resources.host + _globals2.default.ext_resources.preloadPath + "municipalities.json";

    return new Promise(function (resolve, reject) {
      d3.json(shape_path, function (error, json) {
        if (error) return console.warn("Failed loading json " + shape_path + ". " + error);
        _this.world = json;
        _this.geometries = json.objects.topo.geometries;
        _this.id_lookup = json.objects.id_lookup;
        resolve();
      });
    });
  }

});

exports.default = CartogramComponent;

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

var cof = __webpack_require__(28);
module.exports = function(it, msg){
  if(typeof it != 'number' && cof(it) != 'Number')throw TypeError(msg);
  return +it;
};

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

"use strict";
// 22.1.3.3 Array.prototype.copyWithin(target, start, end = this.length)
'use strict';
var toObject = __webpack_require__(13)
  , toIndex  = __webpack_require__(56)
  , toLength = __webpack_require__(12);

module.exports = [].copyWithin || function copyWithin(target/*= 0*/, start/*= 0, end = @length*/){
  var O     = toObject(this)
    , len   = toLength(O.length)
    , to    = toIndex(target, len)
    , from  = toIndex(start, len)
    , end   = arguments.length > 2 ? arguments[2] : undefined
    , count = Math.min((end === undefined ? len : toIndex(end, len)) - from, len - to)
    , inc   = 1;
  if(from < to && to < from + count){
    inc  = -1;
    from += count - 1;
    to   += count - 1;
  }
  while(count-- > 0){
    if(from in O)O[to] = O[from];
    else delete O[to];
    to   += inc;
    from += inc;
  } return O;
};

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

var forOf = __webpack_require__(61);

module.exports = function(iter, ITERATOR){
  var result = [];
  forOf(iter, false, result.push, result, ITERATOR);
  return result;
};


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

var aFunction = __webpack_require__(16)
  , toObject  = __webpack_require__(13)
  , IObject   = __webpack_require__(68)
  , toLength  = __webpack_require__(12);

module.exports = function(that, callbackfn, aLen, memo, isRight){
  aFunction(callbackfn);
  var O      = toObject(that)
    , self   = IObject(O)
    , length = toLength(O.length)
    , index  = isRight ? length - 1 : 0
    , i      = isRight ? -1 : 1;
  if(aLen < 2)for(;;){
    if(index in self){
      memo = self[index];
      index += i;
      break;
    }
    index += i;
    if(isRight ? index < 0 : length <= index){
      throw TypeError('Reduce of empty array with no initial value');
    }
  }
  for(;isRight ? index >= 0 : length > index; index += i)if(index in self){
    memo = callbackfn(memo, self[index], index, O);
  }
  return memo;
};

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

"use strict";
'use strict';
var aFunction  = __webpack_require__(16)
  , isObject   = __webpack_require__(6)
  , invoke     = __webpack_require__(76)
  , arraySlice = [].slice
  , factories  = {};

var construct = function(F, len, args){
  if(!(len in factories)){
    for(var n = [], i = 0; i < len; i++)n[i] = 'a[' + i + ']';
    factories[len] = Function('F,a', 'return new F(' + n.join(',') + ')');
  } return factories[len](F, args);
};

module.exports = Function.bind || function bind(that /*, args... */){
  var fn       = aFunction(this)
    , partArgs = arraySlice.call(arguments, 1);
  var bound = function(/* args... */){
    var args = partArgs.concat(arraySlice.call(arguments));
    return this instanceof bound ? construct(fn, args.length, args) : invoke(fn, args, that);
  };
  if(isObject(fn.prototype))bound.prototype = fn.prototype;
  return bound;
};

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

"use strict";
'use strict';
var dP          = __webpack_require__(9).f
  , create      = __webpack_require__(51)
  , redefineAll = __webpack_require__(54)
  , ctx         = __webpack_require__(35)
  , anInstance  = __webpack_require__(49)
  , defined     = __webpack_require__(29)
  , forOf       = __webpack_require__(61)
  , $iterDefine = __webpack_require__(99)
  , step        = __webpack_require__(162)
  , setSpecies  = __webpack_require__(55)
  , DESCRIPTORS = __webpack_require__(8)
  , fastKey     = __webpack_require__(41).fastKey
  , SIZE        = DESCRIPTORS ? '_s' : 'size';

var getEntry = function(that, key){
  // fast case
  var index = fastKey(key), entry;
  if(index !== 'F')return that._i[index];
  // frozen object case
  for(entry = that._f; entry; entry = entry.n){
    if(entry.k == key)return entry;
  }
};

module.exports = {
  getConstructor: function(wrapper, NAME, IS_MAP, ADDER){
    var C = wrapper(function(that, iterable){
      anInstance(that, C, NAME, '_i');
      that._i = create(null); // index
      that._f = undefined;    // first entry
      that._l = undefined;    // last entry
      that[SIZE] = 0;         // size
      if(iterable != undefined)forOf(iterable, IS_MAP, that[ADDER], that);
    });
    redefineAll(C.prototype, {
      // 23.1.3.1 Map.prototype.clear()
      // 23.2.3.2 Set.prototype.clear()
      clear: function clear(){
        for(var that = this, data = that._i, entry = that._f; entry; entry = entry.n){
          entry.r = true;
          if(entry.p)entry.p = entry.p.n = undefined;
          delete data[entry.i];
        }
        that._f = that._l = undefined;
        that[SIZE] = 0;
      },
      // 23.1.3.3 Map.prototype.delete(key)
      // 23.2.3.4 Set.prototype.delete(value)
      'delete': function(key){
        var that  = this
          , entry = getEntry(that, key);
        if(entry){
          var next = entry.n
            , prev = entry.p;
          delete that._i[entry.i];
          entry.r = true;
          if(prev)prev.n = next;
          if(next)next.p = prev;
          if(that._f == entry)that._f = next;
          if(that._l == entry)that._l = prev;
          that[SIZE]--;
        } return !!entry;
      },
      // 23.2.3.6 Set.prototype.forEach(callbackfn, thisArg = undefined)
      // 23.1.3.5 Map.prototype.forEach(callbackfn, thisArg = undefined)
      forEach: function forEach(callbackfn /*, that = undefined */){
        anInstance(this, C, 'forEach');
        var f = ctx(callbackfn, arguments.length > 1 ? arguments[1] : undefined, 3)
          , entry;
        while(entry = entry ? entry.n : this._f){
          f(entry.v, entry.k, this);
          // revert to the last existing entry
          while(entry && entry.r)entry = entry.p;
        }
      },
      // 23.1.3.7 Map.prototype.has(key)
      // 23.2.3.7 Set.prototype.has(value)
      has: function has(key){
        return !!getEntry(this, key);
      }
    });
    if(DESCRIPTORS)dP(C.prototype, 'size', {
      get: function(){
        return defined(this[SIZE]);
      }
    });
    return C;
  },
  def: function(that, key, value){
    var entry = getEntry(that, key)
      , prev, index;
    // change existing entry
    if(entry){
      entry.v = value;
    // create new entry
    } else {
      that._l = entry = {
        i: index = fastKey(key, true), // <- index
        k: key,                        // <- key
        v: value,                      // <- value
        p: prev = that._l,             // <- previous entry
        n: undefined,                  // <- next entry
        r: false                       // <- removed
      };
      if(!that._f)that._f = entry;
      if(prev)prev.n = entry;
      that[SIZE]++;
      // add to index
      if(index !== 'F')that._i[index] = entry;
    } return that;
  },
  getEntry: getEntry,
  setStrong: function(C, NAME, IS_MAP){
    // add .keys, .values, .entries, [@@iterator]
    // 23.1.3.4, 23.1.3.8, 23.1.3.11, 23.1.3.12, 23.2.3.5, 23.2.3.8, 23.2.3.10, 23.2.3.11
    $iterDefine(C, NAME, function(iterated, kind){
      this._t = iterated;  // target
      this._k = kind;      // kind
      this._l = undefined; // previous
    }, function(){
      var that  = this
        , kind  = that._k
        , entry = that._l;
      // revert to the last existing entry
      while(entry && entry.r)entry = entry.p;
      // get next entry
      if(!that._t || !(that._l = entry = entry ? entry.n : that._t._f)){
        // or finish the iteration
        that._t = undefined;
        return step(1);
      }
      // return step by kind
      if(kind == 'keys'  )return step(0, entry.k);
      if(kind == 'values')return step(0, entry.v);
      return step(0, [entry.k, entry.v]);
    }, IS_MAP ? 'entries' : 'values' , !IS_MAP, true);

    // add [@@species], 23.1.2.2, 23.2.2.2
    setSpecies(NAME);
  }
};

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

// https://github.com/DavidBruant/Map-Set.prototype.toJSON
var classof = __webpack_require__(67)
  , from    = __webpack_require__(153);
module.exports = function(NAME){
  return function toJSON(){
    if(classof(this) != NAME)throw TypeError(NAME + "#toJSON isn't generic");
    return from(this);
  };
};

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

"use strict";
'use strict';
var redefineAll       = __webpack_require__(54)
  , getWeak           = __webpack_require__(41).getWeak
  , anObject          = __webpack_require__(3)
  , isObject          = __webpack_require__(6)
  , anInstance        = __webpack_require__(49)
  , forOf             = __webpack_require__(61)
  , createArrayMethod = __webpack_require__(31)
  , $has              = __webpack_require__(15)
  , arrayFind         = createArrayMethod(5)
  , arrayFindIndex    = createArrayMethod(6)
  , id                = 0;

// fallback for uncaught frozen keys
var uncaughtFrozenStore = function(that){
  return that._l || (that._l = new UncaughtFrozenStore);
};
var UncaughtFrozenStore = function(){
  this.a = [];
};
var findUncaughtFrozen = function(store, key){
  return arrayFind(store.a, function(it){
    return it[0] === key;
  });
};
UncaughtFrozenStore.prototype = {
  get: function(key){
    var entry = findUncaughtFrozen(this, key);
    if(entry)return entry[1];
  },
  has: function(key){
    return !!findUncaughtFrozen(this, key);
  },
  set: function(key, value){
    var entry = findUncaughtFrozen(this, key);
    if(entry)entry[1] = value;
    else this.a.push([key, value]);
  },
  'delete': function(key){
    var index = arrayFindIndex(this.a, function(it){
      return it[0] === key;
    });
    if(~index)this.a.splice(index, 1);
    return !!~index;
  }
};

module.exports = {
  getConstructor: function(wrapper, NAME, IS_MAP, ADDER){
    var C = wrapper(function(that, iterable){
      anInstance(that, C, NAME, '_i');
      that._i = id++;      // collection id
      that._l = undefined; // leak store for uncaught frozen objects
      if(iterable != undefined)forOf(iterable, IS_MAP, that[ADDER], that);
    });
    redefineAll(C.prototype, {
      // 23.3.3.2 WeakMap.prototype.delete(key)
      // 23.4.3.3 WeakSet.prototype.delete(value)
      'delete': function(key){
        if(!isObject(key))return false;
        var data = getWeak(key);
        if(data === true)return uncaughtFrozenStore(this)['delete'](key);
        return data && $has(data, this._i) && delete data[this._i];
      },
      // 23.3.3.4 WeakMap.prototype.has(key)
      // 23.4.3.4 WeakSet.prototype.has(value)
      has: function has(key){
        if(!isObject(key))return false;
        var data = getWeak(key);
        if(data === true)return uncaughtFrozenStore(this).has(key);
        return data && $has(data, this._i);
      }
    });
    return C;
  },
  def: function(that, key, value){
    var data = getWeak(anObject(key), true);
    if(data === true)uncaughtFrozenStore(that).set(key, value);
    else data[that._i] = value;
    return that;
  },
  ufstore: uncaughtFrozenStore
};

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

module.exports = !__webpack_require__(8) && !__webpack_require__(5)(function(){
  return Object.defineProperty(__webpack_require__(91)('div'), 'a', {get: function(){ return 7; }}).a != 7;
});

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

// 20.1.2.3 Number.isInteger(number)
var isObject = __webpack_require__(6)
  , floor    = Math.floor;
module.exports = function isInteger(it){
  return !isObject(it) && isFinite(it) && floor(it) === it;
};

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

// call something on iterator step with safe closing on error
var anObject = __webpack_require__(3);
module.exports = function(iterator, fn, value, entries){
  try {
    return entries ? fn(anObject(value)[0], value[1]) : fn(value);
  // 7.4.6 IteratorClose(iterator, completion)
  } catch(e){
    var ret = iterator['return'];
    if(ret !== undefined)anObject(ret.call(iterator));
    throw e;
  }
};

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

module.exports = function(done, value){
  return {value: value, done: !!done};
};

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

// 20.2.2.20 Math.log1p(x)
module.exports = Math.log1p || function log1p(x){
  return (x = +x) > -1e-8 && x < 1e-8 ? x - x * x / 2 : Math.log(1 + x);
};

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

"use strict";
'use strict';
// 19.1.2.1 Object.assign(target, source, ...)
var getKeys  = __webpack_require__(53)
  , gOPS     = __webpack_require__(80)
  , pIE      = __webpack_require__(69)
  , toObject = __webpack_require__(13)
  , IObject  = __webpack_require__(68)
  , $assign  = Object.assign;

// should work with symbols and should have deterministic property order (V8 bug)
module.exports = !$assign || __webpack_require__(5)(function(){
  var A = {}
    , B = {}
    , S = Symbol()
    , K = 'abcdefghijklmnopqrst';
  A[S] = 7;
  K.split('').forEach(function(k){ B[k] = k; });
  return $assign({}, A)[S] != 7 || Object.keys($assign({}, B)).join('') != K;
}) ? function assign(target, source){ // eslint-disable-line no-unused-vars
  var T     = toObject(target)
    , aLen  = arguments.length
    , index = 1
    , getSymbols = gOPS.f
    , isEnum     = pIE.f;
  while(aLen > index){
    var S      = IObject(arguments[index++])
      , keys   = getSymbols ? getKeys(S).concat(getSymbols(S)) : getKeys(S)
      , length = keys.length
      , j      = 0
      , key;
    while(length > j)if(isEnum.call(S, key = keys[j++]))T[key] = S[key];
  } return T;
} : $assign;

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

var dP       = __webpack_require__(9)
  , anObject = __webpack_require__(3)
  , getKeys  = __webpack_require__(53);

module.exports = __webpack_require__(8) ? Object.defineProperties : function defineProperties(O, Properties){
  anObject(O);
  var keys   = getKeys(Properties)
    , length = keys.length
    , i = 0
    , P;
  while(length > i)dP.f(O, P = keys[i++], Properties[P]);
  return O;
};

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

// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window
var toIObject = __webpack_require__(20)
  , gOPN      = __webpack_require__(52).f
  , toString  = {}.toString;

var windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames
  ? Object.getOwnPropertyNames(window) : [];

var getWindowNames = function(it){
  try {
    return gOPN(it);
  } catch(e){
    return windowNames.slice();
  }
};

module.exports.f = function getOwnPropertyNames(it){
  return windowNames && toString.call(it) == '[object Window]' ? getWindowNames(it) : gOPN(toIObject(it));
};


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

var has          = __webpack_require__(15)
  , toIObject    = __webpack_require__(20)
  , arrayIndexOf = __webpack_require__(72)(false)
  , IE_PROTO     = __webpack_require__(104)('IE_PROTO');

module.exports = function(object, names){
  var O      = toIObject(object)
    , i      = 0
    , result = []
    , key;
  for(key in O)if(key != IE_PROTO)has(O, key) && result.push(key);
  // Don't enum bug & hidden keys
  while(names.length > i)if(has(O, key = names[i++])){
    ~arrayIndexOf(result, key) || result.push(key);
  }
  return result;
};

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

var getKeys   = __webpack_require__(53)
  , toIObject = __webpack_require__(20)
  , isEnum    = __webpack_require__(69).f;
module.exports = function(isEntries){
  return function(it){
    var O      = toIObject(it)
      , keys   = getKeys(O)
      , length = keys.length
      , i      = 0
      , result = []
      , key;
    while(length > i)if(isEnum.call(O, key = keys[i++])){
      result.push(isEntries ? [key, O[key]] : O[key]);
    } return result;
  };
};

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

// all object keys, includes non-enumerable and symbols
var gOPN     = __webpack_require__(52)
  , gOPS     = __webpack_require__(80)
  , anObject = __webpack_require__(3)
  , Reflect  = __webpack_require__(4).Reflect;
module.exports = Reflect && Reflect.ownKeys || function ownKeys(it){
  var keys       = gOPN.f(anObject(it))
    , getSymbols = gOPS.f;
  return getSymbols ? keys.concat(getSymbols(it)) : keys;
};

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

var $parseFloat = __webpack_require__(4).parseFloat
  , $trim       = __webpack_require__(64).trim;

module.exports = 1 / $parseFloat(__webpack_require__(109) + '-0') !== -Infinity ? function parseFloat(str){
  var string = $trim(String(str), 3)
    , result = $parseFloat(string);
  return result === 0 && string.charAt(0) == '-' ? -0 : result;
} : $parseFloat;

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

var $parseInt = __webpack_require__(4).parseInt
  , $trim     = __webpack_require__(64).trim
  , ws        = __webpack_require__(109)
  , hex       = /^[\-+]?0[xX]/;

module.exports = $parseInt(ws + '08') !== 8 || $parseInt(ws + '0x16') !== 22 ? function parseInt(str, radix){
  var string = $trim(String(str), 3);
  return $parseInt(string, (radix >>> 0) || (hex.test(string) ? 16 : 10));
} : $parseInt;

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

// 7.2.9 SameValue(x, y)
module.exports = Object.is || function is(x, y){
  return x === y ? x !== 0 || 1 / x === 1 / y : x != x && y != y;
};

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

// https://github.com/tc39/proposal-string-pad-start-end
var toLength = __webpack_require__(12)
  , repeat   = __webpack_require__(108)
  , defined  = __webpack_require__(29);

module.exports = function(that, maxLength, fillString, left){
  var S            = String(defined(that))
    , stringLength = S.length
    , fillStr      = fillString === undefined ? ' ' : String(fillString)
    , intMaxLength = toLength(maxLength);
  if(intMaxLength <= stringLength || fillStr == '')return S;
  var fillLen = intMaxLength - stringLength
    , stringFiller = repeat.call(fillStr, Math.ceil(fillLen / fillStr.length));
  if(stringFiller.length > fillLen)stringFiller = stringFiller.slice(0, fillLen);
  return left ? stringFiller + S : S + stringFiller;
};


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

exports.f = __webpack_require__(7);

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

"use strict";
'use strict';
var strong = __webpack_require__(156);

// 23.1 Map Objects
module.exports = __webpack_require__(73)('Map', function(get){
  return function Map(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); };
}, {
  // 23.1.3.6 Map.prototype.get(key)
  get: function get(key){
    var entry = strong.getEntry(this, key);
    return entry && entry.v;
  },
  // 23.1.3.9 Map.prototype.set(key, value)
  set: function set(key, value){
    return strong.def(this, key === 0 ? 0 : key, value);
  }
}, strong, true);

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

// 21.2.5.3 get RegExp.prototype.flags()
if(__webpack_require__(8) && /./g.flags != 'g')__webpack_require__(9).f(RegExp.prototype, 'flags', {
  configurable: true,
  get: __webpack_require__(75)
});

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

"use strict";
'use strict';
var strong = __webpack_require__(156);

// 23.2 Set Objects
module.exports = __webpack_require__(73)('Set', function(get){
  return function Set(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); };
}, {
  // 23.2.3.1 Set.prototype.add(value)
  add: function add(value){
    return strong.def(this, value = value === 0 ? 0 : value, value);
  }
}, strong);

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

"use strict";
'use strict';
var each         = __webpack_require__(31)(0)
  , redefine     = __webpack_require__(18)
  , meta         = __webpack_require__(41)
  , assign       = __webpack_require__(164)
  , weak         = __webpack_require__(158)
  , isObject     = __webpack_require__(6)
  , getWeak      = meta.getWeak
  , isExtensible = Object.isExtensible
  , uncaughtFrozenStore = weak.ufstore
  , tmp          = {}
  , InternalMap;

var wrapper = function(get){
  return function WeakMap(){
    return get(this, arguments.length > 0 ? arguments[0] : undefined);
  };
};

var methods = {
  // 23.3.3.3 WeakMap.prototype.get(key)
  get: function get(key){
    if(isObject(key)){
      var data = getWeak(key);
      if(data === true)return uncaughtFrozenStore(this).get(key);
      return data ? data[this._i] : undefined;
    }
  },
  // 23.3.3.5 WeakMap.prototype.set(key, value)
  set: function set(key, value){
    return weak.def(this, key, value);
  }
};

// 23.3 WeakMap Objects
var $WeakMap = module.exports = __webpack_require__(73)('WeakMap', wrapper, methods, weak, true, true);

// IE11 WeakMap frozen keys fix
if(new $WeakMap().set((Object.freeze || Object)(tmp), 7).get(tmp) != 7){
  InternalMap = weak.getConstructor(wrapper);
  assign(InternalMap.prototype, methods);
  meta.NEED = true;
  each(['delete', 'has', 'get', 'set'], function(key){
    var proto  = $WeakMap.prototype
      , method = proto[key];
    redefine(proto, key, function(a, b){
      // store frozen objects on internal weakmap shim
      if(isObject(a) && !isExtensible(a)){
        if(!this._f)this._f = new InternalMap;
        var result = this._f[key](a, b);
        return key == 'set' ? this : result;
      // store all the rest on native weakmap
      } return method.call(this, a, b);
    });
  });
}

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

var g;

// This works in non-strict mode
g = (function() { return this; })();

try {
	// This works if eval is allowed (see CSP)
	g = g || Function("return this")() || (1,eval)("this");
} catch(e) {
	// This works if the window reference is available
	if(typeof window === "object")
		g = window;
}

// g can still be undefined, but nothing to do about it...
// We return undefined, instead of nothing here, so it's
// easier to handle this case. if(!global) { ...}

module.exports = g;


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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _tool = __webpack_require__(14);

var _tool2 = _interopRequireDefault(_tool);

var _agepyramidComponent = __webpack_require__(149);

var _agepyramidComponent2 = _interopRequireDefault(_agepyramidComponent);

var _timeslider = __webpack_require__(24);

var _timeslider2 = _interopRequireDefault(_timeslider);

var _dialogs = __webpack_require__(23);

var _dialogs2 = _interopRequireDefault(_dialogs);

var _buttonlist = __webpack_require__(22);

var _buttonlist2 = _interopRequireDefault(_buttonlist);

var _treemenu = __webpack_require__(27);

var _treemenu2 = _interopRequireDefault(_treemenu);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

//BAR CHART TOOL
var AgePyramid = _tool2.default.extend('AgePyramid', {

  /**
   * Initializes the tool (Bar Chart Tool).
   * Executed once before any template is rendered.
   * @param {Object} placeholder Placeholder element for the tool
   * @param {Object} external_model Model as given by the external page
   */
  init: function init(placeholder, external_model) {

    this.name = "agepyramid";

    //specifying components
    this.components = [{
      component: _agepyramidComponent2.default,
      placeholder: '.vzb-tool-viz',
      model: ["state.time", "state.marker", "locale", "ui"] //pass models to component
    }, {
      component: _timeslider2.default,
      placeholder: '.vzb-tool-timeslider',
      model: ["state.time", "state.entities", "state.marker", "ui"]
    }, {
      component: _dialogs2.default,
      placeholder: '.vzb-tool-dialogs',
      model: ['state', 'ui', 'locale']
    }, {
      component: _buttonlist2.default,
      placeholder: '.vzb-tool-buttonlist',
      model: ['state', 'ui', 'locale']
    }, {
      component: _treemenu2.default,
      placeholder: '.vzb-tool-treemenu',
      model: ['state.marker', 'state.marker_tags', 'state.time', 'locale']
    }];

    //constructor is the same as any tool
    this._super(placeholder, external_model);
  },

  default_model: {
    state: {
      marker_tags: {}
    },
    ui: {
      chart: {
        stacked: true,
        inpercent: false,
        flipSides: true
      },
      presentation: false
    },
    locale: {}
  }

}); /*!
     * VIZABI AGEPYRAMID
     */

exports.default = AgePyramid;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _tool = __webpack_require__(14);

var _tool2 = _interopRequireDefault(_tool);

var _axislabelerComponent = __webpack_require__(216);

var _axislabelerComponent2 = _interopRequireDefault(_axislabelerComponent);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

var comp_template = 'axislabeler.html'; /*!
                                         * VIZABI BARCHART
                                         */

var listPointer = 0;
var listData = [[-123, 123], [1.00000, 10000.0], [4.00000, 123.000], [0.00060, 123.000], [123.000, 4.00000], [123.000, 0.00060], [-123.00, -4.0000], [-123.00, -0.0006], [-4.0000, -123.00], [-0.0006, -123.00], [-123.00, 1800.00], [1800.00, -123.00], [123.000, -18000.], [-18000., 123.000], [-0.0006, 1800.00], [1800.00, -0.0006], [0.00060, -1800.0], [-1800.0, 0.00060], [-12.000, -2.0000], [-80.000, 40.0000], [5.00000, 8.00000], [42.0000, 42.0000], [0.00000000005, 4554545484715], [-2611968678575, 4554545484715], [-0.0020, 0.00200], [-123, -0.1, 0.002, 1540], [-123, -0.001, 0.5, 1540], [123, 0.1, -0.002, -1540], [123, 0.001, -0.5, -1540]];

//AXIS LABELER TOOL
var AxisLabeler = _tool2.default.extend('AxisLabeler', {

  /**
   * Initializes the tool (Bar Chart Tool).
   * Executed once before any template is rendered.
   * @param {Object} placeholder Placeholder element for the tool
   * @param {Object} external_model Model as given by the external page
   */
  init: function init(placeholder, external_model) {

    this.name = "axislabeler";

    //specifying components
    this.components = [{
      component: _axislabelerComponent2.default,
      placeholder: '.vzb-tool-viz',
      model: ["state.scales", "state.show"] //pass models to component
    }];

    //constructor is the same as any tool
    this._super(placeholder, external_model);
  },

  default_model: {
    state: {
      scales: {
        domain: listData[listPointer],
        xScaleType: 'linear',
        yScaleType: 'genericLog'
      },
      show: {
        labelSize: "16px",
        labelMargin: { LR: "5px", TB: "5px" },
        toolMargin: { top: 30, right: 20, left: 40, bottom: 40 }
      }

    },
    data: { noConceptprops: true },
    locale: {},
    ui: {}
  }
});

exports.default = AxisLabeler;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _tool = __webpack_require__(14);

var _tool2 = _interopRequireDefault(_tool);

var _barchartComponent = __webpack_require__(217);

var _barchartComponent2 = _interopRequireDefault(_barchartComponent);

var _timeslider = __webpack_require__(24);

var _timeslider2 = _interopRequireDefault(_timeslider);

var _dialogs = __webpack_require__(23);

var _dialogs2 = _interopRequireDefault(_dialogs);

var _buttonlist = __webpack_require__(22);

var _buttonlist2 = _interopRequireDefault(_buttonlist);

var _treemenu = __webpack_require__(27);

var _treemenu2 = _interopRequireDefault(_treemenu);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

var comp_template = 'barchart.html';

//BAR CHART TOOL
/*!
 * VIZABI BARCHART
 */

var BarChart = _tool2.default.extend('BarChart', {

  /**
   * Initializes the tool (Bar Chart Tool).
   * Executed once before any template is rendered.
   * @param {Object} placeholder Placeholder element for the tool
   * @param {Object} external_model Model as given by the external page
   */
  init: function init(placeholder, external_model) {

    this.name = "barchart";

    //specifying components
    this.components = [{
      component: _barchartComponent2.default,
      placeholder: '.vzb-tool-viz',
      model: ["state.time", "state.entities", "state.marker", "locale"] //pass models to component
    }, {
      component: _timeslider2.default,
      placeholder: '.vzb-tool-timeslider',
      model: ["state.time", "state.entities", "state.marker", "ui"]
    }, {
      component: _dialogs2.default,
      placeholder: '.vzb-tool-dialogs',
      model: ['state', 'ui', 'locale']
    }, {
      component: _buttonlist2.default,
      placeholder: '.vzb-tool-buttonlist',
      model: ['state', 'ui', 'locale']
    }, {
      component: _treemenu2.default,
      placeholder: '.vzb-tool-treemenu',
      model: ['state.marker', 'state.marker_tags', 'state.time', 'locale']
    }];

    //constructor is the same as any tool
    this._super(placeholder, external_model);
  },

  default_model: {
    state: {
      time: {},
      entities: {},
      marker: {
        label: {},
        axis_y: { allow: { scales: ["linear", "log"] } },
        axis_x: { allow: { scales: ["ordinal", "nominal"] } },
        color: {}
      }
    },
    locale: {},
    ui: {
      presentation: false,
      chart: {}
    }
  }
});

exports.default = BarChart;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _tool = __webpack_require__(14);

var _tool2 = _interopRequireDefault(_tool);

var _barrankchartComponent = __webpack_require__(218);

var _barrankchartComponent2 = _interopRequireDefault(_barrankchartComponent);

var _timeslider = __webpack_require__(24);

var _timeslider2 = _interopRequireDefault(_timeslider);

var _dialogs = __webpack_require__(23);

var _dialogs2 = _interopRequireDefault(_dialogs);

var _buttonlist = __webpack_require__(22);

var _buttonlist2 = _interopRequireDefault(_buttonlist);

var _treemenu = __webpack_require__(27);

var _treemenu2 = _interopRequireDefault(_treemenu);

var _datanotes = __webpack_require__(38);

var _datanotes2 = _interopRequireDefault(_datanotes);

var _datawarning = __webpack_require__(39);

var _datawarning2 = _interopRequireDefault(_datawarning);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

var BarRankChart = _tool2.default.extend('BarRankChart', {

  //Run when the tool is created
  init: function init(placeholder, external_model) {

    this.name = "barrankchart";

    this.components = [{
      component: _barrankchartComponent2.default,
      placeholder: '.vzb-tool-viz',
      model: ["state.time", "state.entities", "state.marker", "locale", "ui"]
    }, {
      component: _timeslider2.default,
      placeholder: '.vzb-tool-timeslider',
      model: ["state.time", "state.entities", "state.marker", "ui"]
    }, {
      component: _dialogs2.default,
      placeholder: '.vzb-tool-dialogs',
      model: ['state', 'ui', 'locale']
    }, {
      component: _buttonlist2.default,
      placeholder: '.vzb-tool-buttonlist',
      model: ['state', 'ui', 'locale']
    }, {
      component: _treemenu2.default,
      placeholder: '.vzb-tool-treemenu',
      model: ['state.marker', 'state.marker_tags', 'state.time', 'locale']
    }, {
      component: _datanotes2.default,
      placeholder: '.vzb-tool-datanotes',
      model: ['state.marker', 'locale']
    }, {
      component: _datawarning2.default,
      placeholder: '.vzb-tool-datawarning',
      model: ['locale']
    }];

    //constructor is the same as any tool
    this._super(placeholder, external_model);
  },

  /**
   * Determines the default model of this tool
   */
  default_model: {
    state: {
      entities: {
        dim: "id"
      },
      time: {},
      marker: {
        axis_x: { allow: { scales: ["linear", "log"] } },
        axis_y: { allow: { scales: ["ordinal", "nominal"] } },
        color: {}
      }
    },
    locale: {},
    ui: {
      chart: {},
      datawarning: {
        doubtDomain: [],
        doubtRange: []
      },
      presentation: false
    }
  }
});

exports.default = BarRankChart;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _tool = __webpack_require__(14);

var _tool2 = _interopRequireDefault(_tool);

var _bubblechartComponent = __webpack_require__(219);

var _bubblechartComponent2 = _interopRequireDefault(_bubblechartComponent);

var _timeslider = __webpack_require__(24);

var _timeslider2 = _interopRequireDefault(_timeslider);

var _dialogs = __webpack_require__(23);

var _dialogs2 = _interopRequireDefault(_dialogs);

var _buttonlist = __webpack_require__(22);

var _buttonlist2 = _interopRequireDefault(_buttonlist);

var _treemenu = __webpack_require__(27);

var _treemenu2 = _interopRequireDefault(_treemenu);

var _datawarning = __webpack_require__(39);

var _datawarning2 = _interopRequireDefault(_datawarning);

var _datanotes = __webpack_require__(38);

var _datanotes2 = _interopRequireDefault(_datanotes);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

var BubbleChart = _tool2.default.extend('BubbleChart', {

  /**
   * Initializes the tool (Bubble Chart Tool).
   * Executed once before any template is rendered.
   * @param {Object} placeholder Placeholder element for the tool
   * @param {Object} external_model Model as given by the external page
   */
  init: function init(placeholder, external_model) {

    this.name = "bubblechart";

    //specifying components
    this.components = [{
      component: _bubblechartComponent2.default,
      placeholder: '.vzb-tool-viz',
      model: ["state.time", "state.entities", "state.marker", "locale", "ui"] //pass models to component
    }, {
      component: _timeslider2.default,
      placeholder: '.vzb-tool-timeslider',
      model: ["state.time", "state.entities", "state.marker", "ui"]
    }, {
      component: _dialogs2.default,
      placeholder: '.vzb-tool-dialogs',
      model: ['state', 'ui', 'locale']
    }, {
      component: _buttonlist2.default,
      placeholder: '.vzb-tool-buttonlist',
      model: ['state', 'ui', 'locale']
    }, {
      component: _treemenu2.default,
      placeholder: '.vzb-tool-treemenu',
      model: ['state.marker', 'state.marker_tags', 'state.time', 'locale']
    }, {
      component: _datawarning2.default,
      placeholder: '.vzb-tool-datawarning',
      model: ['locale']
    }, {
      component: _datanotes2.default,
      placeholder: '.vzb-tool-datanotes',
      model: ['state.marker', 'locale']
    }];

    this._super(placeholder, external_model);
  },

  validate: function validate(model) {
    model = this.model || model;

    this._super(model);

    if (model.ui.chart.lockNonSelected) {
      var time = model.state.time.parse("" + model.ui.chart.lockNonSelected);
      if (time < model.state.time.start) model.ui.chart.lockNonSelected = model.state.time.formatDate(model.state.time.start);
      if (time > model.state.time.end) model.ui.chart.lockNonSelected = model.state.time.formatDate(model.state.time.end);
    }
  },

  /**
   * Determines the default model of this tool
   */
  default_model: {
    state: {
      time: {
        autogenerate: {
          data: "data",
          conceptIndex: 0,
          conceptType: "time"
        }
      },
      entities: {
        autogenerate: {
          data: "data",
          conceptIndex: 0
        }
      },
      entities_colorlegend: {
        autogenerate: {
          data: "data",
          conceptIndex: 0
        }
      },
      entities_tags: {},
      marker_tags: {
        space: ["entities_tags"],
        label: {},
        hook_parent: {}
      },
      marker: {
        space: ["entities", "time"],
        axis_x: {
          use: "indicator",
          autogenerate: {
            conceptIndex: 1,
            conceptType: "measure"
          }
        },
        axis_y: {
          use: "indicator",
          autogenerate: {
            conceptIndex: 0,
            conceptType: "measure"
          }
        },
        label: {
          use: "property",
          autogenerate: {
            conceptIndex: 0
          }
        },
        size: {},
        color: {
          syncModels: ["marker_colorlegend"]
        },
        size_label: {
          /*use size model defaults - will be constant*/
          _important: false,
          extent: [0, 0.33]
        }
      },
      "marker_colorlegend": {
        "space": ["entities_colorlegend"],
        "label": {
          "use": "property",
          "which": "name"
        },
        "hook_rank": {
          "use": "property",
          "which": "rank"
        },
        "hook_geoshape": {
          "use": "property",
          "which": "shape_lores_svg"
        }
      }
    },
    locale: {},
    ui: {
      chart: {
        whenHovering: {
          showProjectionLineX: true,
          showProjectionLineY: true,
          higlightValueX: true,
          higlightValueY: true
        },
        labels: {
          dragging: true,
          removeLabelBox: false
        },
        trails: true,
        lockNonSelected: 0
      },
      datawarning: {
        doubtDomain: [],
        doubtRange: []
      },
      presentation: false,
      adaptMinMaxZoom: false,
      cursorMode: 'arrow',
      zoomOnScrolling: false,
      buttons: ['colors', 'find', 'size', 'trails', 'lock', 'moreoptions', 'fullscreen', 'presentation'],
      dialogs: {
        popup: ['colors', 'find', 'size', 'zoom', 'moreoptions'],
        sidebar: ['colors', 'find', 'size', 'zoom'],
        moreoptions: ['opacity', 'speed', 'axes', 'size', 'colors', 'label', 'zoom', 'presentation', 'about']
      }
    }
  }
});

exports.default = BubbleChart;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _tool = __webpack_require__(14);

var _tool2 = _interopRequireDefault(_tool);

var _bubblemapComponent = __webpack_require__(222);

var _bubblemapComponent2 = _interopRequireDefault(_bubblemapComponent);

var _timeslider = __webpack_require__(24);

var _timeslider2 = _interopRequireDefault(_timeslider);

var _dialogs = __webpack_require__(23);

var _dialogs2 = _interopRequireDefault(_dialogs);

var _buttonlist = __webpack_require__(22);

var _buttonlist2 = _interopRequireDefault(_buttonlist);

var _treemenu = __webpack_require__(27);

var _treemenu2 = _interopRequireDefault(_treemenu);

var _datawarning = __webpack_require__(39);

var _datawarning2 = _interopRequireDefault(_datawarning);

var _datanotes = __webpack_require__(38);

var _datanotes2 = _interopRequireDefault(_datanotes);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

//BAR CHART TOOL
var BubbleMap = _tool2.default.extend('BubbleMap', {

  /**
   * Initializes the tool (Bar Chart Tool).
   * Executed once before any template is rendered.
   * @param {Object} placeholder Placeholder element for the tool
   * @param {Object} external_model Model as given by the external page
   */
  init: function init(placeholder, external_model) {

    this.name = "bubblemap";

    //specifying components
    this.components = [{
      component: _bubblemapComponent2.default,
      placeholder: '.vzb-tool-viz',
      model: ["state.time", "state.entities", "state.marker", "locale", "ui"] //pass models to component
    }, {
      component: _timeslider2.default,
      placeholder: '.vzb-tool-timeslider',
      model: ["state.time", "state.entities", "state.marker", "ui"]
    }, {
      component: _dialogs2.default,
      placeholder: '.vzb-tool-dialogs',
      model: ['state', 'ui', 'locale']
    }, {
      component: _buttonlist2.default,
      placeholder: '.vzb-tool-buttonlist',
      model: ['state', 'ui', 'locale']
    }, {
      component: _treemenu2.default,
      placeholder: '.vzb-tool-treemenu',
      model: ['state.marker', 'state.marker_tags', 'state.time', 'locale']
    }, {
      component: _datawarning2.default,
      placeholder: '.vzb-tool-datawarning',
      model: ['locale']
    }, {
      component: _datanotes2.default,
      placeholder: '.vzb-tool-datanotes',
      model: ['state.marker', 'locale']
    }];

    //constructor is the same as any tool
    this._super(placeholder, external_model);
  },

  default_model: {
    state: {
      time: {
        "delay": 100,
        "delayThresholdX2": 50,
        "delayThresholdX4": 25
      },
      entities: {
        "opacitySelectDim": 0.3,
        "opacityRegular": 1
      }
    },
    locale: {},
    ui: {
      map: {
        path: null,
        preserveAspectRatio: true,
        scale: 0.95,
        offset: {
          top: 0,
          right: 0,
          bottom: 0,
          left: 0
        },
        projection: 'robinson',
        topology_object: {
          surface: 'land',
          boundaries: 'countries'
        }
      },
      chart: {
        labels: {
          dragging: true
        }
      },
      datawarning: {
        doubtDomain: [],
        doubtRange: []
      },
      presentation: false
    }
  }
}); /*!
     * VIZABI BUBBLEMAP
     */

exports.default = BubbleMap;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _tool = __webpack_require__(14);

var _tool2 = _interopRequireDefault(_tool);

var _cartogramComponent = __webpack_require__(150);

var _cartogramComponent2 = _interopRequireDefault(_cartogramComponent);

var _timeslider = __webpack_require__(24);

var _timeslider2 = _interopRequireDefault(_timeslider);

var _dialogs = __webpack_require__(23);

var _dialogs2 = _interopRequireDefault(_dialogs);

var _buttonlist = __webpack_require__(22);

var _buttonlist2 = _interopRequireDefault(_buttonlist);

var _treemenu = __webpack_require__(27);

var _treemenu2 = _interopRequireDefault(_treemenu);

var _datawarning = __webpack_require__(39);

var _datawarning2 = _interopRequireDefault(_datawarning);

var _datanotes = __webpack_require__(38);

var _datanotes2 = _interopRequireDefault(_datanotes);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

//CARTOGRAM TOOL
var Cartogram = _tool2.default.extend('Cartogram', {

  /**
   * Initialized the tool
   * @param {Object} placeholder Placeholder element for the tool
   * @param {Object} external_model Model as given by the external page
   */
  init: function init(placeholder, external_model) {

    this.name = 'cartogram';

    //specifying components
    this.components = [{
      component: _cartogramComponent2.default,
      placeholder: '.vzb-tool-viz',
      model: ["state.time", "state.entities", "state.marker", "locale", "ui"] //pass models to component
    }, {
      component: _timeslider2.default,
      placeholder: '.vzb-tool-timeslider',
      model: ["state.time", "state.entities", "state.marker", "ui"]
    }, {
      component: _dialogs2.default,
      placeholder: '.vzb-tool-dialogs',
      model: ['state', 'ui', 'locale']
    }, {
      component: _buttonlist2.default,
      placeholder: '.vzb-tool-buttonlist',
      model: ['state', 'ui', 'locale']
    }, {
      component: _treemenu2.default,
      placeholder: '.vzb-tool-treemenu',
      model: ['state.marker', 'locale']
    }, {
      component: _datawarning2.default,
      placeholder: '.vzb-tool-datawarning',
      model: ['locale']
    }, {
      component: _datanotes2.default,
      placeholder: '.vzb-tool-datanotes',
      model: ['state.marker', 'locale']
    }];

    //constructor is the same as any tool
    this._super(placeholder, external_model);
  },

  default_model: {
    state: {},
    ui: {
      chart: {
        labels: {
          dragging: true
        },
        lockNonSelected: 0,
        lockActive: 0,
        sizeSelectorActive: 0
      },
      datawarning: {
        doubtDomain: [],
        doubtRange: []
      },
      presentation: false
    }
  }
}); /*!
     * VIZABI LINECHART
     */

exports.default = Cartogram;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _tool = __webpack_require__(14);

var _tool2 = _interopRequireDefault(_tool);

var _donutchartComponent = __webpack_require__(223);

var _donutchartComponent2 = _interopRequireDefault(_donutchartComponent);

var _timeslider = __webpack_require__(24);

var _timeslider2 = _interopRequireDefault(_timeslider);

var _dialogs = __webpack_require__(23);

var _dialogs2 = _interopRequireDefault(_dialogs);

var _buttonlist = __webpack_require__(22);

var _buttonlist2 = _interopRequireDefault(_buttonlist);

var _treemenu = __webpack_require__(27);

var _treemenu2 = _interopRequireDefault(_treemenu);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

var comp_template = 'barchart.html';

//BAR CHART TOOL
//extend the base Tool class and register it in Vizabi tools under a name 'DunutChart'
/*!
 * VIZABI BARCHART
 */

var DonutChart = _tool2.default.extend('DonutChart', {

  //Run when the tool is created
  init: function init(placeholder, external_model) {

    //Let's give it a name
    this.name = "donutchart";

    //Now we can specify components that should be included in the tool:
    this.components = [{
      //choose which component to use:
      //at this point you can check Vizabi.Component.getCollection() to see which components are available
      component: 'donut',
      //these placeholdes are defined by the Tool prototype class
      placeholder: '.vzb-tool-viz',
      //component should have access to the following models:
      model: ["state.time", "state.marker"]
    }, {
      component: 'timeslider',
      placeholder: '.vzb-tool-timeslider',
      model: ["state.time", "state.entities", "state.marker", "ui"]
    }];

    this._super(placeholder, external_model);
  },

  //provide the default options
  default_model: {
    state: {},
    ui: {
      presentation: false
    },
    locale: {}
  }
});

exports.default = DonutChart;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _tool = __webpack_require__(14);

var _tool2 = _interopRequireDefault(_tool);

var _cartogramComponent = __webpack_require__(150);

var _cartogramComponent2 = _interopRequireDefault(_cartogramComponent);

var _linechartComponent = __webpack_require__(88);

var _linechartComponent2 = _interopRequireDefault(_linechartComponent);

var _timeslider = __webpack_require__(24);

var _timeslider2 = _interopRequireDefault(_timeslider);

var _dialogs = __webpack_require__(23);

var _dialogs2 = _interopRequireDefault(_dialogs);

var _buttonlist = __webpack_require__(22);

var _buttonlist2 = _interopRequireDefault(_buttonlist);

var _treemenu = __webpack_require__(27);

var _treemenu2 = _interopRequireDefault(_treemenu);

var _datawarning = __webpack_require__(39);

var _datawarning2 = _interopRequireDefault(_datawarning);

var _datanotes = __webpack_require__(38);

var _datanotes2 = _interopRequireDefault(_datanotes);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

//BAR CHART TOOL
/*!
 * VIZABI AGEPYRAMID
 */

var JOINTCartogramLine = _tool2.default.extend('JOINTCartogramLine', {

  /**
   * Initializes the tool (Bar Chart Tool).
   * Executed once before any template is rendered.
   * @param {Object} placeholder Placeholder element for the tool
   * @param {Object} external_model Model as given by the external page
   */
  init: function init(placeholder, external_model) {

    this.name = "joint_cartogramline";

    this.template = '<div class="vzb-tool vzb-tool-' + this.name + '">' + '<div class="vzb-tool-stage vzb-tool-stage-left" style="position:absolute; left: 0; width: 65%; height: 100%;">' + '<div class="vzb-tool-viz vzb-tool-viz-cartogram"></div>' + '</div>' + '<div class="vzb-tool-stage vzb-tool-stage-right" style="position:absolute; right: 0; top: 0; width: 40%; height: 100%;">' + '<div class="vzb-tool-viz vzb-tool-viz-line"></div>' + '<div class="vzb-tool-timeslider"></div>' + '</div>' + '<div class="vzb-tool-sidebar">' + '<div class="vzb-tool-dialogs"></div>' + '<div class="vzb-tool-buttonlist"></div>' + '</div>' + '<div class="vzb-tool-datanotes vzb-hidden"></div>' + '<div class="vzb-tool-treemenu vzb-hidden"></div>' + '<div class="vzb-tool-datawarning vzb-hidden"></div>' + '<div class="vzb-tool-labels vzb-hidden"></div>' + '</div>';

    //specifying components
    this.components = [{
      component: _cartogramComponent2.default,
      placeholder: '.vzb-tool-viz-cartogram',
      model: ["state.time", "state.entities", "state.marker", "locale", "ui"] //pass models to component
    }, {
      component: _linechartComponent2.default,
      placeholder: '.vzb-tool-viz-line',
      model: ["state.time", "state.entities_line", "state.marker_line", "locale"]
    }, {
      component: _timeslider2.default,
      placeholder: '.vzb-tool-timeslider',
      model: ["state.time", "state.entities", "state.marker", "ui"]
    }, {
      component: _dialogs2.default,
      placeholder: '.vzb-tool-dialogs',
      model: ['state', 'ui', 'locale']
    }, {
      component: _buttonlist2.default,
      placeholder: '.vzb-tool-buttonlist',
      model: ['state', 'ui', 'locale']
    }, {
      component: _treemenu2.default,
      placeholder: '.vzb-tool-treemenu',
      model: ['state.marker', 'locale']
    }, {
      component: _datawarning2.default,
      placeholder: '.vzb-tool-datawarning',
      model: ['locale']
    }, {
      component: _datanotes2.default,
      placeholder: '.vzb-tool-datanotes',
      model: ['state.marker', 'locale']
    }];

    //constructor is the same as any tool
    this._super(placeholder, external_model);
  },

  readyOnce: function readyOnce() {
    this.element = d3.select(this.element);
    //this.element.select(".vzb-ct-axis-y-title").classed("vzb-hidden", true);
    //this.element.select(".vzb-ct-axis-y-info").style("visibility", "hidden");
    this.element.select(".vzb-lc-axis-y-title").classed("vzb-hidden", true);
    this.element.select(".vzb-lc-axis-x-title").classed("vzb-hidden", true);
    this.element.select(".vzb-lc-axis-y-info").classed("vzb-hidden", true);
    this.element.select(".vzb-data-warning").classed("vzb-hidden", true);
  },

  default_model: {
    ui: {
      chart: {
        labels: {
          min_number_of_entities_when_values_hide: 0 //values hide when showing 2 entities or more
        },
        hideXAxisValue: true,
        whenHovering: {
          hideVerticalNow: true,
          showProjectionLineX: true,
          showProjectionLineY: true,
          higlightValueX: true,
          higlightValueY: true,
          showTooltip: false
        },
        stacked: true,
        inpercent: false
      },
      presentation: true
    }

  },

  datawarning_content: {
    title: "",
    body: "Comparing the size of economy across countries and time is not trivial. The methods vary and the prices change. Gapminder has adjusted the picture for many such differences, but still we recommend you take these numbers with a large grain of salt.<br/><br/> Countries on a lower income levels have lower data quality in general, as less resources are available for compiling statistics. Historic estimates of GDP before 1950 are generally also more rough. <br/><br/> Data for child mortality is more reliable than GDP per capita, as the unit of comparison, dead children, is universally comparable across time and place. This is one of the reasons this indicator has become so useful to measure social progress. But the historic estimates of child mortality are still suffering from large uncertainties.<br/><br/> Learn more about the datasets and methods in this <a href='http://www.gapminder.org/news/data-sources-dont-panic-end-poverty' target='_blank'>blog post</a>",
    doubtDomain: [1800, 1950, 2015],
    doubtRange: [1.0, .3, .2]
  }

});

exports.default = JOINTCartogramLine;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _tool = __webpack_require__(14);

var _tool2 = _interopRequireDefault(_tool);

var _agepyramidComponent = __webpack_require__(149);

var _agepyramidComponent2 = _interopRequireDefault(_agepyramidComponent);

var _linechartComponent = __webpack_require__(88);

var _linechartComponent2 = _interopRequireDefault(_linechartComponent);

var _timeslider = __webpack_require__(24);

var _timeslider2 = _interopRequireDefault(_timeslider);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

//BAR CHART TOOL
var JOINTPyramidLine = _tool2.default.extend('JOINTPyramidLine', {

  /**
   * Initializes the tool (Bar Chart Tool).
   * Executed once before any template is rendered.
   * @param {Object} placeholder Placeholder element for the tool
   * @param {Object} external_model Model as given by the external page
   */
  init: function init(placeholder, external_model) {

    this.name = "joint_pyramidline";

    this.template = '<div class="vzb-tool vzb-tool-' + this.name + '">' + '<div class="vzb-tool-stage vzb-tool-stage-left" style="position:absolute; left: 0; width: 50%; height: 100%;">' + '<div class="vzb-tool-viz vzb-tool-viz-pyramid"></div>' + '</div>' + '<div class="vzb-tool-stage vzb-tool-stage-right" style="position:absolute; right: 0; width: 50%; height: 100%;">' + '<div class="vzb-tool-viz vzb-tool-viz-line"></div>' + '<div class="vzb-tool-timeslider"></div>' + '</div>' + '<div class="vzb-tool-sidebar">' + '<div class="vzb-tool-dialogs"></div>' + '<div class="vzb-tool-buttonlist"></div>' + '</div>' + '<div class="vzb-tool-datanotes vzb-hidden"></div>' + '<div class="vzb-tool-treemenu vzb-hidden"></div>' + '<div class="vzb-tool-datawarning vzb-hidden"></div>' + '<div class="vzb-tool-labels vzb-hidden"></div>' + '</div>';

    //specifying components
    this.components = [{
      component: _agepyramidComponent2.default,
      placeholder: '.vzb-tool-viz-pyramid',
      model: ["state.time", "state.entities", "state.entities_side", "state.entities_stack", "state.entities_age", "state.marker_pyramid", "state.marker_side", "locale", "ui"] //pass models to component
    }, {
      component: _linechartComponent2.default,
      placeholder: '.vzb-tool-viz-line',
      model: ["state.time", "state.entities", "state.marker_line", "locale"]
    }, {
      component: _timeslider2.default,
      placeholder: '.vzb-tool-timeslider',
      model: ["state.time", "state.entities", "state.marker_pyramid", "ui"]
    }];

    //constructor is the same as any tool
    this._super(placeholder, external_model);
  },

  default_model: {
    ui: {
      chart: {
        labels: {
          min_number_of_entities_when_values_hide: 2 //values hide when showing 2 entities or more
        },
        whenHovering: {
          hideVerticalNow: false,
          showProjectionLineX: true,
          showProjectionLineY: true,
          higlightValueX: true,
          higlightValueY: true,
          showTooltip: false
        },
        stacked: true,
        inpercent: false
      },
      presentation: false
    }
  }

}); /*!
     * VIZABI AGEPYRAMID
     */

exports.default = JOINTPyramidLine;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _tool = __webpack_require__(14);

var _tool2 = _interopRequireDefault(_tool);

var _linechartComponent = __webpack_require__(88);

var _linechartComponent2 = _interopRequireDefault(_linechartComponent);

var _timeslider = __webpack_require__(24);

var _timeslider2 = _interopRequireDefault(_timeslider);

var _dialogs = __webpack_require__(23);

var _dialogs2 = _interopRequireDefault(_dialogs);

var _buttonlist = __webpack_require__(22);

var _buttonlist2 = _interopRequireDefault(_buttonlist);

var _treemenu = __webpack_require__(27);

var _treemenu2 = _interopRequireDefault(_treemenu);

var _datawarning = __webpack_require__(39);

var _datawarning2 = _interopRequireDefault(_datawarning);

var _datanotes = __webpack_require__(38);

var _datanotes2 = _interopRequireDefault(_datanotes);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

//LINE CHART TOOL
var LineChart = _tool2.default.extend('LineChart', {
  /**
   * Initialized the tool
   * @param {Object} placeholder Placeholder element for the tool
   * @param {Object} external_model Model as given by the external page
   */
  init: function init(placeholder, external_model) {

    this.name = 'linechart';

    this.components = [{
      component: _linechartComponent2.default,
      placeholder: '.vzb-tool-viz',
      model: ["state.time", "state.entities", "state.marker", "locale", "ui"] //pass models to component
    }, {
      component: _timeslider2.default,
      placeholder: '.vzb-tool-timeslider',
      model: ["state.time", "state.entities", "state.marker", "ui"],
      ui: { show_value_when_drag_play: false, axis_aligned: true }
    }, {
      component: _dialogs2.default,
      placeholder: '.vzb-tool-dialogs',
      model: ['state', 'ui', 'locale']
    }, {
      component: _buttonlist2.default,
      placeholder: '.vzb-tool-buttonlist',
      model: ['state', 'ui', 'locale']
    }, {
      component: _treemenu2.default,
      placeholder: '.vzb-tool-treemenu',
      model: ['state.marker', 'state.marker_tags', 'state.time', 'locale']
    }, {
      component: _datawarning2.default,
      placeholder: '.vzb-tool-datawarning',
      model: ['locale']
    }, {
      component: _datanotes2.default,
      placeholder: '.vzb-tool-datanotes',
      model: ['state.marker', 'locale']
    }];

    this._super(placeholder, external_model);
  },

  default_model: {
    state: {
      time: {},
      marker: {
        axis_x: { allow: { scales: ["time"] } },
        axis_y: { allow: { scales: ["linear", "log"] } }
      }
    },
    locale: {},
    "ui": {
      "chart": {
        "labels": {
          "min_number_of_entities_when_values_hide": 2 //values hide when showing 2 entities or more
        },
        "whenHovering": {
          "hideVerticalNow": false,
          "showProjectionLineX": true,
          "showProjectionLineY": true,
          "higlightValueX": true,
          "higlightValueY": true,
          "showTooltip": false
        }
      },
      datawarning: {
        doubtDomain: [],
        doubtRange: []
      },
      "presentation": false
    }
  }

}); /*!
     * VIZABI LINECHART
     */

exports.default = LineChart;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _tool = __webpack_require__(14);

var _tool2 = _interopRequireDefault(_tool);

var _mountainchartComponent = __webpack_require__(224);

var _mountainchartComponent2 = _interopRequireDefault(_mountainchartComponent);

var _timeslider = __webpack_require__(24);

var _timeslider2 = _interopRequireDefault(_timeslider);

var _dialogs = __webpack_require__(23);

var _dialogs2 = _interopRequireDefault(_dialogs);

var _buttonlist = __webpack_require__(22);

var _buttonlist2 = _interopRequireDefault(_buttonlist);

var _treemenu = __webpack_require__(27);

var _treemenu2 = _interopRequireDefault(_treemenu);

var _datawarning = __webpack_require__(39);

var _datawarning2 = _interopRequireDefault(_datawarning);

var _datanotes = __webpack_require__(38);

var _datanotes2 = _interopRequireDefault(_datanotes);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

//MOUNTAIN CHART TOOL
var MountainChart = _tool2.default.extend('MountainChart', {

  /**
   * Initializes the tool (MountainChart Tool).
   * Executed once before any template is rendered.
   * @param {Object} placeholder Placeholder element for the tool
   * @param {Object} external_model Model as given by the external page
   */
  init: function init(placeholder, external_model) {

    this.name = "mountainchart";

    //specifying components
    this.components = [{
      component: _mountainchartComponent2.default,
      placeholder: '.vzb-tool-viz',
      model: ["state.time", "state.entities", "state.marker", "locale", "ui"] //pass models to component
    }, {
      component: _timeslider2.default,
      placeholder: '.vzb-tool-timeslider',
      model: ["state.time", "state.entities", "state.marker", "ui"]
    }, {
      component: _dialogs2.default,
      placeholder: '.vzb-tool-dialogs',
      model: ['state', 'ui', 'locale']
    }, {
      component: _buttonlist2.default,
      placeholder: '.vzb-tool-buttonlist',
      model: ['state', 'ui', 'locale']
    }, {
      component: _treemenu2.default,
      placeholder: '.vzb-tool-treemenu',
      model: ['state.marker', 'state.marker_tags', 'state.time', 'locale']
    }, {
      component: _datawarning2.default,
      placeholder: '.vzb-tool-datawarning',
      model: ['locale']
    }, {
      component: _datanotes2.default,
      placeholder: '.vzb-tool-datanotes',
      model: ['state.marker', 'locale']
    }];

    //constructor is the same as any tool
    this._super(placeholder, external_model);
  },

  default_model: {
    state: {
      time: {
        "delay": 100,
        "delayThresholdX2": 50,
        "delayThresholdX4": 25
      },
      "entities": {
        "opacitySelectDim": 0.3,
        "opacityRegular": 0.7
      }
    },
    locale: {},
    ui: {
      chart: {
        manualSortingEnabled: true,
        yMaxMethod: "latest",
        showProbeX: true,
        probeX: 1.85,
        xLogStops: [1, 2, 5],
        xPoints: 50
      },
      datawarning: {
        doubtDomain: [],
        doubtRange: []
      },
      presentation: false
    }
  }
});

exports.default = MountainChart;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _requireAll = __webpack_require__(70);

var _requireAll2 = _interopRequireDefault(_requireAll);

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _tool = __webpack_require__(14);

var _tool2 = _interopRequireDefault(_tool);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _model = __webpack_require__(46);

var _model2 = _interopRequireDefault(_model);

var _reader = __webpack_require__(71);

var _reader2 = _interopRequireDefault(_reader);

var _events = __webpack_require__(45);

var _events2 = _interopRequireDefault(_events);

var _globals = __webpack_require__(44);

var _globals2 = _interopRequireDefault(_globals);

var _d = __webpack_require__(210);

var _d2 = _interopRequireDefault(_d);

var _d3 = __webpack_require__(211);

var _d4 = __webpack_require__(212);

var touchFixes = _interopRequireWildcard(_d4);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var Vzb = function Vzb(name, placeholder, external_model) {
  var tool = _tool2.default.get(name);
  if (tool) {
    var t = new tool(placeholder, external_model);
    Vzb._instances[t._id] = t;
    return t;
  } else {
    utils.error('Tool "' + name + '" was not found.');
  }
};

//stores reference to each tool on the page
Vzb._instances = {};
//stores global variables accessible by any tool or component
Vzb._globals = _globals2.default;

//TODO: clear all objects and intervals as well
//garbage collection
Vzb.clearInstances = function (id) {
  if (id) {
    Vzb._instances[id] = void 0;
  } else {
    for (var i in Vzb._instances) {
      Vzb._instances[i].clear();
    }
    Vzb._instances = {};
  }
};

//available readers = all
var readers = (0, _requireAll2.default)(__webpack_require__(458));

//register available readers
utils.forEach(readers, function (reader, name) {
  _reader2.default.register(name, reader);
});

var components = (0, _requireAll2.default)(__webpack_require__(454), 1);

//register available components
utils.forEach(components, function (component, name) {
  _component2.default.register(name, component);
});

//d3 addons

d3.scale.genericLog = _d2.default;
d3.selection.prototype.onTap = _d3.onTap;
d3.selection.prototype.onLongTap = _d3.onLongTap;

//TODO: Fix for scroll on mobile chrome on d3 v3.5.17. It must be retested/removed on d3 v4.x.x
//see explanation here https://github.com/vizabi/vizabi/issues/2020#issuecomment-250205191
d3.svg.brush = touchFixes.brush;
d3.behavior.drag = touchFixes.drag;
d3.behavior.zoom = touchFixes.zoom;

//makes all objects accessible
Vzb.Tool = _tool2.default;
Vzb.Component = _component2.default;
Vzb.Model = _model2.default;
Vzb.Reader = _reader2.default;
Vzb.Events = _events2.default;
Vzb.utils = utils;

exports.default = Vzb;

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

"use strict";
/* WEBPACK VAR INJECTION */(function(global) {"use strict";

__webpack_require__(408);

__webpack_require__(452);

__webpack_require__(228);

if (global._babelPolyfill) {
  throw new Error("only one instance of babel-polyfill is allowed");
}
global._babelPolyfill = true;

var DEFINE_PROPERTY = "defineProperty";
function define(O, key, value) {
  O[key] || Object[DEFINE_PROPERTY](O, key, {
    writable: true,
    configurable: true,
    value: value
  });
}

define(String.prototype, "padLeft", "".padStart);
define(String.prototype, "padRight", "".padEnd);

"pop,reverse,shift,keys,values,entries,indexOf,every,some,forEach,map,filter,find,findIndex,includes,join,slice,concat,push,splice,unshift,sort,lastIndexOf,reduce,reduceRight,copyWithin,fill".split(",").forEach(function (key) {
  [][key] && define(Array, key, Function.call.bind([][key]));
});
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(179)))

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

// removed by extract-text-webpack-plugin

/***/ },
/* 195 */,
/* 196 */,
/* 197 */,
/* 198 */,
/* 199 */,
/* 200 */,
/* 201 */,
/* 202 */,
/* 203 */,
/* 204 */,
/* 205 */,
/* 206 */,
/* 207 */
/***/ function(module, exports, __webpack_require__) {

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _class = __webpack_require__(21);

var _class2 = _interopRequireDefault(_class);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var Intervals = _class2.default.extend({

  /**
   * Initializes intervals
   */
  init: function init() {
    this.intervals = {};
  },

  /**
   * Sets an interval
   * @param {String} name name of interval
   * @param {Function} func function to be executed
   * @param {Number} duration duration in milliseconds
   */
  setInterval: function (_setInterval) {
    function setInterval(_x, _x2, _x3) {
      return _setInterval.apply(this, arguments);
    }

    setInterval.toString = function () {
      return _setInterval.toString();
    };

    return setInterval;
  }(function (name, func, duration) {
    this.clearInterval(name);
    this.intervals[name] = setInterval(func, duration);
  }),

  /**
   * Clears an interval
   * @param {String} name name of interval to be removed
   */
  clearInterval: function (_clearInterval) {
    function clearInterval(_x4) {
      return _clearInterval.apply(this, arguments);
    }

    clearInterval.toString = function () {
      return _clearInterval.toString();
    };

    return clearInterval;
  }(function (name) {
    return name ? clearInterval(this.intervals[name]) : this.clearAllIntervals();
  }),

  /**
   * Clears all intervals
   */
  clearAllIntervals: function clearAllIntervals() {
    for (var i in this.intervals) {
      this.clearInterval(i);
    }
  }
});

exports.default = Intervals;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = collisionResolver;
//d3.svg.collisionResolver

function collisionResolver() {
  return function collision_resolver() {
    var DURATION = 300;
    var labelHeight = {};
    var labelPosition = {};
    // MAINN FUNCTION. RUN COLLISION RESOLVER ON A GROUP g
    function resolver(g) {
      if (data == null) {
        console.warn('D3 collision resolver stopped: missing data to work with. Example: data = {asi: {valueY: 45, valueX: 87}, ame: {valueY: 987, valueX: 767}}');
        return;
      }
      if (selector == null) {
        console.warn('D3 collision resolver stopped: missing a CSS slector');
        return;
      }
      if (height == null) {
        console.warn('D3 collision resolver stopped: missing height of the canvas');
        return;
      }
      if (value == null) {
        console.warn('D3 collision resolver stopped: missing pointer within data objects. Example: value = \'valueY\' ');
        return;
      }
      if (KEY == null) {
        console.warn('D3 collision resolver stopped: missing a key for data. Example: key = \'geo\' ');
        return;
      }
      g.each(function (d, index) {
        labelHeight[d[KEY]] = d3.select(this).select(selector)[0][0].getBBox().height;
      });
      labelPosition = resolver.calculatePositions(data, value, height, scale);
      //actually reposition the labels
      g.each(function (d, i) {
        if (!data[d[KEY]] || data[d[KEY]][fixed]) return;
        var resolvedY = labelPosition[d[KEY]] || scale(data[d[KEY]][value]) || 0;
        var resolvedX = null;
        if (handleResult != null) {
          handleResult(d, i, this, resolvedX, resolvedY);
          return;
        }
        d3.select(this).selectAll(selector).transition().duration(DURATION).attr('transform', 'translate(0,' + resolvedY + ')');
      });
    }

    // CALCULATE OPTIMIZED POSITIONS BASED ON LABELS' HEIGHT AND THEIR PROXIMITY (DELTA)
    resolver.calculatePositions = function (data, value, height, scale) {
      var result = {};
      var keys = Object.keys(data).sort(function (a, b) {
        return data[a][value] - data[b][value];
      });
      keys.forEach(function (d, index) {
        //initial positioning
        result[d] = scale(data[d][value]);
        // check the overlapping chain reaction all the way down
        for (var j = index; j > 0; j--) {
          // if overlap found shift the overlapped label downwards
          var delta = result[keys[j - 1]] - result[keys[j]] - labelHeight[keys[j]];
          if (delta < 0) result[keys[j - 1]] -= delta;
          // if the chain reaction stopped because found some gap in the middle, then quit
          if (delta > 0) break;
        }
      });
      // check if the lowest label is breaking the boundary...
      var delta = height - result[keys[0]] - labelHeight[keys[0]];
      // if it does, then
      if (delta < 0) {
        // shift the lowest up
        result[keys[0]] += delta;
        // check the overlapping chain reaction all the way up
        for (var j = 0; j < keys.length - 1; j++) {
          // if overlap found shift the overlapped label upwards
          var delta = result[keys[j]] - result[keys[j + 1]] - labelHeight[keys[j + 1]];
          if (delta < 0) result[keys[j + 1]] += delta;
          // if the chain reaction stopped because found some gap in the middle, then quit
          if (delta > 0) break;
        }
      }
      return result;
    };
    // GETTERS AND SETTERS
    var data = null;
    resolver.data = function (arg) {
      if (!arguments.length) return data;
      data = arg;
      return resolver;
    };
    var selector = null;
    resolver.selector = function (arg) {
      if (!arguments.length) return selector;
      selector = arg;
      return resolver;
    };
    var height = null;
    resolver.height = function (arg) {
      if (!arguments.length) return height;
      height = arg;
      return resolver;
    };
    var scale = d3.scale.linear().domain([0, 1]).range([0, 1]);
    resolver.scale = function (arg) {
      if (!arguments.length) return scale;
      scale = arg;
      return resolver;
    };
    var value = null;
    resolver.value = function (arg) {
      if (!arguments.length) return value;
      value = arg;
      return resolver;
    };
    var fixed = null;
    resolver.fixed = function (arg) {
      if (!arguments.length) return fixed;
      fixed = arg;
      return resolver;
    };
    var handleResult = null;
    resolver.handleResult = function (arg) {
      if (!arguments.length) return handleResult;
      handleResult = arg;
      return resolver;
    };
    var KEY = null;
    resolver.KEY = function (arg) {
      if (!arguments.length) return KEY;
      KEY = arg;
      return resolver;
    };
    return resolver;
  }();
};

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = colorPicker;
//d3.svg.colorPicker


var instance = null;

function colorPicker() {

  return function getInstance() {
    if (instance == null) {
      instance = d3_color_picker();
    }
    return instance;
  }();

  function d3_color_picker() {
    // tuning defaults
    var nCellsH = 15;
    // number of cells by hues (angular)
    var minH = 0;
    // which hue do we start from: 0 to 1 instead of 0 to 365
    var nCellsL = 4;
    // number of cells by lightness (radial)
    var minL = .5;
    // which lightness to start from: 0 to 1. Recommended .3...0.5
    var satConstant = .7;
    // constant saturation for color wheel: 0 to 1. Recommended .7...0.8
    var outerL_display = .4;
    // ecxeptional saturation of the outer circle. the one displayed 0 to 1
    var outerL_meaning = .3;
    // ecxeptional saturation of the outer circle. the one actually ment 0 to 1
    var firstAngleSat = 0;
    // exceptional saturation at first angular segment. Set 0 to have shades of grey
    var minRadius = 15;
    //radius of the central hole in color wheel: px
    var maxWidth = 280;
    var maxHeight = 323;
    var margin = {
      top: .1,
      bottom: .1,
      left: .1,
      right: .1
    };
    //margins in % of container's width and height
    var colorOld = '#000';
    var colorDef = '#000';
    var colorWhite = '#f8f8f8';
    // names of CSS classes
    var css = {
      INVISIBLE: 'vzb-invisible',
      COLOR_POINTER: 'vzb-colorpicker-pointer',
      COLOR_BUTTON: 'vzb-colorpicker-cell',
      COLOR_DEFAULT: 'vzb-colorpicker-default',
      COLOR_SAMPLE: 'vzb-colorpicker-sample',
      COLOR_PICKER: 'vzb-colorpicker-svg',
      COLOR_CIRCLE: 'vzb-colorpicker-circle',
      COLOR_CIRCLES: 'vzb-colorpicker-circles',
      COLOR_SEGMENT: 'vzb-colorpicker-segment',
      COLOR_BACKGR: 'vzb-colorpicker-background'
    };
    var colorData = [];
    //here we store color data. formatted as follows:
    /*
     [
     [ // outer circle
     {display: "#123456", meaning: "#123456"}, // first angle
     ...
     {display: "#123456", meaning: "#123456"} // last angle, clockwise
     ],
     [ // next circle
     {display: "#123456", meaning: "#123456"}, // first angle
     ...
     {display: "#123456", meaning: "#123456"} // last angle, clockwise
     ],
      ...
      [ // inner circle
     {display: "#123456", meaning: "#123456"}, // first angle
     ...
     {display: "#123456", meaning: "#123456"} // last angle, clockwise
     ]
     ]
     */
    var arc = d3.svg.arc();
    var pie = d3.layout.pie().sort(null).value(function (d) {
      return 1;
    });
    var svg = null;
    var container = null;
    var colorPointer = null;
    var showColorPicker = false;
    var sampleRect = null;
    var sampleText = null;
    var background = null;
    var callback = function callback(value) {
      console.info('Color picker callback example. Setting color to ' + value);
    };

    function _generateColorData() {
      var result = [];
      // loop across circles
      for (var l = 0; l < nCellsL; l++) {
        var lightness = minL + (1 - minL) / nCellsL * l;
        // new circle of cells
        result.push([]);
        // loop across angles
        for (var h = 0; h <= nCellsH; h++) {
          var hue = minH + (1 - minH) / nCellsH * h;
          // new cell
          result[l].push({
            display: _hslToRgb(hue, h == 0 ? firstAngleSat : satConstant, l == 0 ? outerL_display : lightness),
            meaning: _hslToRgb(hue, h == 0 ? firstAngleSat : satConstant, l == 0 ? outerL_meaning : lightness)
          });
        }
      }
      return result;
    }

    function _hslToRgb(h, s, l) {
      var r, g, b;
      if (s == 0) {
        r = g = b = l; // achromatic
      } else {
        var _hue2rgb = function _hue2rgb(p, q, t) {
          if (t < 0) t += 1;
          if (t > 1) t -= 1;
          if (t < 1 / 6) return p + (q - p) * 6 * t;
          if (t < 1 / 2) return q;
          if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
          return p;
        };
        var q = l < .5 ? l * (1 + s) : l + s - l * s;
        var p = 2 * l - q;
        r = _hue2rgb(p, q, h + 1 / 3);
        g = _hue2rgb(p, q, h);
        b = _hue2rgb(p, q, h - 1 / 3);
      }
      return '#' + Math.round(r * 255).toString(16) + Math.round(g * 255).toString(16) + Math.round(b * 255).toString(16);
    }

    // this is init function. call it once after you are satisfied with parameters tuning
    // container should be a D3 selection that has a div where we want to render color picker
    // that div should have !=0 width and height in its style
    function colorPicker(container) {
      colorPicker.container = container;
      svg = container.select('.' + css.COLOR_PICKER);
      if (!svg.empty()) {
        return;
      }
      container.on('click', function () {
        colorPicker.show(false);
        d3.event.stopPropagation();
      });
      colorData = _generateColorData();

      svg = container.append('svg').style('position', 'absolute').style('top', '0').style('left', '0').style('width', '100%').style('max-width', maxWidth + "px").style('height', '100%').style('max-height', maxHeight + "px").style('z-index', 9999).attr('class', css.COLOR_PICKER + " vzb-dialog-shadow").classed(css.INVISIBLE, !showColorPicker).on('mouseout', function (d) {
        _cellHover(colorOld);
      });

      var width = parseInt(svg.style('width'));
      var height = parseInt(svg.style('height'));
      var maxRadius = width / 2 * (1 - margin.left - margin.right);
      background = svg.append('rect').attr('width', width).attr('height', maxHeight).attr('class', css.COLOR_BUTTON + ' ' + css.COLOR_BACKGR).on('mouseover', function (d) {
        _cellHover(colorOld);
      });
      var circles = svg.append('g').attr('class', css.COLOR_CIRCLES).attr('transform', 'translate(' + (maxRadius + width * margin.left) + ',' + (maxRadius + height * margin.top) + ')');

      svg.append('rect').attr('class', css.COLOR_SAMPLE).attr('width', width / 2).attr('height', height * margin.top / 2);

      sampleRect = svg.append('rect').attr('class', css.COLOR_SAMPLE).attr('width', width / 2).attr('x', width / 2).attr('height', height * margin.top / 2);

      svg.append('text').attr('x', width * margin.left).attr('y', height * margin.top / 2).attr('dy', '1.3em').attr('class', css.COLOR_SAMPLE).style('text-anchor', 'start');

      sampleText = svg.append('text').attr('x', width * (1 - margin.right)).attr('y', height * margin.top / 2).attr('dy', '1.3em').attr('class', css.COLOR_SAMPLE).style('text-anchor', 'end');

      svg.append('text').attr('x', width * .1).attr('y', height * (1 - margin.bottom)).attr('dy', '1.2em').attr('class', "vzb-default-label").style('text-anchor', 'start').text('default');

      svg.append('circle').attr('class', css.COLOR_DEFAULT + ' ' + css.COLOR_BUTTON).attr('r', width * margin.left / 2).attr('cx', width * margin.left * 1.5).attr('cy', height * (1 - margin.bottom * 1.5)).on('mouseover', function () {
        d3.select(this).style('stroke', '#444');
        _cellHover(colorDef);
      }).on('mouseout', function () {
        d3.select(this).style('stroke', 'none');
      });

      circles.selectAll('.' + css.COLOR_CIRCLE).data(colorData).enter().append('g').attr('class', css.COLOR_CIRCLE).each(function (circleData, index) {
        arc.outerRadius(minRadius + (maxRadius - minRadius) / nCellsL * (nCellsL - index)).innerRadius(minRadius + (maxRadius - minRadius) / nCellsL * (nCellsL - index - 1));
        var segment = d3.select(this).selectAll('.' + css.COLOR_SEGMENT).data(pie(circleData)).enter().append('g').attr('class', css.COLOR_SEGMENT);

        segment.append('path').attr('class', css.COLOR_BUTTON).attr('d', arc).style('fill', function (d) {
          return d.data.display;
        }).style('stroke', function (d) {
          return d.data.display;
        }).on('mouseover', function (d) {
          _cellHover(d.data.meaning, this);
        }).on('mouseout', function (d) {
          _cellUnHover();
        });
      });

      circles.append('circle').attr('r', minRadius).attr('fill', colorWhite).attr('class', css.COLOR_BUTTON).on('mouseover', function () {
        d3.select(this).style('stroke', "#555");
        _cellHover(colorWhite);
      }).on('mouseout', function () {
        d3.select(this).style('stroke', 'none');
      });

      colorPointer = circles.append('path').attr('class', css.COLOR_POINTER + ' ' + css.INVISIBLE);

      svg.selectAll('.' + css.COLOR_BUTTON).on('click', function () {
        d3.event.stopPropagation();
        _this.show(false);
      });
      _doTheStyling(svg);
      colorPicker.resize(svg);
    }

    var _doTheStyling = function _doTheStyling(svg) {
      //styling
      svg.select('.' + css.COLOR_BACKGR).style('fill', 'white');

      svg.select('.' + css.COLOR_POINTER).style('stroke-width', 2).style('stroke', colorWhite).style('pointer-events', 'none').style('fill', 'none');

      svg.selectAll('.' + css.COLOR_BUTTON).style('cursor', 'pointer');

      svg.selectAll('text').style('fill', '#D9D9D9').style('font-size', '0.7em').style('text-transform', 'uppercase');

      svg.selectAll('circle.' + css.COLOR_BUTTON).style('stroke-width', 2);
    };

    var _this = colorPicker;
    var _cellHover = function _cellHover(value, view) {
      // show color pointer if the view is set (a cell of colorwheel)
      if (view != null) colorPointer.classed(css.INVISIBLE, false).attr('d', d3.select(view).attr('d'));

      sampleRect.style('fill', value);
      sampleText.text(value);
      callback(value);
    };
    var _cellUnHover = function _cellUnHover() {
      colorPointer.classed(css.INVISIBLE, true);
    };
    //Use this function to hide or show the color picker
    //true = show, false = hide, "toggle" or TOGGLE = toggle
    var TOGGLE = 'toggle';
    colorPicker.show = function (arg) {
      if (!arguments.length) return showColorPicker;
      if (svg == null) console.warn('Color picker is missing SVG element. Was init sequence performed?');
      showColorPicker = arg == TOGGLE ? !showColorPicker : arg;
      if (!showColorPicker) {
        callback = function callback() {};
      }
      svg.classed(css.INVISIBLE, !showColorPicker);
    };
    // getters and setters
    colorPicker.nCellsH = function (arg) {
      if (!arguments.length) return nCellsH;
      nCellsH = arg;
      return colorPicker;
    };
    colorPicker.minH = function (arg) {
      if (!arguments.length) return minH;
      minH = arg;
      return colorPicker;
    };
    colorPicker.nCellsL = function (arg) {
      if (!arguments.length) return nCellsL;
      nCellsL = arg;
      return colorPicker;
    };
    colorPicker.minL = function (arg) {
      if (!arguments.length) return minL;
      minL = arg;
      return colorPicker;
    };
    colorPicker.outerL_display = function (arg) {
      if (!arguments.length) return outerL_display;
      outerL_display = arg;
      return colorPicker;
    };
    colorPicker.outerL_meaning = function (arg) {
      if (!arguments.length) return outerL_meaning;
      outerL_meaning = arg;
      return colorPicker;
    };
    colorPicker.satConstant = function (arg) {
      if (!arguments.length) return satConstant;
      satConstant = arg;
      return colorPicker;
    };
    colorPicker.firstAngleSat = function (arg) {
      if (!arguments.length) return firstAngleSat;
      firstAngleSat = arg;
      return colorPicker;
    };
    colorPicker.minRadius = function (arg) {
      if (!arguments.length) return minRadius;
      minRadius = arg;
      return colorPicker;
    };
    colorPicker.margin = function (arg) {
      if (!arguments.length) return margin;
      margin = arg;
      return colorPicker;
    };
    colorPicker.callback = function (arg) {
      if (!arguments.length) return callback;
      callback = arg;
      return colorPicker;
    };
    colorPicker.colorDef = function (arg) {
      if (!arguments.length) return colorDef;
      if (typeof arg !== 'undefined') {
        colorDef = arg;
      }
      if (svg == null) console.warn('Color picker is missing SVG element. Was init sequence performed?');
      svg.select('.' + css.COLOR_DEFAULT).style('fill', colorDef);
      return colorPicker;
    };
    colorPicker.translate = function (translator) {
      if (translator instanceof Function) {
        svg.select(".vzb-default-label").text(translator("colorpicker/default"));
      }
      return colorPicker;
    };
    /**
     * @param {ClientRect} screen parent element
     * @param {int[]} arg [x,y] of color picker position
     */
    colorPicker.fitToScreen = function (arg) {
      var screen = colorPicker.container.node().getBoundingClientRect();
      var xPos, yPos;

      var width = parseInt(svg.style('width'));
      var height = parseInt(svg.style('height'));

      if (!arg) {
        xPos = screen.width - parseInt(svg.style('right')) - width;
        yPos = parseInt(svg.style('top'));
      } else {
        xPos = arg[0] - screen.left;
        yPos = arg[1] - screen.top;
      }

      var styles = { left: '' };
      if (screen.width * 0.8 <= width) {
        styles.right = (screen.width - width) * 0.5 + "px";
      } else if (xPos + width > screen.width) {
        styles.right = Math.min(screen.width * 0.1, 20) + "px";
      } else {
        styles.right = screen.width - xPos - width + "px";
      }
      if (screen.height * 0.8 <= height) {
        styles.top = (screen.height - height) * 0.5 + "px";
      } else if (yPos + height * 1.2 > screen.height) {
        styles.top = screen.height * 0.9 - height + "px";
      } else {
        styles.top = yPos + "px";
      }

      svg.style(styles);
      return colorPicker;
    };
    colorPicker.colorOld = function (arg) {
      if (!arguments.length) return colorOld;
      colorOld = arg;
      if (svg == null) console.warn('Color picker is missing SVG element. Was init sequence performed?');
      svg.select('rect.' + css.COLOR_SAMPLE).style('fill', colorOld);
      svg.select('text.' + css.COLOR_SAMPLE).text(colorOld);
      return colorPicker;
    };

    colorPicker.resize = function (arg) {

      if (!arguments.length) return resize;
      if (typeof arg !== 'undefined') {
        var svg = arg;
        var width = parseInt(svg.style('width'));
        var height = parseInt(svg.style('height'));
        var maxRadius = width / 2 * (1 - margin.left - margin.right);
        var selectedColor = svg.select('.' + css.COLOR_DEFAULT);
        var defaultLabel = svg.select('.vzb-default-label');
        var circles = svg.select('.' + css.COLOR_CIRCLES);

        var hPos = maxRadius + height * margin.top;
        var hPosCenter = (1 + margin.top * .5) * height * .5;
        hPos = hPos > hPosCenter ? hPosCenter : hPos;
        circles.attr('transform', 'translate(' + (maxRadius + width * margin.left) + ',' + hPos + ')');
        selectedColor.attr('cx', width * margin.left * 1.5).attr('cy', height * (1 - margin.bottom * 1.5));
        defaultLabel.attr('x', width * .1).attr('y', height * (1 - margin.bottom));
      }
      colorPicker.fitToScreen();

      return colorPicker;
    };
    return colorPicker;
  };
};

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

"use strict";
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = genericLog;
//  d3.scale.genericLog
function genericLog() {
  return function d3_scale_genericLog(logScale) {
    var _this = this;
    var scales = [];
    var domainParts = [];
    var eps = 0.1;
    var delta = 5;
    var domain = logScale.domain();
    var range = logScale.range();
    var interpolator = null;
    var rangePointingForward, domainPointingForward;

    var abs = function abs(arg) {
      if (arg instanceof Array) return arg.map(function (d) {
        return Math.abs(d);
      });
      return Math.abs(arg);
    };

    var _buildLinearScale = function _buildLinearScale(fakeDomain, fakeRange) {
      return {
        domain: fakeDomain,
        sign: 1,
        range: fakeRange,
        scale: d3.scale.linear().domain(fakeDomain).range(fakeRange)
      };
    };

    var _buildLogScale = function _buildLogScale(fakeDomain, fakeRange, revertDomain) {
      var normalizedDomain = fakeDomain;
      //var normalizedRange = fakeRange.slice(0);
      if (revertDomain) {
        normalizedDomain = abs(fakeDomain);
        //fakeRange.reverse();
      }
      return {
        domain: fakeDomain,
        sign: revertDomain ? -1 : 1,
        range: fakeRange,
        scale: d3.scale.log().domain(normalizedDomain).range(fakeRange)
      };
    };

    var buildScales = function buildScales() {
      rangePointingForward = range[0] < range[range.length - 1];
      var rangePointingSign = rangePointingForward ? 1 : -1;
      scales = [];
      if (domainParts.length == 1) {
        if (domainParts[0][0] <= 0 && domainParts[0][1] >= 0) {
          scales = [_buildLinearScale(domainParts[0], range)];
        } else {
          scales = [_buildLogScale(domainParts[0], range, domainParts[0][0] <= 0)];
        }
      } else {
        var maxDomain = d3.max(abs(domain));
        var rangeLength = abs(d3.max(range) - d3.min(range));
        var minRangePoint,
            rangePointKoef = 1;
        var firstRangePoint = 0,
            secondRangePoint = 0,
            firstEps = 0,
            secondEps = 0;
        logScale.domain([eps, maxDomain]).range([0, rangeLength]);
        minRangePoint = delta; //logScale(eps * 2);
        if (domain[0] != 0 && abs(domain[0]) > eps) firstRangePoint = logScale(abs(domain[0]));
        if (domain[domain.length - 1] != 0 && abs(domain.length - 1) > eps) secondRangePoint = logScale(abs(domain[domain.length - 1]));

        if (abs(domain[0]) > eps) firstEps = minRangePoint;

        if (abs(domain[domain.length - 1]) > eps) secondEps = minRangePoint;

        rangeLength = rangeLength - firstEps - secondEps;
        if (secondRangePoint != 0) rangePointKoef = abs(firstRangePoint / secondRangePoint);

        var point1, point2;
        if (domainParts.length == 2) {
          // example: [-eps..0,eps][eps, val]
          if (domain[0] == 0 || abs(domain[0]) <= eps) {
            point1 = range[0] + firstRangePoint * rangePointKoef * rangePointingSign + secondEps * rangePointingSign;
            scales = [_buildLinearScale(domainParts[0], [range[0], point1]), _buildLogScale(domainParts[1], [point1, range[range.length - 1]], !domainPointingForward)];
          } else if (domain[domain.length - 1] == 0 || abs(domain[domain.length - 1]) <= eps) {
            // example: [-val,-eps][-eps, 0..eps]
            point1 = range[range.length - 1] - (firstEps + secondEps) * rangePointKoef * rangePointingSign;
            scales = [_buildLogScale(domainParts[0], [range[0], point1], domainPointingForward), _buildLinearScale(domainParts[1], [point1, range[range.length - 1]])];
          }
        } else {
          point1 = range[0] + rangeLength / (1 / rangePointKoef + 1) * rangePointingSign;
          point2 = range[0] + (rangeLength / (1 / rangePointKoef + 1) + firstEps + secondEps) * rangePointingSign;
          scales = [_buildLogScale(domainParts[0], [range[0], point1], domainPointingForward), _buildLinearScale(domainParts[1], [point1, point2]), _buildLogScale(domainParts[2], [point2, range[range.length - 1]], !domainPointingForward)];
        }
      }
    };

    var buildDomain = function buildDomain() {
      domainPointingForward = domain[0] < domain[domain.length - 1];
      domainParts = [];
      if (d3.min(domain) > 0 && d3.max(domain) > 0 || d3.min(domain) < 0 && d3.max(domain) < 0) {
        domainParts = [domain];
      } else {
        var start, end;
        if (domainPointingForward) {
          start = domain[0];
          end = domain[domain.length - 1];
        } else {
          start = domain[domain.length - 1];
          end = domain[0];
        }
        var _addSubdomain = function _addSubdomain(first, second) {
          if (domainPointingForward) {
            domainParts.push([first, second]);
          } else {
            domainParts.unshift([second, first]);
          }
        };
        while (start != end) {
          if (end <= -eps || start >= -eps && end <= eps || start >= eps) {
            _addSubdomain(start, end);
            start = end;
          } else if (start < -eps && end >= -eps) {
            _addSubdomain(start, -eps);
            start = -eps;
          } else if (start >= -eps && end >= eps) {
            _addSubdomain(start, eps);
            start = eps;
          } else {
            console.warn("Something wrong while build subdomains: " + start + " " + end);
            start = end;
          }
        }
      }
      buildScales();
    };

    var _getScaleByDomain = function _getScaleByDomain(x) {
      if (domainPointingForward) {
        if (x < domain[0]) {
          return scales[0];
        } else if (x > domain[domain.length - 1]) {
          return scales[scales.length - 1];
        } else {
          for (var i = 0; i < scales.length; i++) {
            if (x >= scales[i].domain[0] && x <= scales[i].domain[scales[i].domain.length - 1]) {
              return scales[i];
            }
          }
        }
      } else {
        if (x > domain[0]) {
          return scales[0];
        } else if (x < domain[domain.length - 1]) {
          return scales[scales.length - 1];
        } else {
          for (var i = 0; i < scales.length; i++) {
            scale = scales[i];
            if (x <= scales[i].domain[0] && x >= scales[i].domain[scales[i].domain.length - 1]) {
              return scales[i];
            }
          }
        }
      }
    };

    var getScaleByRange = function getScaleByRange(x) {
      if (rangePointingForward) {
        if (x < range[0]) {
          return scales[0];
        } else if (x > range[range.length - 1]) {
          return scales[scales.length - 1];
        } else {
          for (var i = 0; i < scales.length; i++) {
            if (x >= scales[i].range[0] && x <= scales[i].range[scales[i].range.length - 1]) {
              return scales[i];
            }
          }
        }
      } else {
        if (x > range[0]) {
          return scales[0];
        } else if (x < range[range.length - 1]) {
          return scales[scales.length - 1];
        } else {
          for (var i = 0; i < scales.length; i++) {
            var scalePart = scales[i];
            if (x <= scales[i].range[0] && x >= scales[i].range[1]) {
              return scales[i];
            }
          }
        }
      }
    };

    //polyfill for IE11
    Math.sign = Math.sign || function (x) {
      x = +x;
      if (x === 0 || isNaN(x)) {
        return x;
      }
      return x > 0 ? 1 : -1;
    };

    function scale(x) {
      var currScale = _getScaleByDomain(x);
      if (interpolator) {
        return interpolator(currScale.scale(x * currScale.sign));
      } else {
        return currScale.scale(x * currScale.sign);
      }
    }

    scale.eps = function (arg) {
      if (!arguments.length) return eps;
      eps = arg;
      scale.domain(domain);
      return scale;
    };

    scale.delta = function (arg) {
      if (!arguments.length) return delta;
      delta = arg;
      scale.range(range);
      return scale;
    };

    scale.domain = function (arg) {
      if (!arguments.length) return domain;

      // this is an internal array, it will be modified. the input _arg should stay intact
      switch (arg.length) {
        // if no values are given, reset input to the default domain (do nothing)
        case 0:
          arg = domain;
          break;
        // use the given value as a center, get the domain /2 and *2 around it
        case 1:
          arg = [arg[0] / 2, arg[0] * 2];
          break;
      }
      //if the domain is just a single value
      if (arg[0] == arg[arg.length - 1]) {
        arg[0] = arg[0] / 2;
        arg[arg.length - 1] = arg[arg.length - 1] * 2;
      }
      domain = arg;
      var min = d3.min(abs(domain).filter(function (val) {
        return !!val;
      }));
      if (min) eps = Math.min(eps, min / 100);
      buildDomain();
      return scale;
    };

    scale.range = function (arg, force) {
      if (!arguments.length) return interpolator ? interpolator.range() : range;

      switch (arg.length) {
        // reset input to the default range
        case 0:
          arg = range;
          break;
        // use the only value as a center, get the range ±100 around it
        case 1:
          arg = [arg[0] - 100, arg[0] + 100];
          break;
        // two is the standard case. do nothing
      }

      //console.log("LOG and LIN range:", logScale.range(), linScale.range());
      if (interpolator && !force) {
        interpolator.range(arg);
      } else {
        range = arg;
        var min = d3.min(abs(range).filter(function (val) {
          return !!val;
        }));

        if (min) delta = Math.min(delta, min / 100);
        buildScales();
      }
      return scale;
    };

    scale.interpolate = function (arg) {
      interpolator = d3.scale.linear().domain(domain).range(range).interpolate(arg);
      scale.range(interpolator.domain(), true);
      return scale;
    };

    scale.invert = function (arg) {
      var currScale = getScaleByRange(arg);
      return currScale.scale.invert(arg) * currScale.sign;
    };

    scale.ticks = function (arg) {
      var ticks = [],
          partTicks;
      for (var i = 0; i < scales.length; i++) {
        if (scales[i].sign == -1) {
          partTicks = scales[i].scale.ticks().reverse().map(function (val) {
            return val * -1;
          });
        } else {
          partTicks = scales[i].scale.ticks();
        }
        if (ticks.length > 0 && partTicks.length > 0 && ticks[ticks.length - 1] == partTicks[0]) {
          partTicks.splice(0, 1);
        }
        ticks.push.apply(ticks, partTicks);
      }
      return ticks;
    };

    scale.copy = function () {
      return d3_scale_genericLog(logScale).domain(domain).range(range).delta(delta).eps(eps);
    };

    return d3.rebind(scale, logScale, 'base', 'rangeRound', 'clamp', 'nice', 'tickFormat');
  }(d3.scale.log().domain([0.1, 200]).range([0, 1000]));
};

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
function detectTouchEvent(element, onTap, onLongTap) {
  var start;
  var coordX;
  var coordY;
  var namespace = onTap ? '.onTap' : '.onLongTap';
  d3.select(element).on('touchstart' + namespace, function (d, i) {
    start = d3.event.timeStamp;
    coordX = d3.event.changedTouches[0].screenX;
    coordY = d3.event.changedTouches[0].screenY;
  }).on('touchend' + namespace, function (d, i) {
    coordX = Math.abs(coordX - d3.event.changedTouches[0].screenX);
    coordY = Math.abs(coordY - d3.event.changedTouches[0].screenY);
    if (coordX < 5 && coordY < 5) {
      if (d3.event.timeStamp - start < 500) return onTap ? onTap(d, i) : undefined;
      return onLongTap ? onLongTap(d, i) : undefined;
    } else return undefined;
  });
}

//d3.selection.prototype.onTap
var onTap = function onTap(callback) {
  return this.each(function () {
    detectTouchEvent(this, callback);
  });
};

//d3.selection.prototype.onLongTap
var onLongTap = function onLongTap(callback) {
  return this.each(function () {
    detectTouchEvent(this, null, callback);
  });
};

exports.default = {
  onTap: onTap,
  onLongTap: onLongTap
};
exports.onTap = onTap;
exports.onLongTap = onLongTap;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.zoom = exports.drag = exports.brush = undefined;

var _utils = __webpack_require__(1);

//TODO: Fix for scroll on mobile chrome on d3 v3.5.17. It must be retested/removed on d3 v4.x.x
//see explanation here https://github.com/vizabi/vizabi/issues/2020#issuecomment-250205191

function touchcancel() {
  d3.event.target.dispatchEvent(new TouchEvent('touchend', d3.event));
}

var drag = function (_d3_behaviour_drag) {
  if (!(0, _utils.isTouchDevice)()) return _d3_behaviour_drag;

  return function () {

    return function (_super) {

      function drag() {
        _super.call(this);
        this.on("mousedown.drag", null);
        this.on("touchcancel", touchcancel);
      };

      return d3.rebind(drag, _super, "origin", "on");
    }(_d3_behaviour_drag());
  };
}(d3.behavior.drag);

var zoom = function (_d3_behaviour_zoom) {
  if (!(0, _utils.isTouchDevice)()) return _d3_behaviour_zoom;

  return function () {

    return function (_super) {

      function zoom(g) {
        _super(g);
        g.on("mousedown.zoom", null);
        g.on("touchcancel", touchcancel);
        zoom.on("zoomend.clearmousedown", function () {
          g.on("mousedown.zoom", null);
        });
      };

      return d3.rebind(zoom, _super, "translate", "scale", "scaleExtent", "center", "size", "x", "y", "on", "event");
    }(_d3_behaviour_zoom());
  };
}(d3.behavior.zoom);

var brush = function (_d3_svg_brush) {
  if (!(0, _utils.isTouchDevice)()) return _d3_svg_brush;

  function d3_window(node) {
    return node && (node.ownerDocument && node.ownerDocument.defaultView || node.document && node || node.defaultView);
  }

  return function () {

    return function (_super) {

      function brushstart() {
        brush.on("brushend.touchcancel", brushend);

        var w = d3.select(d3_window(this));
        w.on("touchcancel.brush", touchcancel);

        function brushend() {
          w.on("touchcancel.brush", null);
        }
      }

      function brush(g) {
        _super(g);
        g.each(function () {
          var g = d3.select(this).on("mousedown.brush", null);
        });
        brush.on("brushstart.touchcancel", brushstart);
      };

      return d3.rebind(brush, _super, "x", "y", "extent", "clamp", "clear", "empty", "on", "event");
    }(_d3_svg_brush());
  };
}(d3.svg.brush);

exports.default = {
  brush: brush,
  drag: drag,
  zoom: zoom
};
exports.brush = brush;
exports.drag = drag;
exports.zoom = zoom;

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

"use strict";
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});

// topojson
exports.default = function () {
  var topojson = {
    version: "1.6.19",
    mesh: function mesh(topology) {
      return object(topology, meshArcs.apply(this, arguments));
    },
    meshArcs: meshArcs,
    merge: function merge(topology) {
      return object(topology, mergeArcs.apply(this, arguments));
    },
    mergeArcs: mergeArcs,
    feature: featureOrCollection,
    neighbors: neighbors,
    presimplify: presimplify
  };

  function stitchArcs(topology, arcs) {
    var stitchedArcs = {},
        fragmentByStart = {},
        fragmentByEnd = {},
        fragments = [],
        emptyIndex = -1;

    // Stitch empty arcs first, since they may be subsumed by other arcs.
    arcs.forEach(function (i, j) {
      var arc = topology.arcs[i < 0 ? ~i : i],
          t;
      if (arc.length < 3 && !arc[1][0] && !arc[1][1]) {
        t = arcs[++emptyIndex], arcs[emptyIndex] = i, arcs[j] = t;
      }
    });

    arcs.forEach(function (i) {
      var e = ends(i),
          start = e[0],
          end = e[1],
          f,
          g;

      if (f = fragmentByEnd[start]) {
        delete fragmentByEnd[f.end];
        f.push(i);
        f.end = end;
        if (g = fragmentByStart[end]) {
          delete fragmentByStart[g.start];
          var fg = g === f ? f : f.concat(g);
          fragmentByStart[fg.start = f.start] = fragmentByEnd[fg.end = g.end] = fg;
        } else {
          fragmentByStart[f.start] = fragmentByEnd[f.end] = f;
        }
      } else if (f = fragmentByStart[end]) {
        delete fragmentByStart[f.start];
        f.unshift(i);
        f.start = start;
        if (g = fragmentByEnd[start]) {
          delete fragmentByEnd[g.end];
          var gf = g === f ? f : g.concat(f);
          fragmentByStart[gf.start = g.start] = fragmentByEnd[gf.end = f.end] = gf;
        } else {
          fragmentByStart[f.start] = fragmentByEnd[f.end] = f;
        }
      } else {
        f = [i];
        fragmentByStart[f.start = start] = fragmentByEnd[f.end = end] = f;
      }
    });

    function ends(i) {
      var arc = topology.arcs[i < 0 ? ~i : i],
          p0 = arc[0],
          p1;
      if (topology.transform) p1 = [0, 0], arc.forEach(function (dp) {
        p1[0] += dp[0], p1[1] += dp[1];
      });else p1 = arc[arc.length - 1];
      return i < 0 ? [p1, p0] : [p0, p1];
    }

    function flush(fragmentByEnd, fragmentByStart) {
      for (var k in fragmentByEnd) {
        var f = fragmentByEnd[k];
        delete fragmentByStart[f.start];
        delete f.start;
        delete f.end;
        f.forEach(function (i) {
          stitchedArcs[i < 0 ? ~i : i] = 1;
        });
        fragments.push(f);
      }
    }

    flush(fragmentByEnd, fragmentByStart);
    flush(fragmentByStart, fragmentByEnd);
    arcs.forEach(function (i) {
      if (!stitchedArcs[i < 0 ? ~i : i]) fragments.push([i]);
    });

    return fragments;
  }

  function meshArcs(topology, o, filter) {
    var arcs = [];

    function arc(i) {
      var j = i < 0 ? ~i : i;
      (geomsByArc[j] || (geomsByArc[j] = [])).push({
        i: i,
        g: geom
      });
    }

    function line(arcs) {
      arcs.forEach(arc);
    }

    function polygon(arcs) {
      arcs.forEach(line);
    }

    function geometry(o) {
      if (o.type === "GeometryCollection") o.geometries.forEach(geometry);else if (o.type in geometryType) geom = o, geometryType[o.type](o.arcs);
    }

    if (arguments.length > 1) {
      var geomsByArc = [],
          geom;

      var geometryType = {
        LineString: line,
        MultiLineString: polygon,
        Polygon: polygon,
        MultiPolygon: function MultiPolygon(arcs) {
          arcs.forEach(polygon);
        }
      };

      geometry(o);

      geomsByArc.forEach(arguments.length < 3 ? function (geoms) {
        arcs.push(geoms[0].i);
      } : function (geoms) {
        if (filter(geoms[0].g, geoms[geoms.length - 1].g)) arcs.push(geoms[0].i);
      });
    } else {
      for (var i = 0, n = topology.arcs.length; i < n; ++i) {
        arcs.push(i);
      }
    }

    return {
      type: "MultiLineString",
      arcs: stitchArcs(topology, arcs)
    };
  }

  function mergeArcs(topology, objects) {
    var polygonsByArc = {},
        polygons = [],
        components = [];

    objects.forEach(function (o) {
      if (o.type === "Polygon") register(o.arcs);else if (o.type === "MultiPolygon") o.arcs.forEach(register);
    });

    function register(polygon) {
      polygon.forEach(function (ring) {
        ring.forEach(function (arc) {
          (polygonsByArc[arc = arc < 0 ? ~arc : arc] || (polygonsByArc[arc] = [])).push(polygon);
        });
      });
      polygons.push(polygon);
    }

    function exterior(ring) {
      return cartesianRingArea(object(topology, {
        type: "Polygon",
        arcs: [ring]
      }).coordinates[0]) > 0; // TODO allow spherical?
    }

    polygons.forEach(function (polygon) {
      if (!polygon._) {
        var component = [],
            neighbors = [polygon];
        polygon._ = 1;
        components.push(component);
        while (polygon = neighbors.pop()) {
          component.push(polygon);
          polygon.forEach(function (ring) {
            ring.forEach(function (arc) {
              polygonsByArc[arc < 0 ? ~arc : arc].forEach(function (polygon) {
                if (!polygon._) {
                  polygon._ = 1;
                  neighbors.push(polygon);
                }
              });
            });
          });
        }
      }
    });

    polygons.forEach(function (polygon) {
      delete polygon._;
    });

    return {
      type: "MultiPolygon",
      arcs: components.map(function (polygons) {
        var arcs = [];

        // Extract the exterior (unique) arcs.
        polygons.forEach(function (polygon) {
          polygon.forEach(function (ring) {
            ring.forEach(function (arc) {
              if (polygonsByArc[arc < 0 ? ~arc : arc].length < 2) {
                arcs.push(arc);
              }
            });
          });
        });

        // Stitch the arcs into one or more rings.
        arcs = stitchArcs(topology, arcs);

        // If more than one ring is returned,
        // at most one of these rings can be the exterior;
        // this exterior ring has the same winding order
        // as any exterior ring in the original polygons.
        if ((n = arcs.length) > 1) {
          var sgn = exterior(polygons[0][0]);
          for (var i = 0, t; i < n; ++i) {
            if (sgn === exterior(arcs[i])) {
              t = arcs[0], arcs[0] = arcs[i], arcs[i] = t;
              break;
            }
          }
        }

        return arcs;
      })
    };
  }

  function featureOrCollection(topology, o) {
    return o.type === "GeometryCollection" ? {
      type: "FeatureCollection",
      features: o.geometries.map(function (o) {
        return feature(topology, o);
      })
    } : feature(topology, o);
  }

  function feature(topology, o) {
    var f = {
      type: "Feature",
      id: o.id,
      properties: o.properties || {},
      geometry: object(topology, o)
    };
    if (o.id == null) delete f.id;
    return f;
  }

  function object(topology, o) {
    var absolute = transformAbsolute(topology.transform),
        arcs = topology.arcs;

    function arc(i, points) {
      if (points.length) points.pop();
      for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length, p; k < n; ++k) {
        points.push(p = a[k].slice());
        absolute(p, k);
      }
      if (i < 0) reverse(points, n);
    }

    function point(p) {
      p = p.slice();
      absolute(p, 0);
      return p;
    }

    function line(arcs) {
      var points = [];
      for (var i = 0, n = arcs.length; i < n; ++i) {
        arc(arcs[i], points);
      }if (points.length < 2) points.push(points[0].slice());
      return points;
    }

    function ring(arcs) {
      var points = line(arcs);
      while (points.length < 4) {
        points.push(points[0].slice());
      }return points;
    }

    function polygon(arcs) {
      return arcs.map(ring);
    }

    function geometry(o) {
      var t = o.type;
      return t === "GeometryCollection" ? {
        type: t,
        geometries: o.geometries.map(geometry)
      } : t in geometryType ? {
        type: t,
        coordinates: geometryType[t](o)
      } : null;
    }

    var geometryType = {
      Point: function Point(o) {
        return point(o.coordinates);
      },
      MultiPoint: function MultiPoint(o) {
        return o.coordinates.map(point);
      },
      LineString: function LineString(o) {
        return line(o.arcs);
      },
      MultiLineString: function MultiLineString(o) {
        return o.arcs.map(line);
      },
      Polygon: function Polygon(o) {
        return polygon(o.arcs);
      },
      MultiPolygon: function MultiPolygon(o) {
        return o.arcs.map(polygon);
      }
    };

    return geometry(o);
  }

  function reverse(array, n) {
    var t,
        j = array.length,
        i = j - n;
    while (i < --j) {
      t = array[i], array[i++] = array[j], array[j] = t;
    }
  }

  function bisect(a, x) {
    var lo = 0,
        hi = a.length;
    while (lo < hi) {
      var mid = lo + hi >>> 1;
      if (a[mid] < x) lo = mid + 1;else hi = mid;
    }
    return lo;
  }

  function neighbors(objects) {
    var indexesByArc = {},
        // arc index -> array of object indexes
    neighbors = objects.map(function () {
      return [];
    });

    function line(arcs, i) {
      arcs.forEach(function (a) {
        if (a < 0) a = ~a;
        var o = indexesByArc[a];
        if (o) o.push(i);else indexesByArc[a] = [i];
      });
    }

    function polygon(arcs, i) {
      arcs.forEach(function (arc) {
        line(arc, i);
      });
    }

    function geometry(o, i) {
      if (o.type === "GeometryCollection") o.geometries.forEach(function (o) {
        geometry(o, i);
      });else if (o.type in geometryType) geometryType[o.type](o.arcs, i);
    }

    var geometryType = {
      LineString: line,
      MultiLineString: polygon,
      Polygon: polygon,
      MultiPolygon: function MultiPolygon(arcs, i) {
        arcs.forEach(function (arc) {
          polygon(arc, i);
        });
      }
    };

    objects.forEach(geometry);

    for (var i in indexesByArc) {
      for (var indexes = indexesByArc[i], m = indexes.length, j = 0; j < m; ++j) {
        for (var k = j + 1; k < m; ++k) {
          var ij = indexes[j],
              ik = indexes[k],
              n;
          if ((n = neighbors[ij])[i = bisect(n, ik)] !== ik) n.splice(i, 0, ik);
          if ((n = neighbors[ik])[i = bisect(n, ij)] !== ij) n.splice(i, 0, ij);
        }
      }
    }

    return neighbors;
  }

  function presimplify(topology, triangleArea) {
    var absolute = transformAbsolute(topology.transform),
        relative = transformRelative(topology.transform),
        heap = minAreaHeap();

    if (!triangleArea) triangleArea = cartesianTriangleArea;

    topology.arcs.forEach(function (arc) {
      var triangles = [],
          maxArea = 0,
          triangle;

      // To store each point鈥檚 effective area, we create a new array rather than
      // extending the passed-in point to workaround a Chrome/V8 bug (getting
      // stuck in smi mode). For midpoints, the initial effective area of
      // Infinity will be computed in the next step.
      for (var i = 0, n = arc.length, p; i < n; ++i) {
        p = arc[i];
        absolute(arc[i] = [p[0], p[1], Infinity], i);
      }

      for (var i = 1, n = arc.length - 1; i < n; ++i) {
        triangle = arc.slice(i - 1, i + 2);
        triangle[1][2] = triangleArea(triangle);
        triangles.push(triangle);
        heap.push(triangle);
      }

      for (var i = 0, n = triangles.length; i < n; ++i) {
        triangle = triangles[i];
        triangle.previous = triangles[i - 1];
        triangle.next = triangles[i + 1];
      }

      while (triangle = heap.pop()) {
        var previous = triangle.previous,
            next = triangle.next;

        // If the area of the current point is less than that of the previous point
        // to be eliminated, use the latter's area instead. This ensures that the
        // current point cannot be eliminated without eliminating previously-
        // eliminated points.
        if (triangle[1][2] < maxArea) triangle[1][2] = maxArea;else maxArea = triangle[1][2];

        if (previous) {
          previous.next = next;
          previous[2] = triangle[2];
          update(previous);
        }

        if (next) {
          next.previous = previous;
          next[0] = triangle[0];
          update(next);
        }
      }

      arc.forEach(relative);
    });

    function update(triangle) {
      heap.remove(triangle);
      triangle[1][2] = triangleArea(triangle);
      heap.push(triangle);
    }

    return topology;
  };

  function cartesianRingArea(ring) {
    var i = -1,
        n = ring.length,
        a,
        b = ring[n - 1],
        area = 0;

    while (++i < n) {
      a = b;
      b = ring[i];
      area += a[0] * b[1] - a[1] * b[0];
    }

    return area * .5;
  }

  function cartesianTriangleArea(triangle) {
    var a = triangle[0],
        b = triangle[1],
        c = triangle[2];
    return Math.abs((a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1]));
  }

  function compareArea(a, b) {
    return a[1][2] - b[1][2];
  }

  function minAreaHeap() {
    var heap = {},
        array = [],
        size = 0;

    heap.push = function (object) {
      up(array[object._ = size] = object, size++);
      return size;
    };

    heap.pop = function () {
      if (size <= 0) return;
      var removed = array[0],
          object;
      if (--size > 0) object = array[size], down(array[object._ = 0] = object, 0);
      return removed;
    };

    heap.remove = function (removed) {
      var i = removed._,
          object;
      if (array[i] !== removed) return; // invalid request
      if (i !== --size) object = array[size], (compareArea(object, removed) < 0 ? up : down)(array[object._ = i] = object, i);
      return i;
    };

    function up(object, i) {
      while (i > 0) {
        var j = (i + 1 >> 1) - 1,
            parent = array[j];
        if (compareArea(object, parent) >= 0) break;
        array[parent._ = i] = parent;
        array[object._ = i = j] = object;
      }
    }

    function down(object, i) {
      while (true) {
        var r = i + 1 << 1,
            l = r - 1,
            j = i,
            child = array[j];
        if (l < size && compareArea(array[l], child) < 0) child = array[j = l];
        if (r < size && compareArea(array[r], child) < 0) child = array[j = r];
        if (j === i) break;
        array[child._ = i] = child;
        array[object._ = i = j] = object;
      }
    }

    return heap;
  }

  function transformAbsolute(transform) {
    if (!transform) return noop;
    var x0,
        y0,
        kx = transform.scale[0],
        ky = transform.scale[1],
        dx = transform.translate[0],
        dy = transform.translate[1];
    return function (point, i) {
      if (!i) x0 = y0 = 0;
      point[0] = (x0 += point[0]) * kx + dx;
      point[1] = (y0 += point[1]) * ky + dy;
    };
  }

  function transformRelative(transform) {
    if (!transform) return noop;
    var x0,
        y0,
        kx = transform.scale[0],
        ky = transform.scale[1],
        dx = transform.translate[0],
        dy = transform.translate[1];
    return function (point, i) {
      if (!i) x0 = y0 = 0;
      var x1 = (point[0] - dx) / kx | 0,
          y1 = (point[1] - dy) / ky | 0;
      point[0] = x1 - x0;
      point[1] = y1 - y0;
      x0 = x1;
      y0 = y1;
    };
  }

  function noop() {}

  return topojson;
}();

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();

var _csv = __webpack_require__(148);

var _csv2 = _interopRequireDefault(_csv);

var _utils = __webpack_require__(1);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

var CSVTimeInColumnsReader = _csv2.default.extend({

  _name: 'csv-time_in_columns',

  init: function init(readerInfo) {
    this._super(readerInfo);
  },
  load: function load() {
    var _this = this;

    return this._super().then(function (_ref) {
      var data = _ref.data,
          columns = _ref.columns;

      var indicatorKey = columns[_this.keySize];

      var concepts = data.reduce(function (result, row) {
        Object.keys(row).forEach(function (concept) {
          concept = concept === indicatorKey ? row[indicatorKey] : concept;

          if (Number(concept) != concept && !result.includes(concept)) {
            result.push(concept);
          }
        });

        return result;
      }, []);
      concepts.splice(1, 0, 'time');

      var indicators = concepts.slice(2);

      var _concepts = _slicedToArray(concepts, 1),
          entityDomain = _concepts[0];

      return {
        columns: concepts,
        data: data.reduce(function (result, row) {
          Object.keys(row).forEach(function (key) {
            if (![entityDomain, indicatorKey].includes(key)) {
              var _Object$assign;

              result.push(Object.assign((_Object$assign = {}, _defineProperty(_Object$assign, entityDomain, row[entityDomain]), _defineProperty(_Object$assign, 'time', key), _Object$assign), indicators.reduce(function (result, indicator) {
                result[indicator] = row[indicatorKey] === indicator ? row[key] : null;
                return result;
              }, {})));
            }
          });

          return result;
        }, [])
      };
    });
  }
});

exports.default = CSVTimeInColumnsReader;

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

"use strict";
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _reader = __webpack_require__(71);

var _reader2 = _interopRequireDefault(_reader);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/*!
 * Inline Reader
 * the simplest reader possible
 */

var InlineReader = _reader2.default.extend({
  init: function init(reader_info) {
    this.name = "inline";
    this._super(reader_info);
  }
});

exports.default = InlineReader;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _d = __webpack_require__(40);

var _d2 = _interopRequireDefault(_d);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

//BAR CHART COMPONENT
var AxisLabelerComponent = _component2.default.extend({

  /**
   * Initializes the component (Bar Chart).
   * Executed once before any template is rendered.
   * @param {Object} config The options passed to the component
   * @param {Object} context The component's parent
   */
  init: function init(config, context) {
    this.name = 'axislabeler';
    this.template = __webpack_require__(443);

    //define expected models for this component
    this.model_expects = [{ name: "scales" }, { name: "show" }];

    var _this = this;

    this.model_binds = {
      "change:scales": function changeScales(evt) {
        _this.initScales();
        _this.update();
      },
      'change:show': function changeShow(evt, path) {
        _this.initScales();
        _this.update();
      }
    };

    //contructor is the same as any component
    this._super(config, context);

    this.xScale = null;
    this.yScale = null;

    this.xAxis = (0, _d2.default)();
    this.yAxis = (0, _d2.default)();
  },

  /**
   * DOM is ready
   */
  readyOnce: function readyOnce() {
    var _this = this;
    this.element = d3.select(this.element);

    // reference elements
    this.graph = this.element.select('.vzb-al-graph');
    this.xAxisEl = this.graph.select('.vzb-al-axis-x');
    this.yAxisEl = this.graph.select('.vzb-al-axis-y');

    //$(".vzb-bc-axis-x, .vzb-bc-axis-y").css('font-size',this.model.show.labelSize);
    this.xInvert = function (d) {
      return _this.xScale(_this.xScale.invert(_this.xScale(d)));
    };
    this.yInvert = function (d) {
      return _this.yScale(_this.yScale.invert(_this.yScale(d)));
    };

    this.line = d3.svg.line().x(function (d) {
      return _this.xScale(d);
    }).y(function (d) {
      return _this.yScale(d);
    });

    this.lineInvert = d3.svg.line().x(function (d) {
      return _this.xInvert(d);
    }).y(function (d) {
      return _this.yInvert(d);
    });

    //component events
    this.on("resize", function () {
      _this.update();
    });
  },

  /*
   * Both model and DOM are ready
   */
  ready: function ready() {
    console.log("Model ready");
    this.initScales();
    this.update();
  },

  initScales: function initScales() {
    var _this = this;

    var domain = this.model.scales.domain;

    this.xScale = d3.scale[this.model.scales.xScaleType]();
    this.yScale = d3.scale[this.model.scales.yScaleType]();

    this.xScale.domain(domain);

    this.yScale.domain(domain);

    this.mockData = d3.range(domain[0], domain[domain.length - 1], (domain[domain.length - 1] - domain[0]) / 10000);
    this.mockData.push(domain[domain.length - 1]);
  },

  update: function update() {
    var _this = this;

    var margin = this.model.show.toolMargin.getPlainObject();

    //stage
    var height = parseInt(this.element.style("height"), 10) - margin.top - margin.bottom || 0;
    var width = parseInt(this.element.style("width"), 10) - margin.left - margin.right || 0;

    if (height <= 0 || width <= 0) return utils.warn("Axis Labeler update() call interrupted for Vizabi container is too little or has display:none");

    //graph group is shifted according to margins (while svg element is at 100 by 100%)
    this.graph.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    //update scales to the new range
    var xLength = this.xScale.domain().length;
    var yLength = this.yScale.domain().length;
    this.xScale.range(d3.range(xLength).map(function (n) {
      return width / (xLength - 1) * n;
    })); //.nice();
    this.yScale.range(d3.range(yLength).map(function (n) {
      return height / (yLength - 1) * n;
    }).reverse()); //.nice();

    this.xAxis.scale(this.xScale).orient("bottom").tickSize(6, 0).tickSizeMinor(3, 0).labelerOptions({
      scaleType: this.model.scales.xScaleType,
      toolMargin: margin
    });

    this.yAxis.scale(this.yScale).orient("left").tickSize(6, 0).tickSizeMinor(3, 0).labelerOptions({
      scaleType: this.model.scales.yScaleType,
      toolMargin: margin
    });

    this.xAxisEl.attr("transform", "translate(0," + height + ")");
    this.xAxisEl.call(this.xAxis);
    this.yAxisEl.call(this.yAxis);

    //TODO: remove. make font sizing through plain CSS
    //this.xAxisEl.selectAll("text").style('font-size',this.model.show.labelSize);
    //this.yAxisEl.selectAll("text").style('font-size',this.model.show.labelSize);


    var path = this.graph.selectAll(".vzb-al-line").data([0]);
    path.enter().append("path").attr("class", "vzb-al-line");
    path.datum(this.mockData).attr("d", this.line);

    var pathInvert = this.graph.selectAll(".vzb-al-line-invert").data([0]);
    pathInvert.enter().append("path").attr("class", "vzb-al-line-invert");
    pathInvert.datum(this.mockData).attr("d", this.lineInvert);

    var format = d3.format(".4r");

    var dots = this.graph.selectAll(".vzb-al-dots").data(this.mockData);
    dots.enter().append("circle").attr("class", "vzb-al-dots").attr("r", 5).on("mouseenter", function (d, i) {
      console.log("Point #" + i + ": " + d + " x=" + format(_this.xScale(d)) + " y=" + format(_this.yScale(d)));
    });
    dots.exit().remove();
    dots.attr("cx", function (d) {
      return _this.xScale(d);
    }).attr("cy", function (d) {
      return _this.yScale(d);
    });

    var dotsInvert = this.graph.selectAll(".vzb-al-dots-invert").data(this.mockData);
    dotsInvert.enter().append("circle").attr("class", "vzb-al-dots-invert").attr("r", 5).on("mouseenter", function (d, i) {
      console.log("Point #" + i + ": " + d + " x=" + format(_this.xScale(d)) + " y=" + format(_this.yScale(d)));
    });
    dotsInvert.exit().remove();
    dotsInvert.attr("cx", function (d) {
      return _this.xInvert(d);
    }).attr("cy", function (d) {
      return _this.yInvert(d);
    });
  }
});

exports.default = AxisLabelerComponent;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _d = __webpack_require__(40);

var _d2 = _interopRequireDefault(_d);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

//BAR CHART COMPONENT
var BarComponent = _component2.default.extend({

  /**
   * Initializes the component (Bar Chart).
   * Executed once before any template is rendered.
   * @param {Object} config The options passed to the component
   * @param {Object} context The component's parent
   */
  init: function init(config, context) {
    this.name = 'barchart';
    this.template = __webpack_require__(444);

    //define expected models for this component
    this.model_expects = [{
      name: "time",
      type: "time"
    }, {
      name: "entities",
      type: "entities"
    }, {
      name: "marker",
      type: "model"
    }, {
      name: "locale",
      type: "locale"
    }];

    var _this = this;

    this.model_binds = {
      "change:time.value": function changeTimeValue(evt) {
        _this.model.marker.getFrame(_this.model.time.value, function (values) {
          _this.values = values;
          _this.updateEntities();
        });
      },
      'change:marker': function changeMarker(evt, path) {
        if (!_this._readyOnce) return;
        if (path.indexOf("color.palette") > -1) return;
        if (path.indexOf("which") > -1 || path.indexOf("use") > -1) return;

        _this.ready();
      },
      'change:marker.color.palette': utils.debounce(function (evt) {
        if (!_this._readyOnce) return;
        _this.updateEntities();
      }, 200)
    };

    //contructor is the same as any component
    this._super(config, context);

    this.xScale = null;
    this.yScale = null;
    this.cScale = d3.scale.category10();

    this.xAxis = (0, _d2.default)();
    this.yAxis = (0, _d2.default)();
  },

  /**
   * DOM is ready
   */
  readyOnce: function readyOnce() {
    this.element = d3.select(this.element);

    this.graph = this.element.select('.vzb-bc-graph');
    this.yAxisEl = this.graph.select('.vzb-bc-axis-y');
    this.xAxisEl = this.graph.select('.vzb-bc-axis-x');
    this.yTitleEl = this.graph.select('.vzb-bc-axis-y-title');
    this.xTitleEl = this.graph.select('.vzb-bc-axis-x-title');
    this.bars = this.graph.select('.vzb-bc-bars');
    this.year = this.element.select('.vzb-bc-year');

    var _this = this;
    this.on("resize", function () {
      _this.updateEntities();
    });
  },

  /*
   * Both model and DOM are ready
   */
  ready: function ready() {
    var _this = this;
    this.model.marker.getFrame(this.model.time.value, function (values) {
      _this.values = values;
      _this.updateIndicators();
      _this.resize();
      _this.updateEntities();
    });
  },

  /**
   * Changes labels for indicators
   */
  updateIndicators: function updateIndicators() {

    var _this = this;
    this.translator = this.model.locale.getTFunction();
    this.duration = this.model.time.delayAnimations;

    var titleStringY = this.translator("indicator/" + this.model.marker.axis_y.which);
    var titleStringX = this.translator("indicator/" + this.model.marker.axis_x.which);

    var yTitle = this.yTitleEl.selectAll("text").data([0]);
    yTitle.enter().append("text");
    yTitle.attr("y", "-6px").attr("x", "-9px").attr("dx", "-0.72em").text(titleStringY).on("click", function () {
      //TODO: Optimise updateView
      _this.parent.findChildByName("gapminder-treemenu").markerID("axis_y").alignX("left").alignY("top").updateView().toggle();
    });

    var xTitle = this.xTitleEl.selectAll("text").data([0]);
    xTitle.enter().append("text");
    xTitle.attr("y", "-3px").attr("dx", "-0.72em").text(titleStringX).on("click", function () {
      //TODO: Optimise updateView
      _this.parent.findChildByName("gapminder-treemenu").markerID("axis_x").alignY("bottom").alignX("center").updateView().toggle();
    });

    this.yScale = this.model.marker.axis_y.getScale();
    this.xScale = this.model.marker.axis_x.getScale();
    this.cScale = this.model.marker.color.getScale();

    var xFormatter = this.model.marker.axis_x.which == "geo.world_4region" ? function (x) {
      return _this.translator("entity/geo.world_4region/" + x);
    } : _this.model.marker.axis_x.getTickFormatter();

    this.yAxis.tickFormat(_this.model.marker.axis_y.getTickFormatter());
    this.xAxis.tickFormat(xFormatter);
  },

  /**
   * Updates entities
   */
  updateEntities: function updateEntities() {

    var _this = this;
    var time = this.model.time;
    var timeDim = time.getDimension();
    var entityDim = this.model.entities.getDimension();
    var duration = time.playing ? time.delayAnimations : 0;
    var filter = {};
    filter[timeDim] = time.value;
    var items = this.model.marker.getKeys(filter);

    this.entityBars = this.bars.selectAll('.vzb-bc-bar').data(items);

    //exit selection
    this.entityBars.exit().remove();

    //enter selection -- init circles
    this.entityBars.enter().append("rect").attr("class", "vzb-bc-bar").on("mousemove", function (d, i) {}).on("mouseout", function (d, i) {}).on("click", function (d, i) {});

    //positioning and sizes of the bars

    var bars = this.bars.selectAll('.vzb-bc-bar');
    var barWidth = this.xScale.rangeBand();

    this.bars.selectAll('.vzb-bc-bar').attr("width", barWidth).attr("fill", function (d) {
      return _this.cScale(_this.values.color[d[entityDim]]);
    }).attr("x", function (d) {
      return _this.xScale(_this.values.axis_x[d[entityDim]]);
    }).transition().duration(duration).ease("linear").attr("y", function (d) {
      return _this.yScale(_this.values.axis_y[d[entityDim]]);
    }).attr("height", function (d) {
      return _this.height - _this.yScale(_this.values.axis_y[d[entityDim]]);
    });
    this.year.text(this.model.time.formatDate(this.model.time.value));
  },

  /**
   * Executes everytime the container or vizabi is resized
   * Ideally,it contains only operations related to size
   */
  resize: function resize() {

    var _this = this;

    this.profiles = {
      "small": {
        margin: {
          top: 30,
          right: 20,
          left: 40,
          bottom: 50
        },
        padding: 2,
        minRadius: 2,
        maxRadius: 40
      },
      "medium": {
        margin: {
          top: 30,
          right: 60,
          left: 60,
          bottom: 60
        },
        padding: 2,
        minRadius: 3,
        maxRadius: 60
      },
      "large": {
        margin: {
          top: 30,
          right: 60,
          left: 60,
          bottom: 80
        },
        padding: 2,
        minRadius: 4,
        maxRadius: 80
      }
    };

    this.activeProfile = this.profiles[this.getLayoutProfile()];
    var margin = this.activeProfile.margin;

    //stage
    this.height = parseInt(this.element.style("height"), 10) - margin.top - margin.bottom || 0;
    this.width = parseInt(this.element.style("width"), 10) - margin.left - margin.right || 0;

    if (this.height <= 0 || this.width <= 0) return utils.warn("Bar chart resize() abort: vizabi container is too little or has display:none");

    this.graph.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    //update scales to the new range
    if (this.model.marker.axis_y.scaleType !== "ordinal") {
      this.yScale.range([this.height, 0]);
    } else {
      this.yScale.rangePoints([this.height, 0], _this.activeProfile.padding).range();
    }
    if (this.model.marker.axis_x.scaleType !== "ordinal") {
      this.xScale.range([0, this.width]);
    } else {
      this.xScale.rangePoints([0, this.width], _this.activeProfile.padding).range();
    }

    //apply scales to axes and redraw
    this.yAxis.scale(this.yScale).orient("left").tickSize(6, 0).tickSizeMinor(3, 0).labelerOptions({
      scaleType: this.model.marker.axis_y.scaleType,
      timeFormat: this.model.time.getFormatter(),
      toolMargin: { top: 5, right: margin.right, left: margin.left, bottom: margin.bottom },
      limitMaxTickNumber: 6
    });

    this.xAxis.scale(this.xScale).orient("bottom").tickSize(6, 0).tickSizeMinor(3, 0).labelerOptions({
      scaleType: this.model.marker.axis_x.scaleType,
      timeFormat: this.model.time.getFormatter(),
      toolMargin: margin,
      viewportLength: this.width
    });

    this.xAxisEl.attr("transform", "translate(0," + this.height + ")").call(this.xAxis);

    this.xScale.rangeRoundBands([0, this.width], .1, .2);

    this.yAxisEl.call(this.yAxis);
    this.xAxisEl.call(this.xAxis);

    var xAxisSize = this.xAxisEl.node().getBoundingClientRect();
    var xTitleSize = this.xTitleEl.node().getBoundingClientRect();
    var xTitleXPos = xAxisSize.width / 2 - xTitleSize.width / 2;
    var xTitleYPos = this.height + xAxisSize.height + xTitleSize.height;
    this.xTitleEl.attr("transform", "translate(" + xTitleXPos + "," + xTitleYPos + ")");
    this.year.attr('x', this.width).attr('y', 0);
  }
});

exports.default = BarComponent;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _d = __webpack_require__(40);

var _d2 = _interopRequireDefault(_d);

var _iconset = __webpack_require__(10);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

var COLOR_BLACKISH = "#333";
var COLOR_WHITEISH = "#fdfdfd";

var BarRankChart = _component2.default.extend({

  /**
   * Initializes the component (Bar Chart).
   * Executed once before any template is rendered.
   * @param {Object} config The config passed to the component
   * @param {Object} context The component's parent
   */
  init: function init(config, context) {
    var _this2 = this;

    this.name = 'barrankchart-component';
    this.template = __webpack_require__(445);

    //define expected models for this component
    this.model_expects = [{
      name: 'time',
      type: 'time'
    }, {
      name: 'entities',
      type: 'entities'
    }, {
      name: 'marker',
      type: 'model'
    }, {
      name: 'locale',
      type: 'locale'
    }, {
      name: 'ui',
      type: 'ui'
    }];

    this.model_binds = {
      'change:time.value': function changeTimeValue() {
        if (_this2._readyOnce) {
          _this2.onTimeChange();
        }
      },
      'change:marker.select': function changeMarkerSelect() {
        if (_this2._readyOnce) {
          _this2._selectBars();
          _this2._updateOpacity();
          _this2._updateDoubtOpacity();
          _this2._scroll();
        }
      },
      'change:marker.axis_x.scaleType': function changeMarkerAxis_xScaleType() {
        if (_this2._readyOnce) {
          _this2.loadData();
          _this2.draw(true);
        }
      },
      'change:marker.color.palette': function changeMarkerColorPalette() {
        _this2._drawColors();
      },
      'change:marker.highlight': function changeMarkerHighlight() {
        _this2._updateOpacity();
      },
      'change:marker.opacitySelectDim': function changeMarkerOpacitySelectDim() {
        _this2._updateOpacity();
      },
      'change:marker.opacityRegular': function changeMarkerOpacityRegular() {
        _this2._updateOpacity();
      }
    };

    //contructor is the same as any component
    this._super(config, context);

    // set up the scales
    this.xScale = null;
    this.cScale = d3.scale.category10();

    // set up the axes
    this.xAxis = (0, _d2.default)();
  },
  onTimeChange: function onTimeChange() {
    var _this3 = this;

    this.model.marker.getFrame(this.model.time.value, function (values) {
      _this3.values = values;
      _this3.loadData();
      _this3.draw();
    });
  },


  /**
   * DOM and model are ready
   */
  readyOnce: function readyOnce() {
    this.element = d3.select(this.element);

    // reference elements
    //this.graph = this.element.select('.vzb-br-graph');
    //this.yearEl = this.element.select('.vzb-br-year');
    //this.year = new DynamicBackground(this.yearEl);
    this.header = this.element.select('.vzb-br-header');
    this.infoEl = this.element.select('.vzb-br-axis-info');
    this.barViewport = this.element.select('.vzb-br-barsviewport');
    this.barSvg = this.element.select('.vzb-br-bars-svg');
    this.barContainer = this.element.select('.vzb-br-bars');
    this.dataWarningEl = this.element.select('.vzb-data-warning');
    this.wScale = d3.scale.linear().domain(this.model.ui.datawarning.doubtDomain).range(this.model.ui.datawarning.doubtRange);

    // set up formatters
    this.xAxis.tickFormat(this.model.marker.axis_x.getTickFormatter());

    this._presentation = !this.model.ui.presentation;
    this._formatter = this.model.marker.axis_x.getTickFormatter();

    this.ready();

    this._selectBars();
  },


  /**
   * Both model and DOM are ready
   */
  ready: function ready() {
    var _this4 = this;

    this.model.marker.getFrame(this.model.time.value, function (values) {

      _this4.values = values;
      _this4.loadData();
      _this4.draw(true);
      _this4._updateOpacity();
      _this4._drawColors();
    });
  },
  resize: function resize() {
    this.draw(true);
  },
  loadData: function loadData() {
    var _this5 = this;

    var _this = this;

    this.translator = this.model.locale.getTFunction();
    // sort the data (also sets this.total)
    this.sortedEntities = this._sortByIndicator(this.values.axis_x);

    this.header.select('.vzb-br-title').select('text').on('click', function () {
      return _this5.parent.findChildByName('gapminder-treemenu').markerID('axis_x').alignX('left').alignY('top').updateView().toggle();
    });

    // new scales and axes
    this.xScale = this.model.marker.axis_x.getScale();
    this.cScale = this.model.marker.color.getScale();

    utils.setIcon(this.dataWarningEl, _iconset.warn).select('svg').attr('width', 0).attr('height', 0);

    this.dataWarningEl.append('text').text(this.translator('hints/dataWarning'));

    this.dataWarningEl.on('click', function () {
      return _this5.parent.findChildByName('gapminder-datawarning').toggle();
    }).on('mouseover', function () {
      return _this5._updateDoubtOpacity(1);
    }).on('mouseout', function () {
      return _this5._updateDoubtOpacity();
    });

    utils.setIcon(this.infoEl, _iconset.question).select('svg').attr('width', 0).attr('height', 0);

    this.infoEl.on('click', function () {
      _this5.parent.findChildByName('gapminder-datanotes').pin();
    });

    this.infoEl.on('mouseover', function () {
      var rect = this.getBBox();
      var ctx = utils.makeAbsoluteContext(this, this.farthestViewportElement);
      var coord = ctx(rect.x - 10, rect.y + rect.height + 10);
      _this.parent.findChildByName('gapminder-datanotes').setHook('axis_y').show().setPos(coord.x, coord.y);
    });

    this.infoEl.on('mouseout', function () {
      _this.parent.findChildByName('gapminder-datanotes').hide();
    });
  },
  draw: function draw() {
    var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;

    this.time_1 = this.time == null ? this.model.time.value : this.time;
    this.time = this.model.time.value;
    //smooth animation is needed when playing, except for the case when time jumps from end to start
    var duration = this.model.time.playing && this.time - this.time_1 > 0 ? this.model.time.delayAnimations : 0;

    //return if drawAxes exists with error
    if (this.drawAxes(duration, force)) return;
    this.drawData(duration, force);
  },


  /*
   * draw the chart/stage
   */
  drawAxes: function drawAxes() {
    var duration = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;

    var profiles = {
      small: {
        margin: { top: 60, right: 5, left: 5, bottom: 20 },
        headerMargin: { top: 10, right: 20, bottom: 20, left: 20 },
        infoElHeight: 16,
        infoElMargin: 5,
        barHeight: 18,
        barMargin: 3,
        barRectMargin: 5,
        barValueMargin: 5,
        scrollMargin: 20
      },
      medium: {
        margin: { top: 60, right: 5, left: 5, bottom: 20 },
        headerMargin: { top: 10, right: 20, bottom: 20, left: 20 },
        infoElHeight: 16,
        infoElMargin: 5,
        barHeight: 21,
        barMargin: 3,
        barRectMargin: 5,
        barValueMargin: 5,
        scrollMargin: 25
      },
      large: {
        margin: { top: 60, right: 5, left: 5, bottom: 20 },
        headerMargin: { top: 10, right: 20, bottom: 20, left: 20 },
        infoElHeight: 16,
        infoElMargin: 5,
        barHeight: 28,
        barMargin: 4,
        barRectMargin: 5,
        barValueMargin: 5,
        scrollMargin: 25
      }
    };

    var presentationProfileChanges = {
      medium: {
        margin: { top: 60, right: 10, left: 10, bottom: 40 },
        headerMargin: { top: 10, right: 20, bottom: 20, left: 20 },
        infoElHeight: 25,
        infoElMargin: 10,
        barHeight: 25,
        barMargin: 6
      },
      large: {
        margin: { top: 60, right: 10, left: 10, bottom: 40 },
        headerMargin: { top: 10, right: 20, bottom: 20, left: 20 },
        infoElHeight: 16,
        infoElMargin: 10,
        barHeight: 30,
        barMargin: 6
      }
    };

    this.activeProfile = this.getActiveProfile(profiles, presentationProfileChanges);

    var _activeProfile = this.activeProfile,
        margin = _activeProfile.margin,
        headerMargin = _activeProfile.headerMargin,
        infoElHeight = _activeProfile.infoElHeight,
        infoElMargin = _activeProfile.infoElMargin;


    this.height = +this.element.style('height').replace('px', '');
    this.width = +this.element.style('width').replace('px', '');

    this.barViewport.style('height', this.height - margin.bottom - margin.top + 'px');

    // header
    this.header.attr('height', margin.top);
    var headerTitle = this.header.select('.vzb-br-title');

    // change header titles for new data

    var _model$marker$axis_x$ = this.model.marker.axis_x.getConceptprops(),
        name = _model$marker$axis_x$.name,
        unit = _model$marker$axis_x$.unit;

    var headerTitleText = headerTitle.select('text');

    if (unit) {
      headerTitleText.text(name + ', ' + unit);

      var rightEdgeOfLeftText = headerMargin.left + headerTitle.node().getBBox().width + infoElMargin + infoElHeight;

      if (rightEdgeOfLeftText > this.width - headerMargin.right) {
        headerTitleText.text(name);
      }
    }

    var headerTitleBBox = headerTitle.node().getBBox();

    var titleTx = headerMargin.left;
    var titleTy = headerMargin.top + headerTitleBBox.height;
    headerTitle.attr('transform', 'translate(' + titleTx + ', ' + titleTy + ')');

    var headerInfo = this.infoEl;

    headerInfo.select('svg').attr('width', infoElHeight + 'px').attr('height', infoElHeight + 'px');

    var infoTx = titleTx + headerTitle.node().getBBox().width + infoElMargin;
    var infoTy = headerMargin.top + infoElHeight / 4;
    headerInfo.attr('transform', 'translate(' + infoTx + ', ' + infoTy + ')');

    var headerTotal = this.header.select('.vzb-br-total');

    if (duration) {
      headerTotal.select('text').transition('text').delay(duration).text(this.model.time.formatDate(this.time));
    } else {
      headerTotal.select('text').interrupt().text(this.model.time.formatDate(this.time));
    }
    headerTotal.style('opacity', Number(this.getLayoutProfile() !== 'large'));

    var headerTotalBBox = headerTotal.node().getBBox();

    var totalTx = this.width - headerMargin.right - headerTotalBBox.width;
    var totalTy = headerMargin.top + headerTotalBBox.height;
    headerTotal.attr('transform', 'translate(' + totalTx + ', ' + totalTy + ')').classed('vzb-transparent', headerTitleBBox.width + headerTotalBBox.width + 10 > this.width);

    this.element.select('.vzb-data-warning-svg').style('height', margin.bottom + 'px');

    var warningBBox = this.dataWarningEl.select('text').node().getBBox();
    this.dataWarningEl.attr('transform', 'translate(' + (this.width - margin.right - warningBBox.width) + ', ' + warningBBox.height + ')').select('text');

    this.dataWarningEl.select('svg').attr('width', warningBBox.height).attr('height', warningBBox.height).attr('x', -warningBBox.height - 5).attr('y', -warningBBox.height + 1);

    this._updateDoubtOpacity();
  },
  drawData: function drawData() {
    var _this6 = this;

    var duration = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
    var force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;

    // update the shown bars for new data-set
    this._createAndDeleteBars(this.barContainer.selectAll('.vzb-br-bar').data(this.sortedEntities, function (d) {
      return d.entity;
    }));

    var presentation = this.model.ui.presentation;

    var presentationModeChanged = this._presentation !== presentation;

    if (presentationModeChanged) {
      this._presentation = presentation;
    }

    var entitiesCountChanged = typeof this._entitiesCount === 'undefined' || this._entitiesCount !== this.sortedEntities.length;

    if (presentationModeChanged || entitiesCountChanged) {
      if (entitiesCountChanged) {
        this._entitiesCount = this.sortedEntities.length;
      }
      this._resizeSvg();
    }

    this._scroll(duration);

    var _activeProfile2 = this.activeProfile,
        barRectMargin = _activeProfile2.barRectMargin,
        barValueMargin = _activeProfile2.barValueMargin,
        scrollMargin = _activeProfile2.scrollMargin,
        margin = _activeProfile2.margin;
    var axis_x = this.model.marker.axis_x;

    var limits = axis_x.getLimits(axis_x.which);
    var ltr = Math.abs(limits.max) >= Math.abs(limits.min);

    var rightEdge = this.width - margin.right - margin.left - this._getWidestLabelWidth() - barRectMargin - scrollMargin;
    this.xScale.range([0, rightEdge]);

    var zeroValueWidth = this.xScale(0) || 0;
    var shift = this._getWidestLabelWidth();

    if (zeroValueWidth > (ltr ? margin.left : margin.right) + this._getWidestLabelWidth()) {
      shift = zeroValueWidth;
    }

    if (zeroValueWidth < 0) {
      this.xScale.range([0, rightEdge - Math.abs(zeroValueWidth)]);
      zeroValueWidth = this.xScale(0) || 0;
    }

    var barWidth = function barWidth(value) {
      return _this6.xScale(value) - zeroValueWidth;
    };

    var labelAnchor = ltr ? 'end' : 'start';
    var valueAnchor = ltr ? 'start' : 'end';

    var labelX = ltr ? margin.left + shift : this.width - shift - scrollMargin - margin.right;

    var barX = ltr ? labelX + barRectMargin : labelX - barRectMargin;

    var valueX = ltr ? barX + barValueMargin : barX - barValueMargin;

    var isLabelBig = this._getWidestLabelWidth(true) + (ltr ? margin.left : margin.right) < shift;
    this.sortedEntities.forEach(function (bar) {
      var value = bar.value;


      if (force || presentationModeChanged || bar.isNew) {
        bar.barLabel.attr('x', labelX).attr('y', _this6.activeProfile.barHeight / 2).attr('text-anchor', labelAnchor).text(isLabelBig ? bar.labelFull : bar.labelSmall);

        bar.barRect.attr('rx', _this6.activeProfile.barHeight / 4).attr('ry', _this6.activeProfile.barHeight / 4).attr('height', _this6.activeProfile.barHeight);

        bar.barValue.attr('x', valueX).attr('y', _this6.activeProfile.barHeight / 2).attr('text-anchor', valueAnchor);
      }

      if (force || bar.changedWidth || presentationModeChanged) {
        var width = Math.max(0, value && barWidth(Math.abs(value)));

        if (force || bar.changedWidth || presentationModeChanged) {
          bar.barRect.transition().duration(duration).ease('linear').attr('width', width);
        }

        bar.barRect.attr('x', barX - (value < 0 ? width : 0));

        if (force || bar.changedValue) {
          bar.barValue.text(_this6._formatter(value) || _this6.translator('hints/nodata'));
        }
      }

      if (force || bar.changedIndex || presentationModeChanged) {
        bar.self.transition().duration(duration).ease('linear').attr('transform', 'translate(0, ' + _this6._getBarPosition(bar.index) + ')');
      }
    });
  },
  _resizeSvg: function _resizeSvg() {
    var _activeProfile3 = this.activeProfile,
        barHeight = _activeProfile3.barHeight,
        barMargin = _activeProfile3.barMargin;

    this.barSvg.attr('height', (barHeight + barMargin) * this.sortedEntities.length + 'px');
  },
  _scroll: function _scroll() {
    var duration = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;

    var follow = this.barContainer.select('.vzb-selected');
    if (!follow.empty()) {
      var d = follow.datum();
      var yPos = this._getBarPosition(d.index);

      var margin = this.activeProfile.margin;

      var height = this.height - margin.top - margin.bottom;

      var scrollTo = yPos - (height + this.activeProfile.barHeight) / 2;
      this.barViewport.transition().duration(duration).tween('scrollfor' + d.entity, this._scrollTopTween(scrollTo));
    }
  },
  _createAndDeleteBars: function _createAndDeleteBars(updatedBars) {
    var _this = this;

    // remove groups for entities that are gone
    updatedBars.exit().remove();

    // make the groups for the entities which were not drawn yet (.data.enter() does this)
    updatedBars.enter().append('g').each(function (d) {
      var self = d3.select(this);

      self.attr('class', 'vzb-br-bar').classed('vzb-selected', _this.model.marker.isSelected(d)).attr('id', 'vzb-br-bar-' + d.entity + '-' + _this._id).on('mousemove', function (d) {
        return _this.model.marker.highlightMarker(d);
      }).on('mouseout', function () {
        return _this.model.marker.clearHighlighted();
      }).on('click', function (d) {
        _this.model.marker.selectMarker(d);
      });

      var barRect = self.append('rect').attr('stroke', 'transparent');

      var labelFull = _this.values.label[d.entity];
      var labelSmall = labelFull.length < 12 ? labelFull : labelFull.substring(0, 9) + '...';
      var barLabel = self.append('text').attr('class', 'vzb-br-label').attr('dominant-baseline', 'middle');

      var labelFullWidth = barLabel.text(labelFull).node().getBBox().width;
      var labelSmallWidth = barLabel.text(labelSmall).node().getBBox().width;

      var barValue = self.append('text').attr('class', 'vzb-br-value').attr('dominant-baseline', 'middle');

      Object.assign(d, {
        self: self,
        barRect: barRect,
        barLabel: barLabel,
        barValue: barValue,
        isNew: true,
        labelFullWidth: labelFullWidth,
        labelSmallWidth: labelSmallWidth,
        labelFull: labelFull,
        labelSmall: labelSmall
      });
    });
  },
  _getWidestLabelWidth: function _getWidestLabelWidth() {
    var big = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;

    var widthKey = big ? 'labelFullWidth' : 'labelSmallWidth';
    var labelKey = big ? 'labelFull' : 'labelSmall';

    var bar = this.sortedEntities.reduce(function (a, b) {
      return a[widthKey] < b[widthKey] ? b : a;
    });

    var text = bar.barLabel.text();
    var width = bar.barLabel.text(bar[labelKey]).node().getBBox().width;
    bar.barLabel.text(text);

    return width;
  },
  _drawColors: function _drawColors() {
    var _this7 = this;

    var _this = this;

    this.barContainer.selectAll('.vzb-br-bar>rect').each(function (_ref) {
      var entity = _ref.entity;

      var self = d3.select(this);
      var color = _this.values.color[entity];

      if (!color && color !== 0) {
        self.style('fill', COLOR_WHITEISH).attr('stroke', COLOR_BLACKISH);
      } else {
        self.style('fill', _this._getColor(color)).attr('stroke', 'transparent');
      }
    });

    this.barContainer.selectAll('.vzb-br-bar>text').style('fill', function (_ref2) {
      var entity = _ref2.entity;
      return _this7._getDarkerColor(_this7.values.color[entity]);
    });
  },
  _getColor: function _getColor(value) {
    return d3.rgb(this.cScale(value));
  },
  _getDarkerColor: function _getDarkerColor(d) {
    return this._getColor(d).darker(2);
  },


  /**
   * DATA HELPER FUNCTIONS
   */

  _scrollTopTween: function _scrollTopTween(scrollTop) {
    return function () {
      var i = d3.interpolateNumber(this.scrollTop, scrollTop);
      return function (t) {
        this.scrollTop = i(t);
      };
    };
  },
  _getBarPosition: function _getBarPosition(i) {
    return (this.activeProfile.barHeight + this.activeProfile.barMargin) * i;
  },


  _entities: {},

  _sortByIndicator: function _sortByIndicator(values) {
    var _this8 = this;

    return Object.keys(values).map(function (entity) {
      var _this8$_entities$enti;

      var cached = _this8._entities[entity];
      var value = values[entity];
      var formattedValue = _this8._formatter(value);

      if (cached) {
        return Object.assign(cached, {
          value: value,
          formattedValue: formattedValue,
          changedValue: formattedValue !== cached.formattedValue,
          changedWidth: value !== cached.value,
          isNew: false
        });
      }

      return _this8._entities[entity] = (_this8$_entities$enti = {
        entity: entity,
        value: value,
        formattedValue: formattedValue
      }, _defineProperty(_this8$_entities$enti, _this8.model.entities.dim, entity), _defineProperty(_this8$_entities$enti, 'changedValue', true), _defineProperty(_this8$_entities$enti, 'changedWidth', true), _defineProperty(_this8$_entities$enti, 'isNew', true), _this8$_entities$enti);
    }).sort(function (_ref3, _ref4) {
      var a = _ref3.value;
      var b = _ref4.value;
      return b - a;
    }).map(function (entity, index) {
      return Object.assign(entity, {
        index: index,
        changedIndex: index !== entity.index
      });
    });
  },
  _selectBars: function _selectBars() {
    var _this9 = this;

    var entityDim = this.model.entities.dim;
    var selected = this.model.marker.select;

    // unselect all bars
    this.barContainer.classed('vzb-dimmed-selected', false);
    this.barContainer.selectAll('.vzb-br-bar.vzb-selected').classed('vzb-selected', false);

    // select the selected ones
    if (selected.length) {
      this.barContainer.classed('vzb-dimmed-selected', true);
      selected.forEach(function (selectedBar) {
        _this9.barContainer.select('#vzb-br-bar-' + selectedBar[entityDim] + '-' + _this9._id).classed('vzb-selected', true);
      });
    }
  },
  _updateOpacity: function _updateOpacity() {
    var marker = this.model.marker;


    var OPACITY_HIGHLIGHT_DEFAULT = 1;
    var highlight = marker.highlight,
        select = marker.select,
        OPACITY_HIGHLIGHT_DIM = marker.opacityHighlightDim,
        OPACITY_SELECT_DIM = marker.opacitySelectDim,
        OPACITY_REGULAR = marker.opacityRegular;
    var someHighlighted = highlight.length > 0,
        someSelected = select.length > 0;


    this.barContainer.selectAll('.vzb-br-bar').style('opacity', function (d) {
      if (someHighlighted && marker.isHighlighted(d)) {
        return OPACITY_HIGHLIGHT_DEFAULT;
      }

      if (someSelected) {
        return marker.isSelected(d) ? OPACITY_REGULAR : OPACITY_SELECT_DIM;
      }

      if (someHighlighted) {
        return OPACITY_HIGHLIGHT_DIM;
      }

      return OPACITY_REGULAR;
    });
  },
  _updateDoubtOpacity: function _updateDoubtOpacity(opacity) {
    this.dataWarningEl.style('opacity', opacity || (!this.model.marker.select.length ? this.wScale(+this.model.time.value.getUTCFullYear().toString()) : 1));
  }
});

exports.default = BarRankChart;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _bubblechartTrail = __webpack_require__(221);

var _bubblechartTrail2 = _interopRequireDefault(_bubblechartTrail);

var _bubblechartPanzoom = __webpack_require__(220);

var _bubblechartPanzoom2 = _interopRequireDefault(_bubblechartPanzoom);

var _svgexport = __webpack_require__(136);

var _svgexport2 = _interopRequireDefault(_svgexport);

var _labels = __webpack_require__(86);

var _labels2 = _interopRequireDefault(_labels);

var _d = __webpack_require__(40);

var _d2 = _interopRequireDefault(_d);

var _d3 = __webpack_require__(66);

var _d4 = _interopRequireDefault(_d3);

var _iconset = __webpack_require__(10);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

//BUBBLE CHART COMPONENT
var BubbleChartComp = _component2.default.extend({

  /**
   * Initializes the component (Bubble Chart).
   * Executed once before any template is rendered.
   * @param {Object} config The config passed to the component
   * @param {Object} context The component's parent
   */
  init: function init(config, context) {
    var _this = this;
    this.name = 'bubblechart';
    this.template = __webpack_require__(446);

    //define expected models for this component
    this.model_expects = [{
      name: "time",
      type: "time"
    }, {
      name: "entities",
      type: "entities"
    }, {
      name: "marker",
      type: "model"
    }, {
      name: "locale",
      type: "locale"
    }, {
      name: "ui",
      type: "ui"
    }];

    this.model_binds = {
      'change:time.playing': function changeTimePlaying(evt, original) {
        if (utils.isTouchDevice() && _this.model.time.playing && _this.someHighlighted) {
          _this.model.marker.clearHighlighted();
        }
      },
      'change:time.start': function changeTimeStart(evt, original) {
        if (_this.model.marker.color.scaleType === 'time') {
          _this.model.marker.color.scale = null;
        }
        if (!_this._readyOnce || _this.model.time.splash) return;
        _this._trails.create().then(function () {
          _this._trails.run(["findVisible", "reveal", "opacityHandler"]);
        });
      },
      'change:time.end': function changeTimeEnd(evt, original) {
        if (!_this._readyOnce || _this.model.time.splash) return;
        _this._trails.create().then(function () {
          _this._trails.run(["findVisible", "reveal", "opacityHandler"]);
        });
      },
      "change:time.record": function changeTimeRecord() {
        //console.log("change time record");
        if (_this.model.time.record) {
          _this._export.open(this.element, this.name);
        } else {
          _this._export.reset();
        }
      },
      "change:ui.chart.trails": function changeUiChartTrails(evt) {
        //console.log("EVENT change:time:trails");
        _this._trails.toggle(_this.model.ui.chart.trails);
        _this.redrawDataPoints();
      },
      "change:ui.chart.lockNonSelected": function changeUiChartLockNonSelected(evt) {
        //console.log("EVENT change:time:lockNonSelected");
        _this.redrawDataPoints(500);
      },
      "change:marker": function changeMarker(evt, path) {
        // bubble size change is processed separately
        if (!_this._readyOnce) return;
        if (path.indexOf("scaleType") > -1) {
          _this.ready();
          return;
        }

        if (path.indexOf("marker.color") !== -1) return;
        if (path.indexOf("marker.size") !== -1) return;
        if (path.indexOf("marker.size_label") !== -1) return;

        if (path.indexOf("domainMin") > -1 || path.indexOf("domainMax") > -1) {
          if (!_this.yScale || !_this.xScale) return; //abort if building of the scale is in progress
          _this.updateSize();
          _this.updateMarkerSizeLimits();
          _this._trails.run("findVisible");
          _this.redrawDataPoints();
          _this._trails.run("resize", null, 500);
          return;
        }
        if (path.indexOf("zoomedMin") > -1 || path.indexOf("zoomedMax") > -1) {
          if (_this.draggingNow) return;

          //avoid zooming again if values didn't change.
          //also prevents infinite loop on forced URL update from zoom.stop()
          if (utils.approxEqual(_this._zoomedXYMinMax.axis_x.zoomedMin, _this.model.marker.axis_x.zoomedMin, 0.01) && utils.approxEqual(_this._zoomedXYMinMax.axis_x.zoomedMax, _this.model.marker.axis_x.zoomedMax, 0.01) && utils.approxEqual(_this._zoomedXYMinMax.axis_y.zoomedMin, _this.model.marker.axis_y.zoomedMin, 0.01) && utils.approxEqual(_this._zoomedXYMinMax.axis_y.zoomedMax, _this.model.marker.axis_y.zoomedMax, 0.01)) return;
          var playAfterZoom = false;
          if (_this.model.time.playing) {
            playAfterZoom = true;
            _this.model.time.pause(true);
          }
          _this._trails.run("abortAnimation");
          _this._panZoom.zoomToMaxMin(_this.model.marker.axis_x.zoomedMin, _this.model.marker.axis_x.zoomedMax, _this.model.marker.axis_y.zoomedMin, _this.model.marker.axis_y.zoomedMax, 500 /*duration*/, "don't feed these zoom values back to state");
          if (playAfterZoom) {
            _this.model.time.postponePause = false;
          }
          return;
        }

        //console.log("EVENT change:marker", evt);
      },
      "change:marker.select": function changeMarkerSelect(evt, path) {
        if (!_this._readyOnce || !_this.entityBubbles) return;
        //console.log("EVENT change:entities:select");

        //disable trails if too many items get selected at once
        //otherwise it's too much waiting time
        if ((evt.source._val || []).length - (evt.source._previousVal || []).length > 50) _this.model.ui.chart.trails = false;

        _this.selectDataPoints();
        _this.redrawDataPoints();
        _this._trails.create().then(function () {
          _this._trails.run(["findVisible", "reveal", "opacityHandler"]);
        });
        _this.updateBubbleOpacity();
        _this._updateDoubtOpacity();
      },
      "change:marker.highlight": function changeMarkerHighlight(evt, path) {
        if (!_this._readyOnce) return;
        //path have values if trail is highlighted
        if (path != 'highlight') {
          if (path !== null) {
            var titles = _this._formatSTitleValues(path.size, path.color);
            _this._updateSTitle(titles[0], titles[1]);
          } else {
            _this._updateSTitle();
          }
          return;
        }
        //console.log("EVENT change:entities:highlight");
        _this.highlightDataPoints();
      },
      'change:time.value': function changeTimeValue() {
        if (!_this._readyOnce || !_this.entityBubbles) return;
        if (!_this.calculationQueue) {
          // collect timestamp that we request
          _this.calculationQueue = [_this.model.time.value.toString()];
        } else {
          _this.calculationQueue.push(_this.model.time.value.toString());
        }
        (function (time) {
          // isolate timestamp
          //_this._bubblesInteract().mouseout();
          _this.model.marker.getFrame(time, function (frame, time) {
            if (!_this._frameIsValid(frame)) return utils.warn("change:time.value: empty data received from marker.getFrame(). doing nothing");
            var index = _this.calculationQueue.indexOf(time.toString()); //
            if (index == -1) {
              // we was receive more recent frame before so we pass this frame
              return;
            } else {
              _this.calculationQueue.splice(0, index + 1); // remove timestamps that added to queue before current timestamp
            }
            _this.frameChanged(frame, time);
          });
        })(_this.model.time.value);
      },
      'change:ui.adaptMinMaxZoom': function changeUiAdaptMinMaxZoom() {
        //console.log("EVENT change:ui:adaptMinMaxZoom");
        if (_this.model.ui.adaptMinMaxZoom) {
          _this._panZoom.expandCanvas(500);
        } else {
          _this._panZoom.reset();
        }
      },
      'change:marker.size.extent': function changeMarkerSizeExtent(evt, path) {
        //console.log("EVENT change:marker:size:max");
        if (!_this._readyOnce) return;
        _this.updateMarkerSizeLimits();
        _this.redrawDataPointsOnlySize();
        _this._trails.run("resize");
      },
      'change:marker.color': function changeMarkerColor(evt, path) {
        if (!_this._readyOnce) return;
        //console.log("EVENT change:marker:color:palette");
        _this.redrawDataPointsOnlyColors();
        _this._trails.run("recolor");
      },
      // 'change:marker.color.palette': function(evt, path) {
      //   if(!_this._readyOnce) return;
      //   //console.log("EVENT change:marker:color:palette");
      //   _this.redrawDataPointsOnlyColors();
      //   _this._trails.run("recolor");
      // },
      'change:marker.opacitySelectDim': function changeMarkerOpacitySelectDim() {
        _this.updateBubbleOpacity();
      },
      'change:marker.opacityRegular': function changeMarkerOpacityRegular() {
        _this.updateBubbleOpacity();
        _this._trails.run("opacityHandler");
      },
      'change:ui.cursorMode': function changeUiCursorMode() {
        var svg = _this.element.select("svg");
        if (_this.model.ui.cursorMode === "plus") {
          svg.classed("vzb-zoomin", true);
          svg.classed("vzb-zoomout", false);
        } else if (_this.model.ui.cursorMode === "minus") {
          svg.classed("vzb-zoomin", false);
          svg.classed("vzb-zoomout", true);
        } else {
          svg.classed("vzb-zoomin", false);
          svg.classed("vzb-zoomout", false);
        }
      },
      'ready': function ready() {
        // if(_this.model.marker.color.scaleType === 'time') {
        //   _this.model.marker.color.scale = null;
        //   utils.defer(function() {
        //     _this.trigger('ready');
        //   });
        // }
      }
    };

    this._super(config, context);

    this.xScale = null;
    this.yScale = null;
    this.sScale = null;
    this.cScale = null;

    this.xAxis = (0, _d2.default)();
    this.yAxis = (0, _d2.default)();

    _this.COLOR_BLACKISH = "#333";
    _this.COLOR_WHITEISH = "#fdfdfd";

    this.isCanvasPreviouslyExpanded = false;
    this.draggingNow = null;

    this._trails = new _bubblechartTrail2.default(this);
    this._panZoom = new _bubblechartPanzoom2.default(this);
    this._export = new _svgexport2.default(this);
    this._export.prefix("vzb-bc-").deleteClasses(["vzb-bc-bubbles-crop", "vzb-hidden", "vzb-bc-year", "vzb-bc-zoom-rect", "vzb-bc-projection-x", "vzb-bc-projection-y", "vzb-bc-axis-c-title"]);
    this._labels = new _labels2.default(this);
    this._labels.config({
      CSS_PREFIX: 'vzb-bc',
      LABELS_CONTAINER_CLASS: 'vzb-bc-labels',
      LINES_CONTAINER_CLASS: 'vzb-bc-bubbles',
      LINES_CONTAINER_SELECTOR_PREFIX: 'bubble-'
    });
  },

  _rangeBump: function _rangeBump(arg, undo) {
    var bump = this.activeProfile.maxRadius / 2;
    undo = undo ? -1 : 1;
    if (utils.isArray(arg) && arg.length > 1) {
      var z1 = arg[0];
      var z2 = arg[arg.length - 1];

      //the sign of bump depends on the direction of the scale
      if (z1 < z2) {
        z1 += bump * undo;
        z2 -= bump * undo;
        // if the scale gets inverted because of bump, set it to avg between z1 and z2
        if (z1 > z2) z1 = z2 = (z1 + z2) / 2;
      } else if (z1 > z2) {
        z1 -= bump * undo;
        z2 += bump * undo;
        // if the scale gets inverted because of bump, set it to avg between z1 and z2
        if (z1 < z2) z1 = z2 = (z1 + z2) / 2;
      } else {
        utils.warn("rangeBump error: the input scale range has 0 length. that sucks");
      }
      return [z1, z2];
    } else {
      utils.warn("rangeBump error: input is not an array or empty");
    }
  },

  //  _marginUnBump: function(arg) {
  //    var bump = this.profiles[this.getLayoutProfile()].maxRadius/2;
  //    if(utils.isObject(arg)) {
  //      return {
  //        left: arg.left - bump,
  //        right: arg.right - bump,
  //        top: arg.top - bump,
  //        bottom: arg.bottom - bump
  //      };
  //    } else {
  //      utils.warn("marginUnBump error: input is not an object {left top bottom right}");
  //    }
  //  },


  /**
   * Executes right after the template is in place, but the model is not yet ready
   */
  readyOnce: function readyOnce() {
    var _this = this;
    this._readyOnce = false;
    this.scrollableAncestor = utils.findScrollableAncestor(this.element);
    this.element = d3.select(this.element);

    // reference elements
    this.graph = this.element.select('.vzb-bc-graph');
    this.yAxisElContainer = this.graph.select('.vzb-bc-axis-y');
    this.yAxisEl = this.yAxisElContainer.select('g');

    this.xAxisElContainer = this.graph.select('.vzb-bc-axis-x');
    this.xAxisEl = this.xAxisElContainer.select('g');

    this.yTitleEl = this.graph.select('.vzb-bc-axis-y-title');
    this.xTitleEl = this.graph.select('.vzb-bc-axis-x-title');
    this.sTitleEl = this.graph.select('.vzb-bc-axis-s-title');
    this.cTitleEl = this.graph.select('.vzb-bc-axis-c-title');
    this.yearEl = this.graph.select('.vzb-bc-year');

    this.year = new _d4.default(this.yearEl);

    this.yInfoEl = this.graph.select('.vzb-bc-axis-y-info');
    this.xInfoEl = this.graph.select('.vzb-bc-axis-x-info');
    this.dataWarningEl = this.graph.select('.vzb-data-warning');

    this.projectionX = this.graph.select(".vzb-bc-projection-x");
    this.projectionY = this.graph.select(".vzb-bc-projection-y");
    this.lineEqualXY = this.graph.select(".vzb-bc-line-equal-xy");

    this.trailsContainer = this.graph.select('.vzb-bc-trails');
    this.bubbleContainerCrop = this.graph.select('.vzb-bc-bubbles-crop');
    this.labelsContainerCrop = this.graph.select('.vzb-bc-labels-crop');
    this.bubbleContainer = this.graph.select('.vzb-bc-bubbles');
    this.labelsContainer = this.graph.select('.vzb-bc-labels');
    this.linesContainer = this.graph.select('.vzb-bc-lines');
    this.zoomRect = this.element.select('.vzb-bc-zoom-rect');
    this.eventArea = this.element.select('.vzb-bc-eventarea');

    this.entityBubbles = null;
    this.bubbleCrown = this.element.select('.vzb-bc-bubble-crown');
    //set filter
    this.bubbleCrown.selectAll(".vzb-crown-glow").attr("filter", "url(" + location.pathname + "#vzb-glow-filter)");
    this.tooltip = this.element.select('.vzb-bc-tooltip');
    //set filter
    this.tooltip.select(".vzb-tooltip-glow").attr("filter", "url(" + location.pathname + "#vzb-glow-filter)");

    this.tooltipMobile = this.element.select('.vzb-tooltip-mobile');
    //component events
    this.on("resize", function () {
      //console.log("EVENT: resize");
      //return if updatesize exists with error
      _this._trails.run("abortAnimation");
      if (_this.updateSize()) return;
      _this.updateMarkerSizeLimits();
      _this._labels.updateSize();
      (function (xMin, xMax, yMin, yMax) {
        _this._panZoom.zoomer.dontFeedToState = true;
        _this._panZoom.rerun(); // includes redraw data points and trail resize
        _this._panZoom.zoomToMaxMin(xMin, xMax, yMin, yMax, 0, true);
      })(_this._zoomedXYMinMax.axis_x.zoomedMin, _this._zoomedXYMinMax.axis_x.zoomedMax, _this._zoomedXYMinMax.axis_y.zoomedMin, _this._zoomedXYMinMax.axis_y.zoomedMax);
    });

    //keyboard listeners
    d3.select("body").on("keydown", function () {
      if (_this.model.ui.cursorMode !== 'arrow') return;
      if (d3.event.metaKey || d3.event.ctrlKey) _this.element.select("svg").classed("vzb-zoomin", true);
    }).on("keyup", function () {
      if (_this.model.ui.cursorMode !== 'arrow') return;
      if (!d3.event.metaKey && !d3.event.ctrlKey) _this.element.select("svg").classed("vzb-zoomin", false);
    })
    //this is for the case when user would press ctrl and move away from the browser tab or window
    //keyup event would happen somewhere else and won't be captured, so zoomin class would get stuck
    .on("mouseenter", function () {
      if (_this.model.ui.cursorMode !== 'arrow') return;
      if (!d3.event.metaKey && !d3.event.ctrlKey) _this.element.select("svg").classed("vzb-zoomin", false);
    });

    this.root.on('resetZoom', function () {
      _this._panZoom.reset(null, 500);
    });

    this.bubbleContainerCrop.call(this._panZoom.zoomer).call(this._panZoom.dragRectangle).on('dblclick.zoom', null).on("mouseup", function () {
      _this.draggingNow = false;
    }).on("click", function () {
      var cursor = _this.model.ui.cursorMode;
      if (!d3.event.defaultPrevented && cursor !== "arrow") {
        _this._panZoom.zoomByIncrement(cursor, 500);
      }
    });

    this.KEY = this.model.entities.getDimension();
    this.TIMEDIM = this.model.time.getDimension();

    this.updateUIStrings();

    this.wScale = d3.scale.linear().domain(this.model.ui.datawarning.doubtDomain).range(this.model.ui.datawarning.doubtRange);

    this._labels.readyOnce();

    _this._readyOnce = true;
  },

  _frameIsValid: function _frameIsValid(frame) {
    return !(!frame || Object.keys(frame.axis_y).length === 0 || Object.keys(frame.axis_x).length === 0 || Object.keys(frame.size).length === 0);
  },

  ready: function ready() {
    var _this = this;
    this.updateUIStrings();
    var endTime = this.model.time.end;
    this.updateIndicators();
    this.updateTime();
    if (!_this.model.time.splash) {
      _this._trails.create();
    }
    this.model.marker.getFrame(this.model.time.value, function (frame, time) {
      // TODO: temporary fix for case when after data loading time changed on validation
      if (time.toString() != _this.model.time.value.toString()) {
        utils.defer(function () {
          _this.ready();
        });
        return;
      }
      if (!_this._frameIsValid(frame)) return utils.warn("ready: empty data received from marker.getFrame(). doing nothing");

      _this.frame = frame;
      _this.updateSize();
      _this.updateMarkerSizeLimits();
      _this.updateEntities();
      _this._labels.ready();
      _this.redrawDataPoints();
      _this.selectDataPoints();
      _this.updateBubbleOpacity();
      _this._updateDoubtOpacity();
      _this.zoomToMarkerMaxMin(); // includes redraw data points and trail resize
      if (!_this.model.time.splash) {
        _this._trails.run(["findVisible", "reveal", "opacityHandler"]);
      }
      if (_this.model.ui.adaptMinMaxZoom) _this._panZoom.expandCanvas();
    });
  },

  /*
   * Zoom to the min and max values given in the URL axes markers.
   */
  zoomToMarkerMaxMin: function zoomToMarkerMaxMin() {
    /*
     * Reset just the zoom values without triggering a zoom event. This ensures
     * a clean zoom state for the subsequent zoom event.
     */
    this._panZoom.resetZoomState();

    var xAxis = this.model.marker.axis_x;
    var yAxis = this.model.marker.axis_y;

    var xDomain = xAxis.getScale().domain();
    var yDomain = yAxis.getScale().domain();

    /*
     * The axes may return null when there is no value given for the zoomed
     * min and max values. In that case, fall back to the axes' domain values.
     */
    var zoomedMinX = xAxis.zoomedMin ? xAxis.zoomedMin : xDomain[0];
    var zoomedMaxX = xAxis.zoomedMax ? xAxis.zoomedMax : xDomain[1];
    var zoomedMinY = yAxis.zoomedMin ? yAxis.zoomedMin : yDomain[0];
    var zoomedMaxY = yAxis.zoomedMax ? yAxis.zoomedMax : yDomain[1];

    //by default this will apply no transition and feed values back to state
    this._panZoom.zoomToMaxMin(zoomedMinX, zoomedMaxX, zoomedMinY, zoomedMaxY, 0, "don't feed these zoom values back to state");
  },

  /*
   * UPDATE INDICATORS
   */
  updateIndicators: function updateIndicators() {
    var _this = this;

    //scales
    this.yScale = this.model.marker.axis_y.getScale();
    this.xScale = this.model.marker.axis_x.getScale();
    this.sScale = this.model.marker.size.getScale();
    this.cScale = this.model.marker.color.getScale();
    this._labels.setScales(this.xScale, this.yScale);

    this.yAxis.tickFormat(_this.model.marker.axis_y.getTickFormatter());
    this.xAxis.tickFormat(_this.model.marker.axis_x.getTickFormatter());
  },

  frameChanged: function frameChanged(frame, time) {
    //    if (time.toString() != this.model.time.value.toString()) return; // frame is outdated
    this.frame = frame;
    this.updateTime();

    this._updateDoubtOpacity();
    this._trails.run("findVisible");
    if (this.model.ui.adaptMinMaxZoom) {
      this._panZoom.expandCanvas();
    } else {
      this.redrawDataPoints();
    }
    this._trails.run("reveal", null, this.duration);
    this.tooltipMobile.classed('vzb-hidden', true);
    this._reorderEntities();
  },

  updateUIStrings: function updateUIStrings() {
    var _this = this;

    var conceptPropsY = _this.model.marker.axis_y.getConceptprops();
    var conceptPropsX = _this.model.marker.axis_x.getConceptprops();
    var conceptPropsS = _this.model.marker.size.getConceptprops();
    var conceptPropsC = _this.model.marker.color.getConceptprops();
    this.translator = this.model.locale.getTFunction();

    this.strings = {
      title: {
        Y: conceptPropsY.name,
        X: conceptPropsX.name,
        S: conceptPropsS.name,
        C: conceptPropsC.name
      },
      unit: {
        Y: conceptPropsY.unit || "",
        X: conceptPropsX.unit || "",
        S: conceptPropsS.unit || "",
        C: conceptPropsC.unit || ""
      }
    };

    var yTitle = this.yTitleEl.selectAll("text").data([0]);
    yTitle.enter().append("text");
    yTitle
    //.attr("y", "-6px")
    .on("click", function () {
      _this.parent.findChildByName("gapminder-treemenu").markerID("axis_y").alignX(_this.model.locale.isRTL() ? "right" : "left").alignY("top").updateView().toggle();
    });

    var xTitle = this.xTitleEl.selectAll("text").data([0]);
    xTitle.enter().append("text");
    xTitle.on("click", function () {
      _this.parent.findChildByName("gapminder-treemenu").markerID("axis_x").alignX(_this.model.locale.isRTL() ? "right" : "left").alignY("bottom").updateView().toggle();
    });

    var sTitle = this.sTitleEl.selectAll("text").data([0]);
    sTitle.enter().append("text");
    sTitle.attr("text-anchor", "end");

    utils.setIcon(this.dataWarningEl, _iconset.warn).select("svg").attr("width", "0px").attr("height", "0px");
    this.dataWarningEl.append("text").attr("text-anchor", "end").text(this.translator("hints/dataWarning"));

    utils.setIcon(this.yInfoEl, _iconset.question).select("svg").attr("width", "0px").attr("height", "0px");

    utils.setIcon(this.xInfoEl, _iconset.question).select("svg").attr("width", "0px").attr("height", "0px");

    //TODO: move away from UI strings, maybe to ready or ready once
    this.yInfoEl.on("click", function () {
      _this.parent.findChildByName("gapminder-datanotes").pin();
    });
    this.yInfoEl.on("mouseover", function () {
      var rect = this.getBBox();
      var coord = utils.makeAbsoluteContext(this, this.farthestViewportElement)(rect.x - 10, rect.y + rect.height + 10);
      var toolRect = _this.root.element.getBoundingClientRect();
      var chartRect = _this.element.node().getBoundingClientRect();
      _this.parent.findChildByName("gapminder-datanotes").setHook('axis_y').show().setPos(coord.x + chartRect.left - toolRect.left, coord.y);
    });
    this.yInfoEl.on("mouseout", function () {
      _this.parent.findChildByName("gapminder-datanotes").hide();
    });
    this.xInfoEl.on("click", function () {
      _this.parent.findChildByName("gapminder-datanotes").pin();
    });
    this.xInfoEl.on("mouseover", function () {
      if (_this.model.time.dragging) return;
      var rect = this.getBBox();
      var coord = utils.makeAbsoluteContext(this, this.farthestViewportElement)(rect.x - 10, rect.y + rect.height + 10);
      var toolRect = _this.root.element.getBoundingClientRect();
      var chartRect = _this.element.node().getBoundingClientRect();
      _this.parent.findChildByName("gapminder-datanotes").setHook('axis_x').show().setPos(coord.x + chartRect.left - toolRect.left, coord.y);
    });
    this.xInfoEl.on("mouseout", function () {
      if (_this.model.time.dragging) return;
      _this.parent.findChildByName("gapminder-datanotes").hide();
    });
    this.dataWarningEl.on("click", function () {
      _this.parent.findChildByName("gapminder-datawarning").toggle();
    }).on("mouseover", function () {
      _this._updateDoubtOpacity(1);
    }).on("mouseout", function () {
      _this._updateDoubtOpacity();
    });
  },

  _updateDoubtOpacity: function _updateDoubtOpacity(opacity) {
    if (opacity == null) opacity = this.wScale(+this.model.time.formatDate(this.time));
    if (this.someSelected) opacity = 1;
    this.dataWarningEl.style("opacity", opacity);
  },

  /*
   * UPDATE ENTITIES:
   * Ideally should only update when show parameters change or data changes
   */
  updateEntities: function updateEntities() {
    var _this = this;
    var KEY = this.KEY;
    var TIMEDIM = this.TIMEDIM;

    var getKeys = function getKeys(prefix) {
      prefix = prefix || "";
      return _this.model.marker.getKeys().map(function (d) {
        var pointer = {};
        pointer[KEY] = d[KEY];
        pointer[TIMEDIM] = endTime;
        pointer.sortValue = _this.frame.size[d[KEY]] || 0;
        pointer[KEY] = prefix + d[KEY];
        return pointer;
      }).sort(function (a, b) {
        return b.sortValue - a.sortValue;
      });
    };

    // get array of GEOs, sorted by the size hook
    // that makes larger bubbles go behind the smaller ones
    var endTime = this.model.time.end;
    var markers = getKeys.call(this);
    this.model.marker.setVisible(markers);

    //unselecting bubbles with no data is used for the scenario when
    //some bubbles are selected and user would switch indicator.
    //bubbles would disappear but selection would stay
    if (!this.model.time.splash) {
      this.unselectBubblesWithNoData(markers);
    }
    this.entityBubbles = this.bubbleContainer.selectAll('circle.vzb-bc-entity').data(this.model.marker.getVisible(), function (d) {
      return d[KEY];
    }); // trails have not keys

    //exit selection
    this.entityBubbles.exit().remove();

    //enter selection -- init circles
    this.entityBubbles.enter().append("circle").attr("class", function (d) {
      return "vzb-bc-entity " + "bubble-" + d[KEY];
    }).on("mouseover", function (d, i) {
      if (utils.isTouchDevice() || _this.model.ui.cursorMode !== 'arrow') return;
      _this._bubblesInteract().mouseover(d, i);
    }).on("mouseout", function (d, i) {
      if (utils.isTouchDevice() || _this.model.ui.cursorMode !== 'arrow') return;

      _this._bubblesInteract().mouseout(d, i);
    }).on("click", function (d, i) {
      if (utils.isTouchDevice() || _this.model.ui.cursorMode !== 'arrow') return;

      _this._bubblesInteract().click(d, i);
    }).onTap(function (d, i) {
      d3.event.stopPropagation();
      _this._bubblesInteract().click(d, i);
    }).onLongTap(function (d, i) {});

    this._reorderEntities();
  },

  unselectBubblesWithNoData: function unselectBubblesWithNoData(entities) {
    var _this = this;
    var KEY = this.KEY;
    if (!this.model.marker.select.length) return;

    var _select = [];
    var keys = entities.map(function (d) {
      return d[KEY];
    });

    this.model.marker.select.forEach(function (d) {
      if (keys.indexOf(d[KEY]) !== -1) _select.push(d);
    });

    if (_select.length !== _this.model.marker.select.length) _this.model.marker.select = _select;
  },

  _reorderEntities: function _reorderEntities() {
    var _this = this;
    var KEY = this.KEY;
    this.bubbleContainer.selectAll('.vzb-bc-entity').sort(function (a, b) {
      var sizeA = _this.frame.size[a[KEY]];
      var sizeB = _this.frame.size[b[KEY]];

      if (typeof sizeA == "undefined" && typeof sizeB != "undefined") return -1;
      if (typeof sizeA != "undefined" && typeof sizeB == "undefined") return 1;
      if (sizeA != sizeB) return d3.descending(sizeA, sizeB);
      if (a[KEY] != b[KEY]) return d3.ascending(a[KEY], b[KEY]);
      if (typeof a.trailStartTime != "undefined" || typeof b.trailStartTime != "undefined") return typeof a.trailStartTime != "undefined" ? -1 : 1; // only lines has trailStartTime
      if (typeof a.limits != "undefined" || typeof b.limits != "undefined") return typeof a.limits != "undefined" ? -1 : 1; // only trails has attribute limits
      return d3.descending(sizeA, sizeB);
    });
  },

  _bubblesInteract: function _bubblesInteract() {
    var _this = this;
    var KEY = this.KEY;
    var TIMEDIM = this.TIMEDIM;

    return {
      mouseover: function mouseover(d, i) {
        _this.model.marker.highlightMarker(d);

        _this._labels.showCloseCross(d, true);
      },

      mouseout: function mouseout(d, i) {
        _this.model.marker.clearHighlighted();

        _this._labels.showCloseCross(d, false);
      },

      click: function click(d, i) {
        if (_this.draggingNow) return;
        var isSelected = _this.model.marker.isSelected(d);
        _this.model.marker.selectMarker(d);
        //return to highlighted state
        if (!utils.isTouchDevice()) {
          if (isSelected) _this.model.marker.highlightMarker(d);
          _this.highlightDataPoints();
        }
      }
    };
  },

  /*
   * UPDATE TIME:
   * Ideally should only update when time or data changes
   */
  updateTime: function updateTime() {
    var _this = this;

    this.time_1 = this.time == null ? this.model.time.value : this.time;
    this.time = this.model.time.value;
    this.duration = this.model.time.playing && this.time - this.time_1 > 0 ? this.model.time.delayAnimations : 0;
    this.year.setText(this.model.time.formatDate(this.time, 'ui'), this.duration);
  },

  /*
   * RESIZE:
   * Executed whenever the container is resized
   */
  updateSize: function updateSize() {

    var profiles = {
      small: {
        margin: { top: 30, right: 10, left: 40, bottom: 35 },
        padding: 2,
        minRadius: 0.5,
        maxRadius: 30,
        infoElHeight: 16,
        yAxisTitleBottomMargin: 6,
        xAxisTitleBottomMargin: 4
      },
      medium: {
        margin: { top: 40, right: 15, left: 60, bottom: 55 },
        padding: 2,
        minRadius: 1,
        maxRadius: 55,
        infoElHeight: 20,
        yAxisTitleBottomMargin: 6,
        xAxisTitleBottomMargin: 5
      },
      large: {
        margin: { top: 50, right: 20, left: 60, bottom: 60 },
        padding: 2,
        minRadius: 1,
        maxRadius: 65,
        infoElHeight: 22,
        yAxisTitleBottomMargin: 6,
        xAxisTitleBottomMargin: 5,
        hideSTitle: true
      }
    };

    var presentationProfileChanges = {
      "medium": {
        margin: { top: 80, bottom: 80, left: 100 },
        yAxisTitleBottomMargin: 20,
        xAxisTitleBottomMargin: 20,
        infoElHeight: 26
      },
      "large": {
        margin: { top: 80, bottom: 100, left: 100 },
        yAxisTitleBottomMargin: 20,
        xAxisTitleBottomMargin: 20,
        infoElHeight: 32,
        hideSTitle: true
      }
    };

    var _this = this;

    this.activeProfile = this.getActiveProfile(profiles, presentationProfileChanges);
    var margin = this.activeProfile.margin;
    var infoElHeight = this.activeProfile.infoElHeight;

    //labels
    _this._labels.setCloseCrossHeight(_this.activeProfile.infoElHeight * 1.2);

    //stage
    this.height = parseInt(this.element.style("height"), 10) - margin.top - margin.bottom || 0;
    this.width = parseInt(this.element.style("width"), 10) - margin.left - margin.right || 0;

    if (this.height <= 0 || this.width <= 0) return utils.warn("Bubble chart updateSize() abort: vizabi container is too little or has display:none");

    //graph group is shifted according to margins (while svg element is at 100 by 100%)
    this.graph.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    this.year.resize(this.width, this.height);
    this.eventArea.attr("width", this.width).attr("height", Math.max(0, this.height));

    //update scales to the new range
    if (this.model.marker.axis_y.scaleType !== "ordinal") {
      this.yScale.range(this._rangeBump([this.height, 0]));
    } else {
      this.yScale.rangePoints([this.height, 0], _this.activeProfile.padding).range();
    }
    if (this.model.marker.axis_x.scaleType !== "ordinal") {
      this.xScale.range(this._rangeBump([0, this.width]));
    } else {
      this.xScale.rangePoints([0, this.width], _this.activeProfile.padding).range();
    }

    //apply scales to axes and redraw
    this.yAxis.scale(this.yScale).orient("left").tickSize(-this.width, 0).tickPadding(6).tickSizeMinor(-this.width, 0).labelerOptions({
      scaleType: this.model.marker.axis_y.scaleType,
      toolMargin: margin,
      limitMaxTickNumber: 6,
      bump: this.activeProfile.maxRadius / 2,
      viewportLength: this.height,
      formatter: this.model.marker.axis_y.getTickFormatter()
    });

    this.xAxis.scale(this.xScale).orient("bottom").tickSize(-this.height, 0).tickPadding(6).tickSizeMinor(-this.height, 0).labelerOptions({
      scaleType: this.model.marker.axis_x.scaleType,
      toolMargin: margin,
      bump: this.activeProfile.maxRadius / 2,
      viewportLength: this.width,
      formatter: this.model.marker.axis_x.getTickFormatter()
    });

    this.bubbleContainerCrop.attr("width", this.width).attr("height", Math.max(0, this.height));

    this.labelsContainerCrop.attr("width", this.width).attr("height", Math.max(0, this.height));

    this.xAxisElContainer.attr("width", this.width + 1).attr("height", this.activeProfile.margin.bottom + this.height).attr("y", -1).attr("x", -1);
    this.xAxisEl.attr("transform", "translate(1," + (1 + this.height) + ")");

    this.yAxisElContainer.attr("width", this.activeProfile.margin.left + this.width).attr("height", Math.max(0, this.height)).attr("x", -this.activeProfile.margin.left);
    this.yAxisEl.attr("transform", "translate(" + (this.activeProfile.margin.left - 1) + "," + 0 + ")");

    this.yAxisEl.call(this.yAxis);
    this.xAxisEl.call(this.xAxis);

    this.projectionX.attr("y1", _this.yScale.range()[0] + this.activeProfile.maxRadius / 2);
    this.projectionY.attr("x2", _this.xScale.range()[0] - this.activeProfile.maxRadius / 2);

    // reduce font size if the caption doesn't fit
    this._updateSTitle();
    this.sTitleEl.attr("transform", "translate(" + this.width + "," + 20 + ") rotate(-90)");

    var isRTL = this.model.locale.isRTL();
    this.yTitleEl.style("font-size", infoElHeight + "px").attr("transform", "translate(" + (isRTL ? this.width : 10 - this.activeProfile.margin.left) + ", -" + this.activeProfile.yAxisTitleBottomMargin + ")");

    this.xTitleEl.style("font-size", infoElHeight + "px").attr("transform", "translate(" + (isRTL ? this.width : 0) + "," + (this.height + margin.bottom - this.activeProfile.xAxisTitleBottomMargin) + ")");

    var ySeparator = this.strings.unit.Y ? ", " : "";
    var yTitleText = this.yTitleEl.select("text").text(this.strings.title.Y + ySeparator + this.strings.unit.Y);
    if (yTitleText.node().getBBox().width > this.width) yTitleText.text(this.strings.title.Y);

    var xSeparator = this.strings.unit.Y ? ", " : "";
    var xTitleText = this.xTitleEl.select("text").text(this.strings.title.X + xSeparator + this.strings.unit.X);
    if (xTitleText.node().getBBox().width > this.width - 100) xTitleText.text(this.strings.title.X);

    if (this.yInfoEl.select('svg').node()) {
      var titleBBox = this.yTitleEl.node().getBBox();
      var translate = d3.transform(this.yTitleEl.attr('transform')).translate;
      var hTranslate = isRTL ? titleBBox.x + translate[0] - infoElHeight * 1.4 : titleBBox.x + translate[0] + titleBBox.width + infoElHeight * .4;

      this.yInfoEl.select('svg').attr("width", infoElHeight + "px").attr("height", infoElHeight + "px");
      this.yInfoEl.attr('transform', 'translate(' + hTranslate + ',' + (translate[1] - infoElHeight * 0.8) + ')');
    }

    if (this.xInfoEl.select('svg').node()) {
      var titleBBox = this.xTitleEl.node().getBBox();
      var translate = d3.transform(this.xTitleEl.attr('transform')).translate;
      var hTranslate = isRTL ? titleBBox.x + translate[0] - infoElHeight * 1.4 : titleBBox.x + translate[0] + titleBBox.width + infoElHeight * .4;

      this.xInfoEl.select('svg').attr("width", infoElHeight + "px").attr("height", infoElHeight + "px");
      this.xInfoEl.attr('transform', 'translate(' + hTranslate + ',' + (translate[1] - infoElHeight * 0.8) + ')');
    }

    this._resizeDataWarning();
  },

  _updateLineEqualXY: function _updateLineEqualXY(duration) {
    var oneMeasure = this.model.marker.axis_x.which == this.model.marker.axis_y.which;
    this.lineEqualXY.classed("vzb-invisible", !oneMeasure);
    if (!oneMeasure) return;

    var min = d3.min(this.yScale.domain().concat(this.xScale.domain()));
    var max = d3.max(this.yScale.domain().concat(this.xScale.domain()));

    this.lineEqualXY.transition().duration(duration || 0).attr("y1", this.yScale(min)).attr("y2", this.yScale(max)).attr("x1", this.xScale(min)).attr("x2", this.xScale(max));
  },

  _resizeDataWarning: function _resizeDataWarning() {
    // reset font size to remove jumpy measurement
    var dataWarningText = this.dataWarningEl.select("text").style("font-size", null);

    // reduce font size if the caption doesn't fit
    var dataWarningWidth = dataWarningText.node().getBBox().width + dataWarningText.node().getBBox().height * 3;
    var remainingWidth = this.width - this.xTitleEl.node().getBBox().width - this.activeProfile.infoElHeight;
    var font = parseInt(dataWarningText.style("font-size")) * remainingWidth / dataWarningWidth;
    dataWarningText.style("font-size", dataWarningWidth > remainingWidth ? font + "px" : null);

    // position the warning icon
    var warnBB = dataWarningText.node().getBBox();
    this.dataWarningEl.select("svg").attr("width", warnBB.height * 0.75).attr("height", warnBB.height * 0.75).attr("x", -warnBB.width - warnBB.height * 1.2).attr("y", -warnBB.height * 0.65);

    this.dataWarningEl.attr("transform", "translate(" + (this.model.locale.isRTL() ? warnBB.width + warnBB.height : this.width) + "," + (this.height + this.activeProfile.margin.bottom - this.activeProfile.xAxisTitleBottomMargin) + ")");
  },

  updateMarkerSizeLimits: function updateMarkerSizeLimits() {
    var _this = this;
    var extent = this.model.marker.size.extent || [0, 1];

    if (!this.activeProfile) return utils.warn("updateMarkerSizeLimits() is called before ready(). This can happen if events get unfrozen and getFrame() still didn't return data");

    var minRadius = this.activeProfile.minRadius;
    var maxRadius = this.activeProfile.maxRadius;

    this.minRadius = Math.max(maxRadius * extent[0], minRadius);
    this.maxRadius = Math.max(maxRadius * extent[1], minRadius);

    if (this.model.marker.size.scaleType !== "ordinal") {
      this.sScale.range([utils.radiusToArea(_this.minRadius), utils.radiusToArea(_this.maxRadius)]);
    } else {
      this.sScale.rangePoints([utils.radiusToArea(_this.minRadius), utils.radiusToArea(_this.maxRadius)], _this.activeProfile.padding).range();
    }
  },

  redrawDataPointsOnlyColors: function redrawDataPointsOnlyColors() {
    var _this = this;
    if (!this.entityBubbles) return utils.warn("redrawDataPointsOnlyColors(): no entityBubbles defined. likely a premature call, fix it!");

    var valuesNow;
    var KEY = this.KEY;

    var time = this.model.time.value;

    if (this.model.ui.chart.lockNonSelected && this.someSelected) {
      time = this.model.time.parse("" + this.model.ui.chart.lockNonSelected);
    }
    this.model.marker.getFrame(time, function (valuesLocked) {
      if (!_this._frameIsValid(valuesLocked)) return utils.warn("redrawDataPointsOnlyColor: empty data received from marker.getFrame(). doing nothing");

      valuesNow = _this.frame;
      _this.entityBubbles.each(function (d, index) {

        var selected = _this.model.marker.isSelected(d);

        var valueC = selected ? valuesNow.color[d[KEY]] : valuesLocked.color[d[KEY]];

        var scaledC = valueC != null ? _this.cScale(valueC) : _this.COLOR_WHITEISH;

        d3.select(this).style("fill", scaledC);

        //update lines of labels
        if (selected) {

          var select = utils.find(_this.model.marker.select, function (f) {
            return f[KEY] == d[KEY];
          });

          var trailStartTime = _this.model.time.parse("" + select.trailStartTime);

          _this.model.marker.getFrame(trailStartTime, function (valuesTrailStart) {
            if (!valuesTrailStart) return utils.warn("redrawDataPointsOnlyColor: empty data received from marker.getFrames(). doing nothing");

            var cache = {};
            if (!_this.model.ui.chart.trails || trailStartTime - _this.time == 0) {
              cache.scaledC0 = scaledC;
            } else {
              var valueC = valuesTrailStart.color[d[KEY]];
              cache.scaledC0 = valueC != null ? _this.cScale(valueC) : _this.COLOR_WHITEISH;
            }

            _this._labels.updateLabelOnlyColor(d, index, cache);
          });
        }
      });
    });
  },

  redrawDataPointsOnlySize: function redrawDataPointsOnlySize() {
    var _this = this;

    var valuesNow;
    var KEY = this.KEY;

    var time = this.model.time.value;

    if (this.model.ui.chart.lockNonSelected && this.someSelected) {
      time = this.model.time.parse("" + this.model.ui.chart.lockNonSelected);
    }
    this.model.marker.getFrame(time, function (valuesLocked) {
      if (!_this._frameIsValid(valuesLocked)) return utils.warn("redrawDataPointsOnlySize: empty data received from marker.getFrame(). doing nothing");

      valuesNow = _this.frame;
      _this.entityBubbles.each(function (d, index) {

        var selected = _this.model.marker.isSelected(d);

        var valueS = selected ? valuesNow.size[d[KEY]] : valuesLocked.size[d[KEY]];
        if (valueS == null) return;

        var scaledS = utils.areaToRadius(_this.sScale(valueS));
        d3.select(this).attr("r", scaledS);

        //update lines of labels
        if (selected) {

          var select = utils.find(_this.model.marker.select, function (f) {
            return f[KEY] == d[KEY];
          });

          var trailStartTime = _this.model.time.parse("" + select.trailStartTime);

          _this.model.marker.getFrame(trailStartTime, function (valuesTrailStart) {
            if (!valuesTrailStart) return utils.warn("redrawDataPointsOnlySize: empty data received from marker.getFrames(). doing nothing");

            var cache = {};
            if (!_this.model.ui.chart.trails || trailStartTime - _this.time == 0) {
              cache.scaledS0 = scaledS;
            } else {
              cache.scaledS0 = utils.areaToRadius(_this.sScale(valuesTrailStart.size[d[KEY]]));
            }

            _this._labels.updateLabelOnlyPosition(d, index, cache);
          });
        }
      });
    });
  },

  /*
   * REDRAW DATA POINTS:
   * Here plotting happens
   * debouncing to improve performance: events might trigger it more than 1x
   */
  redrawDataPoints: function redrawDataPoints(duration) {
    var _this = this;
    var KEY = this.KEY;
    if (duration == null) duration = _this.duration;

    if (this.model.ui.chart.lockNonSelected && this.someSelected) {
      var time = this.model.time.parse("" + this.model.ui.chart.lockNonSelected);

      //get values for locked frames
      this.model.marker.getFrame(time, function (lockedFrame) {
        if (!lockedFrame) return utils.warn("redrawDataPoints: empty data received from marker.getFrames(). doing nothing");

        // each bubble
        _this.entityBubbles.each(function (d, index) {
          var frame = _this.model.marker.isSelected(d) ? _this.frame : lockedFrame;
          _this._updateBubble(d, frame, index, d3.select(this), duration);
        });
      });
    } else {
      // each bubble
      _this.entityBubbles.each(function (d, index) {
        _this._updateBubble(d, _this.frame, index, d3.select(this), duration);
      });
    }

    this._updateLineEqualXY(duration);
  },

  //redraw Data Points
  _updateBubble: function _updateBubble(d, values, index, view, duration) {
    var _this = this;
    var KEY = this.KEY;

    var showhide = false;

    var valueY = values.axis_y[d[KEY]];
    var valueX = values.axis_x[d[KEY]];
    var valueS = values.size[d[KEY]];
    var valueL = values.label[d[KEY]];
    var valueC = values.color[d[KEY]];
    var valueLST = values.size_label[d[KEY]];

    // check if fetching data succeeded
    if (!valueL && valueL !== 0 || !valueY && valueY !== 0 || !valueX && valueX !== 0 || !valueS && valueS !== 0) {
      // if entity is missing data it should hide
      if (!d.hidden) {
        d.hidden = true;
        showhide = true;
      }

      if (showhide) {
        if (duration) {
          var opacity = view.style("opacity");
          view.transition().duration(duration).ease("exp").style("opacity", 0).each("end", function () {
            //to avoid transition from null state add class with a delay
            view.classed("vzb-invisible", d.hidden);
            view.style("opacity", opacity);
          });
        } else {
          //immediately hide the bubble
          view.classed("vzb-invisible", d.hidden);
        }
      }
    } else {
      if (d.hidden || view.classed("vzb-invisible")) {
        d.hidden = false;
        showhide = true;
      }

      // if entity has all the data we update the visuals
      var scaledS = utils.areaToRadius(_this.sScale(valueS));

      view.style("fill", valueC != null ? _this.cScale(valueC) : _this.COLOR_WHITEISH);

      if (duration) {
        if (showhide) {
          var opacity = view.style("opacity");
          view.classed("vzb-invisible", d.hidden);
          view.style("opacity", 0).attr("cy", _this.yScale(valueY)).attr("cx", _this.xScale(valueX)).attr("r", scaledS).transition().duration(duration).ease("exp").style("opacity", opacity);
        } else {
          view.transition().duration(duration).ease("linear").attr("cy", _this.yScale(valueY)).attr("cx", _this.xScale(valueX)).attr("r", scaledS);
        }
      } else {

        //interrupt the ongoing transition and immediately do the visual updates
        view.interrupt().attr("cy", _this.yScale(valueY)).attr("cx", _this.xScale(valueX)).attr("r", scaledS).transition();

        //show entity if it was hidden
        if (showhide) view.classed("vzb-invisible", d.hidden);
      }

      if (this.model.time.record) _this._export.write({
        type: "circle",
        id: d[KEY],
        time: this.model.time.value.getUTCFullYear(),
        fill: valueC != null ? _this.cScale(valueC) : _this.COLOR_WHITEISH,
        cx: _this.xScale(valueX),
        cy: _this.yScale(valueY),
        r: scaledS
      });
    } // data exists
    _this._updateLabel(d, index, valueX, valueY, valueS, valueC, valueL, valueLST, duration, showhide);
  },

  _updateLabel: function _updateLabel(d, index, valueX, valueY, valueS, valueC, valueL, valueLST, duration, showhide) {
    var _this = this;
    var KEY = this.KEY;

    // only for selected markers
    if (_this.model.marker.isSelected(d)) {

      var cache = {};

      var select = utils.find(_this.model.marker.select, function (f) {
        return f[KEY] == d[KEY];
      });

      var time = _this.model.time.formatDate(_this.time);
      if (!this.model.ui.chart.trails || select.trailStartTime == time || select.trailStartTime == null) {
        if (this.model.ui.chart.trails && select.trailStartTime == null) select.trailStartTime = time; // need only when trailStartTime == null

        cache.labelX0 = valueX;
        cache.labelY0 = valueY;
        cache.scaledC0 = valueC != null ? _this.cScale(valueC) : _this.COLOR_WHITEISH, cache.scaledS0 = valueS || valueS === 0 ? utils.areaToRadius(_this.sScale(valueS)) : null;
      }

      var trailStartTime = _this.model.time.parse("" + select.trailStartTime);

      var labelText = valueL + (_this.model.ui.chart.trails ? " " + select.trailStartTime : "");

      if (showhide && d.hidden && _this.model.ui.chart.trails && trailStartTime && trailStartTime < _this.time) showhide = false;
      if (d.hidden && !_this.model.ui.chart.trails) showhide = true;

      this._labels.updateLabel(d, index, cache, valueX, valueY, valueS, valueC, labelText, valueLST, duration, showhide);
    }
  },

  _formatSTitleValues: function _formatSTitleValues(titleS, titleC) {
    var _this = this;
    var unitS = this.strings.unit.S;
    var unitC = this.strings.unit.C;

    var formatterS = this.model.marker.size.getTickFormatter();
    var formatterC = this.model.marker.color.getTickFormatter();

    //resolve labels for colors via the color legend
    if (this.model.marker.color.isDiscrete() && this.model.marker.color.use !== "constant" && titleC && this.model.marker.color.getColorlegendMarker()) {
      titleC = this.model.marker.color.getColorlegendMarker().label.getItems()[titleC] || "";
    }

    return [formatterS(titleS) + " " + unitS, titleC || titleC === 0 ? formatterC(titleC) + " " + unitC : this.translator("hints/nodata")];
  },

  _updateSTitle: function _updateSTitle(titleS, titleC) {

    // vertical text about size and color
    if (this.activeProfile.hideSTitle && this.model.ui.dialogs.sidebar.indexOf("colors") > -1 && this.model.ui.dialogs.sidebar.indexOf("size") > -1) {
      this.sTitleEl.classed("vzb-invisible", true);
      return;
    }
    if (this.sTitleEl.classed("vzb-invisible")) {
      this.sTitleEl.classed("vzb-invisible", false);
    }
    var sTitleContentON = this.model.marker.size.use !== "constant";
    var cTitleContentON = this.model.marker.color.use !== "constant";
    var sTitleText = this.sTitleEl.select("text")
    // reset font size to remove jumpy measurement
    .style("font-size", null).text((sTitleContentON ? this.translator("buttons/size") + ": " + (titleS ? titleS : this.strings.title.S) : "") + (sTitleContentON && cTitleContentON ? ", " : "") + (cTitleContentON ? this.translator("buttons/colors") + ": " + (titleC ? titleC : this.strings.title.C) : ""));
    var sTitleWidth = sTitleText.node().getBBox().width;
    var remainigHeight = this.height - 30;
    var font = parseInt(sTitleText.style("font-size")) * remainigHeight / sTitleWidth;
    sTitleText.style("font-size", sTitleWidth > remainigHeight ? font + "px" : null);
  },

  selectDataPoints: function selectDataPoints() {
    var _this = this;
    var KEY = this.KEY;

    if (utils.isTouchDevice()) {
      _this.model.marker.clearHighlighted();
      _this._labels.showCloseCross(null, false);
    } else {
      //hide tooltip
      _this._setTooltip();
      _this._setBubbleCrown();
    }

    _this.someSelected = _this.model.marker.select.length > 0;
    _this.nonSelectedOpacityZero = false;
  },

  _setBubbleCrown: function _setBubbleCrown(x, y, r, glow, skipInnerFill) {
    if (x != null) {
      this.bubbleCrown.classed("vzb-hidden", false);
      this.bubbleCrown.select(".vzb-crown").attr("cx", x).attr("cy", y).attr("r", r).attr("fill", skipInnerFill ? "none" : glow);
      this.bubbleCrown.selectAll(".vzb-crown-glow").attr("cx", x).attr("cy", y).attr("r", r + 10).attr("stroke", glow);
    } else {
      this.bubbleCrown.classed("vzb-hidden", true);
    }
  },

  _setTooltip: function _setTooltip(tooltipText, x, y, offset, glow) {
    if (tooltipText) {
      var xPos,
          yPos,
          xSign = -1,
          ySign = -1,
          xOffset = 0,
          yOffset = 0;

      if (offset) {
        xOffset = offset * .71; // .71 - sin and cos for 315
        yOffset = offset * .71;
      }
      //position tooltip
      this.tooltip.classed("vzb-hidden", false)
      //.attr("style", "left:" + (mouse[0] + 50) + "px;top:" + (mouse[1] + 50) + "px")
      .selectAll("text").text(tooltipText);

      var contentBBox = this.tooltip.select('text')[0][0].getBBox();
      if (x - xOffset - contentBBox.width < 0) {
        xSign = 1;
        x += contentBBox.width + 5; // corrective to the block Radius and text padding
      } else {
        x -= 5; // corrective to the block Radius and text padding
      }
      if (y - yOffset - contentBBox.height < 0) {
        ySign = 1;
        y += contentBBox.height;
      } else {
        y -= 11; // corrective to the block Radius and text padding
      }
      if (offset) {
        xPos = x + xOffset * xSign;
        yPos = y + yOffset * ySign; // 5 and 11 - corrective to the block Radius and text padding
      } else {
        xPos = x + xOffset * xSign; // .71 - sin and cos for 315
        yPos = y + yOffset * ySign; // 5 and 11 - corrective to the block Radius and text padding
      }
      this.tooltip.attr("transform", "translate(" + xPos + "," + yPos + ")");

      this.tooltip.selectAll("rect").attr("width", contentBBox.width + 8).attr("height", contentBBox.height * 1.2).attr("x", -contentBBox.width - 4).attr("y", -contentBBox.height * .85).attr("rx", contentBBox.height * .2).attr("ry", contentBBox.height * .2);

      this.tooltip.select(".vzb-tooltip-glow").attr("stroke", glow);
    } else {
      this.tooltip.classed("vzb-hidden", true);
    }
  },

  /*
   * Shows and hides axis projections
   */
  _axisProjections: function _axisProjections(d) {
    var _this = this;
    var TIMEDIM = this.TIMEDIM;
    var KEY = this.KEY;

    if (d != null) {

      this.model.marker.getFrame(d[TIMEDIM], function (values) {
        var valueY = values.axis_y[d[KEY]];
        var valueX = values.axis_x[d[KEY]];
        var valueS = values.size[d[KEY]];
        var radius = utils.areaToRadius(_this.sScale(valueS));

        if (!valueY && valueY !== 0 || !valueX && valueX !== 0 || !valueS && valueS !== 0) return;

        if (_this.model.ui.chart.whenHovering.showProjectionLineX && _this.xScale(valueX) > 0 && _this.xScale(valueX) < _this.width && _this.yScale(valueY) + radius < _this.height) {
          _this.projectionX.style("opacity", 1).attr("y2", _this.yScale(valueY) + radius).attr("x1", _this.xScale(valueX)).attr("x2", _this.xScale(valueX));
        }

        if (_this.model.ui.chart.whenHovering.showProjectionLineY && _this.yScale(valueY) > 0 && _this.yScale(valueY) < _this.height && _this.xScale(valueX) - radius > 0) {
          _this.projectionY.style("opacity", 1).attr("y1", _this.yScale(valueY)).attr("y2", _this.yScale(valueY)).attr("x1", _this.xScale(valueX) - radius);
        }

        if (_this.model.ui.chart.whenHovering.higlightValueX) _this.xAxisEl.call(_this.xAxis.highlightValue(valueX));

        if (_this.model.ui.chart.whenHovering.higlightValueY) _this.yAxisEl.call(_this.yAxis.highlightValue(valueY));
      });
    } else {

      this.projectionX.style("opacity", 0);
      this.projectionY.style("opacity", 0);
      this.xAxisEl.call(this.xAxis.highlightValue("none"));
      this.yAxisEl.call(this.yAxis.highlightValue("none"));
    }
  },

  /*
   * Highlights all hovered bubbles
   */
  highlightDataPoints: function highlightDataPoints() {
    var _this = this;
    var TIMEDIM = this.TIMEDIM;
    var KEY = this.KEY;

    this.someHighlighted = this.model.marker.highlight.length > 0;

    this.updateBubbleOpacity();

    if (this.model.marker.highlight.length === 1) {
      var d = utils.clone(this.model.marker.highlight[0]);

      if (_this.model.ui.chart.lockNonSelected && _this.someSelected && !_this.model.marker.isSelected(d)) {
        d[TIMEDIM] = _this.model.time.parse("" + _this.model.ui.chart.lockNonSelected);
      } else {
        d[TIMEDIM] = _this.model.time.parse("" + d.trailStartTime) || _this.time;
      }

      _this.model.marker.getFrame(d[TIMEDIM], function (values) {
        if (!values) return;
        var x = _this.xScale(values.axis_x[d[KEY]]);
        var y = _this.yScale(values.axis_y[d[KEY]]);
        var s = utils.areaToRadius(_this.sScale(values.size[d[KEY]]));
        var c = values.color[d[KEY]] != null ? _this.cScale(values.color[d[KEY]]) : _this.COLOR_WHITEISH;
        var entityOutOfView = false;

        var titles = _this._formatSTitleValues(values.size[d[KEY]], values.color[d[KEY]]);
        _this._updateSTitle(titles[0], titles[1]);
        if (x + s < 0 || x - s > _this.width || y + s < 0 || y - s > _this.height) {
          entityOutOfView = true;
        }

        //show tooltip
        var text = "";
        var hoverTrail = false;
        if (_this.model.marker.isSelected(d) && _this.model.ui.chart.trails) {
          text = _this.model.time.formatDate(_this.time);
          var selectedData = utils.find(_this.model.marker.select, function (f) {
            return f[KEY] == d[KEY];
          });
          hoverTrail = text !== selectedData.trailStartTime && !d3.select(d3.event.target).classed('bubble-' + d[KEY]);
          text = text !== selectedData.trailStartTime && _this.time === d[TIMEDIM] ? text : '';
        } else {
          text = _this.model.marker.isSelected(d) ? '' : values.label[d[KEY]];
        }

        _this._labels.highlight(null, false);
        _this._labels.highlight(d, true);
        if (_this.model.marker.isSelected(d)) {
          var skipCrownInnerFill = !d.trailStartTime || d.trailStartTime == _this.model.time.formatDate(_this.time);
          _this._setBubbleCrown(x, y, s, c, skipCrownInnerFill);
        }

        if (!entityOutOfView && !hoverTrail) {
          _this._axisProjections(d);
        }

        //set tooltip and show axis projections
        if (text && !entityOutOfView && !hoverTrail) {
          _this._setTooltip(text, x, y, s + 3, c);
        }

        var selectedData = utils.find(_this.model.marker.select, function (f) {
          return f[KEY] == d[KEY];
        });
        if (selectedData) {
          var clonedSelectedData = utils.clone(selectedData);
          //change opacity to OPACITY_HIGHLT = 1.0;
          clonedSelectedData.opacity = 1.0;
          _this._trails.run(["opacityHandler"], clonedSelectedData);
        }
      });
    } else {
      this._axisProjections();
      this._trails.run(["opacityHandler"]);
      //hide tooltip
      _this._updateSTitle();
      this._setTooltip();
      this._setBubbleCrown();
      this._labels.highlight(null, false);
    }
  },

  updateBubbleOpacity: function updateBubbleOpacity(duration) {
    var _this = this;
    //if(!duration)duration = 0;

    var OPACITY_HIGHLT = 1.0;
    var OPACITY_HIGHLT_DIM = this.model.marker.opacityHighlightDim;
    var OPACITY_SELECT = this.model.marker.opacityRegular;
    var OPACITY_REGULAR = this.model.marker.opacityRegular;
    var OPACITY_SELECT_DIM = this.model.marker.opacitySelectDim;

    this.entityBubbles
    //.transition().duration(duration)
    .style("opacity", function (d) {

      if (_this.someHighlighted) {
        //highlight or non-highlight
        if (_this.model.marker.isHighlighted(d)) return OPACITY_HIGHLT;
      }

      if (_this.someSelected) {
        //selected or non-selected
        return _this.model.marker.isSelected(d) ? OPACITY_SELECT : OPACITY_SELECT_DIM;
      }

      if (_this.someHighlighted) return OPACITY_HIGHLT_DIM;

      return OPACITY_REGULAR;
    });

    var nonSelectedOpacityZero = _this.model.marker.opacitySelectDim < .01;

    // when pointer events need update...
    if (nonSelectedOpacityZero != this.nonSelectedOpacityZero) {
      this.entityBubbles.style("pointer-events", function (d) {
        return !_this.someSelected || !nonSelectedOpacityZero || _this.model.marker.isSelected(d) ? "visible" : "none";
      });
    }

    this.nonSelectedOpacityZero = _this.model.marker.opacitySelectDim < .01;
  }

});

exports.default = BubbleChartComp;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
    value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _class = __webpack_require__(21);

var _class2 = _interopRequireDefault(_class);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

exports.default = _class2.default.extend({

    init: function init(context) {
        this.context = context;

        this.dragRectangle = d3.behavior.drag();
        this.zoomer = d3.behavior.zoom();

        this.dragLock = false;

        this.dragRectangle.on("dragstart", this.drag().start).on("drag", this.drag().go).on("dragend", this.drag().stop);

        this.zoomer.on("zoomstart", this.zoom().start).on("zoom", this.zoom().go).on('zoomend', this.zoom().stop);

        this.zoomer.ratioX = 1;
        this.zoomer.ratioY = 1;

        context._zoomedXYMinMax = { axis_x: { zoomedMin: null, zoomedMax: null }, axis_y: { zoomedMin: null, zoomedMax: null } };
    },

    drag: function drag() {
        var _this = this.context;
        var self = this;

        return {
            start: function start(d, i) {
                /*
                 * Do not drag if the Ctrl key, Meta key, or plus cursor mode is
                 * not enabled. Also do not drag if zoom-pinching on touchmove
                 * events.
                 */
                if (!(d3.event.sourceEvent.ctrlKey || d3.event.sourceEvent.metaKey || _this.ui.cursorMode === "plus") || (d3.event.sourceEvent.type === "touchmove" || d3.event.sourceEvent.type === "touchstart") && (d3.event.sourceEvent.touches.length > 1 || d3.event.sourceEvent.targetTouches.length > 1)) {
                    return;
                }

                self.dragLock = true;
                this.origin = {
                    x: d3.mouse(this)[0],
                    y: d3.mouse(this)[1]
                };
                _this.zoomRect.classed("vzb-invisible", false);
            },

            go: function go(d, i) {
                /*
                 * Cancel drag if drag lock is false, or when zoom-pinching via
                 * touchmove events.
                 */
                if (!self.dragLock || (d3.event.sourceEvent.type === "touchmove" || d3.event.sourceEvent.type === "touchstart") && (d3.event.sourceEvent.touches.length > 1 || d3.event.sourceEvent.targetTouches.length > 1)) {
                    self.dragLock = false;

                    _this.zoomRect.attr("width", 0).attr("height", 0).classed("vzb-invisible", true);

                    return;
                }

                var origin = this.origin;
                var mouse = {
                    x: d3.event.x,
                    y: d3.event.y
                };

                _this.zoomRect.attr("x", Math.min(mouse.x, origin.x)).attr("y", Math.min(mouse.y, origin.y)).attr("width", Math.abs(mouse.x - origin.x)).attr("height", Math.abs(mouse.y - origin.y));
            },

            stop: function stop(e) {
                if (!self.dragLock) return;
                self.dragLock = false;

                _this.zoomRect.attr("width", 0).attr("height", 0).classed("vzb-invisible", true);

                this.target = {
                    x: d3.mouse(this)[0],
                    y: d3.mouse(this)[1]
                };
                if (Math.abs(this.origin.x - this.target.x) < 10 || Math.abs(this.origin.y - this.target.y) < 10) return;

                /*
                 * Only compensate for dragging when the Ctrl key or Meta key
                 * are pressed, or if the cursorMode is not in plus mode.
                 */
                var compensateDragging = d3.event.sourceEvent.ctrlKey || d3.event.sourceEvent.metaKey || _this.ui.cursorMode === "plus";

                self._zoomOnRectangle(d3.select(this), this.origin.x, this.origin.y, this.target.x, this.target.y, compensateDragging, 500);
            }
        };
    },

    zoom: function zoom() {
        var _this = this.context;
        var zoomer = this.zoomer;
        var self = this;

        return {
            start: function start() {
                this.savedScale = zoomer.scale();
            },
            go: function go() {

                var sourceEvent = d3.event.sourceEvent;

                if (sourceEvent != null && (sourceEvent.ctrlKey || sourceEvent.metaKey)) return;

                // Cancel drag lock when zoom-pinching via touchmove events.
                if (sourceEvent !== null && (sourceEvent.type === "touchmove" || sourceEvent.type === "touchstart") && (sourceEvent.touches.length > 1 || sourceEvent.targetTouches.length > 1)) {
                    self.dragLock = false;
                }

                if (self.dragLock) return;

                //send the event to the page if fully zoomed our or page not scrolled into view
                //
                //                    if(d3.event.scale == 1)
                //
                //                    if(utils.getViewportPosition(_this.element.node()).y < 0 && d3.event.scale > 1) {
                //                        _this.scrollableAncestor.scrollTop += d3.event.sourceEvent.deltaY;
                //                        return;
                //                    }
                /*
                 * Do not zoom on the chart if the scroll event is a wheel
                 * scroll. Instead, redirect the scroll event to the scrollable
                 * ancestor
                 */
                if (sourceEvent != null && (sourceEvent.type === "wheel" || sourceEvent.type === "mousewheel") && !_this.ui.zoomOnScrolling) {
                    if (_this.scrollableAncestor) {
                        _this.scrollableAncestor.scrollTop += sourceEvent.deltaY || -sourceEvent.wheelDelta;
                    }
                    d3.event.scale = null;
                    zoomer.scale(this.savedScale);
                    this.quitZoom = true;
                    return;
                }
                this.quitZoom = false;

                _this.model._data.marker.clearHighlighted();
                _this._setTooltip();

                var zoom = d3.event.scale;
                var pan = d3.event.translate;
                var ratioY = zoomer.ratioY;
                var ratioX = zoomer.ratioX;

                _this.draggingNow = true;

                //value protections and fallbacks
                if (isNaN(zoom) || zoom == null) zoom = zoomer.scale();
                if (isNaN(zoom) || zoom == null) zoom = 1;

                //TODO: this is a patch to fix #221. A proper code review of zoom and zoomOnRectangle logic is needed
                /*
                 * Mouse wheel and touchmove events set the zoom value
                 * independently of axis ratios. If the zoom event was triggered
                 * by a mouse wheel event scrolling down or touchmove event with
                 * more than 1 contact that sets zoom to 1, then set the axis
                 * ratios to 1 as well, which will fully zoom out.
                 */
                if (zoom === 1 && sourceEvent !== null && ((sourceEvent.type === "wheel" || sourceEvent.type === "mousewheel") && (sourceEvent.deltaY || -sourceEvent.wheelDelta) > 0 || sourceEvent.type === "touchmove" && sourceEvent.touches.length > 1)) {
                    zoomer.ratioX = 1;
                    ratioX = 1;
                    zoomer.ratioY = 1;
                    ratioY = 1;
                }

                if (isNaN(pan[0]) || isNaN(pan[1]) || pan[0] == null || pan[1] == null) pan = zoomer.translate();
                if (isNaN(pan[0]) || isNaN(pan[1]) || pan[0] == null || pan[1] == null) pan = [0, 0];

                // limit the zooming, so that it never goes below min value of zoom for any of the axes
                var minZoomScale = zoomer.scaleExtent()[0];
                if (zoom * ratioY < minZoomScale) {
                    ratioY = minZoomScale / zoom;
                    zoomer.ratioY = ratioY;
                }
                if (zoom * ratioX < minZoomScale) {
                    ratioX = minZoomScale / zoom;
                    zoomer.ratioX = ratioX;
                }

                var zoomXOut = zoom * ratioX < 1;
                var zoomYOut = zoom * ratioY < 1;

                //limit the panning, so that we are never outside the possible range
                if (!zoomXOut) {
                    if (pan[0] > 0) pan[0] = 0;
                    if (pan[0] < (1 - zoom * ratioX) * _this.width) pan[0] = (1 - zoom * ratioX) * _this.width;
                } else {
                    if (pan[0] < 0) pan[0] = 0;
                    if (pan[0] > (1 - zoom * ratioX) * _this.width) pan[0] = (1 - zoom * ratioX) * _this.width;
                }

                if (!zoomYOut) {
                    if (pan[1] > 0) pan[1] = 0;
                    if (pan[1] < (1 - zoom * ratioY) * _this.height) pan[1] = (1 - zoom * ratioY) * _this.height;
                } else {
                    if (pan[1] < 0) pan[1] = 0;
                    if (pan[1] > (1 - zoom * ratioY) * _this.height) pan[1] = (1 - zoom * ratioY) * _this.height;
                }

                var xPanOffset = _this.width * zoom * ratioX;
                var yPanOffset = _this.height * zoom * ratioY;

                var xRange = [0 * zoom * ratioX + pan[0], xPanOffset + pan[0]];
                var yRange = [yPanOffset + pan[1], 0 * zoom * ratioY + pan[1]];

                var xRangeBumped = _this._rangeBump(xRange);
                var yRangeBumped = _this._rangeBump(yRange);

                /*
                 * Shift xRange and yRange by the difference between the bumped
                 * ranges, which is scaled by the zoom factor. This accounts for
                 * the range bump, which controls a gutter around the
                 * bubblechart, while correctly zooming.
                 */
                var xRangeMinOffset = (xRangeBumped[0] - xRange[0]) * zoom * ratioX;
                var xRangeMaxOffset = (xRangeBumped[1] - xRange[1]) * zoom * ratioX;

                var yRangeMinOffset = (yRangeBumped[0] - yRange[0]) * zoom * ratioY;
                var yRangeMaxOffset = (yRangeBumped[1] - yRange[1]) * zoom * ratioY;

                xRange[0] = xRange[0] + xRangeMinOffset;
                xRange[1] = xRange[1] + xRangeMaxOffset;

                yRange[0] = yRange[0] + yRangeMinOffset;
                yRange[1] = yRange[1] + yRangeMaxOffset;

                // Calculate the maximum xRange and yRange available.
                var xRangeBounds = [0, _this.width];
                var yRangeBounds = [_this.height, 0];

                var xRangeBoundsBumped = _this._rangeBump(xRangeBounds);
                var yRangeBoundsBumped = _this._rangeBump(yRangeBounds);

                /*
                 * Set the pan to account for the range bump by subtracting
                 * offsets and preventing panning past the range bump gutter.
                 */
                if (!zoomXOut) {
                    if (xRange[0] > xRangeBoundsBumped[0]) pan[0] = xRangeBoundsBumped[0] - xRangeMinOffset;
                    if (xRange[1] < xRangeBoundsBumped[1]) pan[0] = xRangeBoundsBumped[1] - xRangeMaxOffset - xPanOffset;
                } else {
                    if (xRange[0] < xRangeBoundsBumped[0]) pan[0] = xRangeBoundsBumped[0] - xRangeMinOffset;
                    if (xRange[1] > xRangeBoundsBumped[1]) pan[0] = xRangeBoundsBumped[1] - xRangeMaxOffset - xPanOffset;
                }

                if (!zoomYOut) {
                    if (yRange[0] < yRangeBoundsBumped[0]) pan[1] = yRangeBoundsBumped[0] - yRangeMinOffset - yPanOffset;
                    if (yRange[1] > yRangeBoundsBumped[1]) pan[1] = yRangeBoundsBumped[1] - yRangeMaxOffset;
                } else {
                    if (yRange[0] > yRangeBoundsBumped[0]) pan[1] = yRangeBoundsBumped[0] - yRangeMinOffset - yPanOffset;
                    if (yRange[1] < yRangeBoundsBumped[1]) pan[1] = yRangeBoundsBumped[1] - yRangeMaxOffset;
                }

                zoomer.translate(pan);

                /*
                 * Clamp the xRange and yRange by the amount that the bounds
                 * that are range bumped.
                 *
                 * Additionally, take the amount clamped on the end of the range
                 * and either subtract or add it to the range's other end. This
                 * prevents visible stretching of the range when only panning.
                 */
                if (!zoomXOut) {
                    if (xRange[0] > xRangeBoundsBumped[0]) {
                        xRange[1] = xRange[1] - Math.abs(xRange[0] - xRangeBoundsBumped[0]);
                        xRange[0] = xRangeBoundsBumped[0];
                    }

                    if (xRange[1] < xRangeBoundsBumped[1]) {
                        xRange[0] = xRange[0] + Math.abs(xRange[1] - xRangeBoundsBumped[1]);
                        xRange[1] = xRangeBoundsBumped[1];
                    }
                } else {
                    if (xRange[0] < xRangeBoundsBumped[0]) {
                        xRange[1] = xRange[1] + Math.abs(xRange[0] - xRangeBoundsBumped[0]);
                        xRange[0] = xRangeBoundsBumped[0];
                    }

                    if (xRange[1] > xRangeBoundsBumped[1]) {
                        xRange[0] = xRange[0] - Math.abs(xRange[1] - xRangeBoundsBumped[1]);
                        xRange[1] = xRangeBoundsBumped[1];
                    }
                }

                if (!zoomYOut) {
                    if (yRange[0] < yRangeBoundsBumped[0]) {
                        yRange[1] = yRange[1] + Math.abs(yRange[0] - yRangeBoundsBumped[0]);
                        yRange[0] = yRangeBoundsBumped[0];
                    }

                    if (yRange[1] > yRangeBoundsBumped[1]) {
                        yRange[0] = yRange[0] - Math.abs(yRange[1] - yRangeBoundsBumped[1]);
                        yRange[1] = yRangeBoundsBumped[1];
                    }
                } else {
                    if (yRange[0] > yRangeBoundsBumped[0]) {
                        yRange[1] = yRange[1] - Math.abs(yRange[0] - yRangeBoundsBumped[0]);
                        yRange[0] = yRangeBoundsBumped[0];
                    }

                    if (yRange[1] < yRangeBoundsBumped[1]) {
                        yRange[0] = yRange[0] + Math.abs(yRange[1] - yRangeBoundsBumped[1]);
                        yRange[1] = yRangeBoundsBumped[1];
                    }
                }

                if (_this.model.marker.axis_x.scaleType === 'ordinal') {
                    _this.xScale.rangeBands(xRange);
                } else {
                    _this.xScale.range(xRange);
                }

                if (_this.model.marker.axis_y.scaleType === 'ordinal') {
                    _this.yScale.rangeBands(yRange);
                } else {
                    _this.yScale.range(yRange);
                }

                var formatter = function formatter(n) {
                    return utils.isDate(n) ? n : d3.round(n, 2);
                };

                var zoomedXRange = xRangeBoundsBumped;
                var zoomedYRange = yRangeBoundsBumped;

                /*
                 * Set the zoomed min/max to the correct value depending on if the
                 * min/max values lie within the range bound regions.
                 */
                if (!zoomXOut) {
                    zoomedXRange[0] = xRangeBounds[0] > xRange[0] ? xRangeBounds[0] : xRange[0];
                    zoomedXRange[1] = xRangeBounds[1] < xRange[1] ? xRangeBounds[1] : xRange[1];
                }

                if (!zoomYOut) {
                    zoomedYRange[0] = yRangeBounds[0] < yRange[0] ? yRangeBounds[0] : yRange[0];
                    zoomedYRange[1] = yRangeBounds[1] > yRange[1] ? yRangeBounds[1] : yRange[1];
                }

                _this._zoomedXYMinMax = {
                    axis_x: {
                        zoomedMin: formatter(_this.xScale.invert(zoomedXRange[0])),
                        zoomedMax: formatter(_this.xScale.invert(zoomedXRange[1]))
                    },
                    axis_y: {
                        zoomedMin: formatter(_this.yScale.invert(zoomedYRange[0])),
                        zoomedMax: formatter(_this.yScale.invert(zoomedYRange[1]))
                    }
                };

                if (!zoomer.dontFeedToState) _this.model.marker.set(_this._zoomedXYMinMax, null, false /*avoid storing it in URL*/);

                // Keep the min and max size (pixels) constant, when zooming.
                //                    _this.sScale.range([utils.radiusToArea(_this.minRadius) * zoom * zoom * ratioY * ratioX,
                //                                        utils.radiusToArea(_this.maxRadius) * zoom * zoom * ratioY * ratioX ]);

                var optionsY = _this.yAxis.labelerOptions();
                var optionsX = _this.xAxis.labelerOptions();
                optionsY.limitMaxTickNumber = zoom * ratioY < 1.5 ? 8 : zoom * ratioY * 8;
                optionsX.limitMaxTickNumber = zoom * ratioX < 1.5 ? 8 : zoom * ratioX * 8;
                optionsY.transitionDuration = zoomer.duration;
                optionsX.transitionDuration = zoomer.duration;

                _this.xAxisEl.call(_this.xAxis.labelerOptions(optionsX));
                _this.yAxisEl.call(_this.yAxis.labelerOptions(optionsY));
                _this.redrawDataPoints(zoomer.duration);
                _this._trails.run("resize", null, zoomer.duration);

                zoomer.duration = 0;
            },

            stop: function stop() {

                _this.draggingNow = false;

                if (this.quitZoom) return;

                //Force the update of the URL and history, with the same values
                if (!zoomer.dontFeedToState) _this.model.marker.set(_this._zoomedXYMinMax, true, true);
                zoomer.dontFeedToState = null;
            }
        };
    },

    expandCanvas: function expandCanvas(duration) {
        var _this = this.context;
        if (!duration) duration = _this.duration;

        //d3 extent returns min and max of the input array as [min, max]
        var mmX = d3.extent(utils.values(_this.frame.axis_x));
        var mmY = d3.extent(utils.values(_this.frame.axis_y));
        var radiusMax = utils.areaToRadius(_this.sScale(d3.extent(utils.values(_this.frame.size))[1])) || 0;

        //protection agains unreasonable min-max results -- abort function
        if (!mmX[0] && mmX[0] !== 0 || !mmX[1] && mmX[1] !== 0 || !mmY[0] && mmY[0] !== 0 || !mmY[1] && mmY[1] !== 0) {
            return utils.warn("panZoom.expandCanvas: X or Y min/max are broken. Aborting with no action");
        }
        /*
         * Use a range bumped scale to correctly accommodate the range bump
         * gutter.
         */
        var suggestedFrame = {
            x1: _this.xScale(mmX[0]) - radiusMax,
            y1: _this.yScale(mmY[0]) + radiusMax,
            x2: _this.xScale(mmX[1]) + radiusMax,
            y2: _this.yScale(mmY[1]) - radiusMax
        };
        var xBounds = [0, _this.width];
        var yBounds = [_this.height, 0];

        // Get the current zoom frame based on the current dimensions.
        var frame = {
            x1: xBounds[0],
            x2: xBounds[1],
            y1: yBounds[0],
            y2: yBounds[1]
        };

        var TOLERANCE = .0;

        /*
         * If there is no current zoom frame, or if any of the suggested frame
         * points extend outside of the current zoom frame, then expand the
         * canvas.
         */
        if (!_this.isCanvasPreviouslyExpanded || suggestedFrame.x1 < frame.x1 * (1 - TOLERANCE) || suggestedFrame.x2 > frame.x2 * (1 + TOLERANCE) || suggestedFrame.y2 < frame.y2 * (1 - TOLERANCE) || suggestedFrame.y1 > frame.y1 * (1 + TOLERANCE)) {
            /*
             * If there is already a zoom frame, then clamp the suggested frame
             * points to only zoom out and expand the canvas.
             *
             * If any of x1, x2, y1, or y2 is within the current frame
             * boundaries, then clamp them to the frame boundaries. If any of
             * the above values will translate into a data value that is outside
             * of the possible data range, then clamp them to the frame
             * coordinate that corresponds to the maximum data value that can
             * be displayed.
             */
            if (_this.isCanvasPreviouslyExpanded) {
                /*
                 * Calculate bounds and bumped scale for calculating the data boundaries
                 * to which the suggested frame points need to be clamped.
                 */
                var xBoundsBumped = _this._rangeBump(xBounds);
                var yBoundsBumped = _this._rangeBump(yBounds);

                var xScaleBoundsBumped = _this.xScale.copy().range(xBoundsBumped);
                var yScaleBoundsBumped = _this.yScale.copy().range(yBoundsBumped);

                var xDataBounds = [xScaleBoundsBumped.invert(xBounds[0]), xScaleBoundsBumped.invert(xBounds[1])];
                var yDataBounds = [yScaleBoundsBumped.invert(yBounds[0]), yScaleBoundsBumped.invert(yBounds[1])];

                if (suggestedFrame.x1 > 0) suggestedFrame.x1 = 0;else if (_this.xScale.invert(suggestedFrame.x1) < xDataBounds[0]) suggestedFrame.x1 = _this.xScale(xDataBounds[0]);

                if (suggestedFrame.x2 < _this.width) suggestedFrame.x2 = _this.width;else if (_this.xScale.invert(suggestedFrame.x2) > xDataBounds[1]) suggestedFrame.x2 = _this.xScale(xDataBounds[1]);

                if (suggestedFrame.y1 < _this.height) suggestedFrame.y1 = _this.height;else if (_this.yScale.invert(suggestedFrame.y1) < yDataBounds[0]) suggestedFrame.y1 = _this.yScale(yDataBounds[0]);

                if (suggestedFrame.y2 > 0) suggestedFrame.y2 = 0;else if (_this.yScale.invert(suggestedFrame.y2) > yDataBounds[1]) suggestedFrame.y2 = _this.yScale(yDataBounds[1]);
            }

            _this.isCanvasPreviouslyExpanded = true;
            this._zoomOnRectangle(_this.element, suggestedFrame.x1, suggestedFrame.y1, suggestedFrame.x2, suggestedFrame.y2, false, duration);
        } else {
            _this.redrawDataPoints(duration);
        }
    },

    zoomToMaxMin: function zoomToMaxMin(zoomedMinX, zoomedMaxX, zoomedMinY, zoomedMaxY, duration, dontFeedToState) {
        var _this = this.context;
        var minX = zoomedMinX;
        var maxX = zoomedMaxX;
        var minY = zoomedMinY;
        var maxY = zoomedMaxY;
        var zoomer = this.zoomer;

        var xRangeBounds = [0, _this.width];
        var yRangeBounds = [_this.height, 0];
        var xRangeBoundsBumped = _this._rangeBump(xRangeBounds);
        var yRangeBoundsBumped = _this._rangeBump(yRangeBounds);

        var xDomain = _this.xScale.domain();
        var yDomain = _this.yScale.domain();

        /*
         * Prevent zoomout if only one of zoom edges set outside domain
         */
        if (minX < xDomain[0] && maxX < xDomain[1]) minX = xDomain[0];
        if (minX > xDomain[0] && maxX > xDomain[1]) maxX = xDomain[1];
        if (minY < yDomain[0] && maxY < yDomain[1]) minY = yDomain[0];
        if (minY > yDomain[0] && maxY > yDomain[1]) maxY = yDomain[1];

        var zoomXOut = minX <= xDomain[0] && xDomain[1] <= maxX && xDomain[1] - xDomain[0] < maxX - zoomedMinX;
        var zoomYOut = minY <= yDomain[0] && yDomain[1] <= maxY && yDomain[1] - yDomain[0] < maxY - zoomedMinY;

        /*
         * Define TOLERANCE value as Number.EPSILON if exists, otherwise use
         * ES6 standard value.
         */
        var TOLERANCE = Number.EPSILON ? Number.EPSILON : 2.220446049250313e-16;

        /*
         * Check if the range bump region is currently displayed, i.e. for the
         * minX range bump region, check:
         * _this.xScale.invert(xRangeBounds[0]) < _this.xScale.domain()[0]
         *
         * Also check if the given min/max values equal the domain edges.
         * If so, then set the min/max values according to their range bumped
         * values. These values are used to calculate the correct rectangle
         * points for zooming.
         */
        if (_this.xScale.invert(xRangeBounds[0]) < xDomain[0] && !zoomXOut && Math.abs(minX - xDomain[0]) < TOLERANCE) {
            minX = _this.xScale.invert(xRangeBounds[0]);
        }

        if (_this.xScale.invert(xRangeBounds[1]) > xDomain[1] && !zoomXOut && Math.abs(maxX - xDomain[1]) < TOLERANCE) {
            maxX = _this.xScale.invert(xRangeBounds[1]);
        }

        if (_this.yScale.invert(yRangeBounds[0]) < yDomain[0] && !zoomYOut && Math.abs(minY - yDomain[0]) < TOLERANCE) {
            minY = _this.yScale.invert(yRangeBounds[0]);
        }

        if (_this.yScale.invert(yRangeBounds[1]) > yDomain[1] && !zoomYOut && Math.abs(maxY - yDomain[1]) < TOLERANCE) {
            maxY = _this.yScale.invert(yRangeBounds[1]);
        }

        var xRange = [_this.xScale(minX), _this.xScale(maxX)];
        var yRange = [_this.yScale(minY), _this.yScale(maxY)];

        /*
         * Calculate correct pan for zoom out
         * Expand ranges to viewport and after shift them to pan
         */
        if (zoomXOut) {
            if (zoomedMaxX >= xDomain[1] && zoomedMinX <= xDomain[0]) {
                var scale = Math.abs(_this.xScale(xDomain[1]) - _this.xScale(xDomain[0])) / Math.abs(xRange[1] - xRange[0]);
                var bump = Math.abs(xRangeBoundsBumped[0] - xRangeBounds[0]);
                var deltaVB = Math.abs(xRangeBounds[1] - xRangeBounds[0]);
                var deltaVBBumped = Math.abs(xRangeBoundsBumped[1] - xRangeBoundsBumped[0]);

                var scaledPanX = zoomer.translate()[0] - zoomer.scale() * zoomer.ratioX * (1 / scale - 1) * (bump + deltaVBBumped * Math.abs(_this.xScale(xDomain[0]) - xRange[0]) / Math.abs(xRange[1] - _this.xScale(xDomain[1]) + Math.abs(_this.xScale(xDomain[0]) - xRange[0])));
                xRange[1] = (xRange[1] - xRange[0]) * deltaVB / deltaVBBumped + scaledPanX;
                xRange[0] = scaledPanX;
            }
        }

        if (zoomYOut) {
            if (zoomedMaxY >= yDomain[1] && zoomedMinY <= yDomain[0]) {
                var scale = Math.abs(_this.yScale(yDomain[0]) - _this.yScale(yDomain[1])) / Math.abs(yRange[0] - yRange[1]);
                var bump = Math.abs(yRangeBoundsBumped[1] - yRangeBounds[1]);
                var deltaVB = Math.abs(yRangeBounds[0] - yRangeBounds[1]);
                var deltaVBBumped = Math.abs(yRangeBoundsBumped[0] - yRangeBoundsBumped[1]);

                var scaledPanY = zoomer.translate()[1] - zoomer.scale() * zoomer.ratioY * (1 / scale - 1) * (bump + deltaVBBumped * Math.abs(_this.yScale(yDomain[1]) - yRange[1]) / (Math.abs(_this.yScale(yDomain[0]) - yRange[0]) + Math.abs(yRange[1] - _this.yScale(yDomain[1]))));
                yRange[0] = (yRange[0] - yRange[1]) * deltaVB / deltaVBBumped + scaledPanY;
                yRange[1] = scaledPanY;
            }
        }

        this._zoomOnRectangle(_this.element, xRange[0], yRange[0], xRange[1], yRange[1], false, duration, dontFeedToState);
    },

    _zoomOnRectangle: function _zoomOnRectangle(element, zoomedX1, zoomedY1, zoomedX2, zoomedY2, compensateDragging, duration, dontFeedToState) {
        var _this = this.context;
        var zoomer = this.zoomer;

        var x1 = zoomedX1;
        var y1 = zoomedY1;
        var x2 = zoomedX2;
        var y2 = zoomedY2;

        /*
         * When dragging to draw a rectangle, the translate vector has (x2 - x1)
         * added to zoomer.translate()[0], and (y2 - 1) added to
         * zoomer.translate()[1].
         *
         * We need to compensate for this addition when
         * zooming with a rectangle, because zooming with a rectangle will
         * update the translate vector with new values based on the rectangle
         * dimensions.
         */
        if (compensateDragging) {
            zoomer.translate([zoomer.translate()[0] + x1 - x2, zoomer.translate()[1] + y1 - y2]);
        }

        var xRangeBounds = [0, _this.width];
        var yRangeBounds = [_this.height, 0];

        var xDomain = _this.xScale.domain();
        var yDomain = _this.yScale.domain();

        var zoomXOut = zoomer.scale() * zoomer.ratioX < 1;
        var zoomYOut = zoomer.scale() * zoomer.ratioY < 1;

        /*
         * If the min or max of one axis lies in the range bump region, then
         * changing the opposite end of that axis must correctly scale and
         * maintain the range bump region.
         */

        if (_this.xScale.invert(x1) < xDomain[0] && x1 >= xRangeBounds[0] && !zoomXOut) {
            x1 = this._scaleCoordinate(x1, xRangeBounds[1] - x2, _this.xScale.range()[0], xRangeBounds[1]);
        } else if (_this.xScale.invert(x2) < xDomain[0] && x2 >= xRangeBounds[0] && !zoomXOut) {
            x2 = this._scaleCoordinate(x2, xRangeBounds[1] - x1, _this.xScale.range()[0], xRangeBounds[1]);
        }

        if (_this.xScale.invert(x2) > xDomain[1] && x2 <= xRangeBounds[1] && !zoomXOut) {
            x2 = this._scaleCoordinate(x2, x1 - xRangeBounds[0], _this.xScale.range()[1], xRangeBounds[0]);
        } else if (_this.xScale.invert(x1) > xDomain[1] && x1 <= xRangeBounds[1] && !zoomXOut) {
            x1 = this._scaleCoordinate(x1, x2 - xRangeBounds[0], _this.xScale.range()[1], xRangeBounds[0]);
        }

        if (_this.yScale.invert(y1) < yDomain[0] && y1 <= yRangeBounds[0] && !zoomYOut) {
            y1 = this._scaleCoordinate(y1, y2 - yRangeBounds[1], _this.yScale.range()[0], yRangeBounds[1]);
        } else if (_this.yScale.invert(y2) < yDomain[0] && y2 <= yRangeBounds[0] && !zoomYOut) {
            y2 = this._scaleCoordinate(y2, y1 - yRangeBounds[1], _this.yScale.range()[0], yRangeBounds[1]);
        }

        if (_this.yScale.invert(y2) > yDomain[1] && y2 >= yRangeBounds[1] && !zoomYOut) {
            y2 = this._scaleCoordinate(y2, yRangeBounds[0] - y1, _this.yScale.range()[1], yRangeBounds[0]);
        } else if (_this.yScale.invert(y1) > yDomain[1] && y1 >= yRangeBounds[1] && !zoomYOut) {
            y1 = this._scaleCoordinate(y1, yRangeBounds[0] - y2, _this.yScale.range()[1], yRangeBounds[0]);
        }

        var minZoom = zoomer.scaleExtent()[0];
        var maxZoom = zoomer.scaleExtent()[1];

        if (Math.abs(x1 - x2) > Math.abs(y1 - y2)) {
            var zoom = _this.height / Math.abs(y1 - y2) * zoomer.scale();

            /*
             * Clamp the zoom scalar to the maximum zoom allowed before
             * calculating the next ratioX and ratioY.
             */
            if (zoom < minZoom) {
                zoomer.ratioY *= zoom / zoomer.scale();
                zoom = minZoom;
            }
            if (zoom > maxZoom) zoom = maxZoom;

            var ratioX = _this.width / Math.abs(x1 - x2) * zoomer.scale() / zoom * zoomer.ratioX;
            var ratioY = zoomer.ratioY;
        } else {
            var zoom = _this.width / Math.abs(x1 - x2) * zoomer.scale();

            /*
             * Clamp the zoom scalar to the maximum zoom allowed before
             * calculating the next ratioX and ratioY.
             */
            if (zoom < minZoom) {
                zoomer.ratioX *= zoom / zoomer.scale();
                zoom = minZoom;
            }
            if (zoom > maxZoom) zoom = maxZoom;

            var ratioY = _this.height / Math.abs(y1 - y2) * zoomer.scale() / zoom * zoomer.ratioY;
            var ratioX = zoomer.ratioX;
        }

        var pan = [(zoomer.translate()[0] - Math.min(x1, x2)) / zoomer.scale() / zoomer.ratioX * zoom * ratioX, (zoomer.translate()[1] - Math.min(y1, y2)) / zoomer.scale() / zoomer.ratioY * zoom * ratioY];

        zoomer.dontFeedToState = dontFeedToState;
        zoomer.scale(zoom);
        zoomer.ratioY = ratioY;
        zoomer.ratioX = ratioX;
        zoomer.translate(pan);
        zoomer.duration = duration ? duration : 0;

        zoomer.event(element);
    },

    /*
     * Helper function that returns a scaled coordinate value based on the
     * distance between the given coordinate and the data boundary.
     */
    _scaleCoordinate: function _scaleCoordinate(coordValue, scaleDifference, dataBoundary, viewportBoundary) {
        var scalar = scaleDifference / Math.abs(dataBoundary - viewportBoundary);
        return (coordValue - dataBoundary) * (1 - scalar) + dataBoundary;
    },

    /*
     * Calculate a proportional reduction of the scalar value. Also,
     * calculate the reduction of the value by a constant of 1.
     *
     * Return the larger of the two calculated values.
     */
    _scaleToMin: function _scaleToMin(scalar, minScalar, proportion, constant) {
        var scalarProportionDelta = (scalar - minScalar) * proportion;
        var scalarDifferenceDelta = Math.max(constant, minScalar - constant);
        var scalarDelta = Math.max(scalarProportionDelta, scalarDifferenceDelta);

        return scalarDelta;
    },

    /*
     * Incrementally zoom in or out and pan the view so that it never looses the point where click happened
     * this function is a modified d3's own zoom behavior on double click
     * for the original code see https://github.com/mbostock/d3/blob/master/src/behavior/zoom.js
     * function dblclicked() and what it refers to
     */
    zoomByIncrement: function zoomByIncrement(direction, duration) {
        var _this = this.context;

        var ratio = this.zoomer.scale();
        var pan = [this.zoomer.translate()[0], this.zoomer.translate()[1]];

        var mouse = d3.mouse(_this.element.node());
        var k = Math.log(ratio) / Math.LN2;

        //change factor direction based on the input. default is no direction supplied
        if (direction == "plus" || !direction) k = Math.floor(k) + 1;
        if (direction == "minus") k = Math.ceil(k) - 1;

        //decode panning
        var locus = [(mouse[0] - pan[0]) / ratio, (mouse[1] - pan[1]) / ratio];

        //recalculate zoom ratio
        var scaleExtent = this.zoomer.scaleExtent();
        if (ratio == scaleExtent[0]) {
            this.zoomer.ratioY = 1;
            this.zoomer.ratioX = 1;
        }
        ratio = Math.max(scaleExtent[0], Math.min(scaleExtent[1], Math.pow(2, k)));

        //recalculate panning
        locus = [locus[0] * ratio + pan[0], locus[1] * ratio + pan[1]];
        pan[0] += mouse[0] - locus[0];
        pan[1] += mouse[1] - locus[1];

        //save changes to the zoom behavior and run the event
        this.zoomer.scale(ratio);
        this.zoomer.translate([pan[0], pan[1]]);
        this.zoomer.duration = duration || 0;
        this.zoomer.event(_this.element);
    },

    /*
     * Reset zoom values without triggering a zoom event.
     */
    resetZoomState: function resetZoomState(element) {
        this.zoomer.scale(1);
        this.zoomer.ratioY = 1;
        this.zoomer.ratioX = 1;
        this.zoomer.translate([0, 0]);
    },

    reset: function reset(element, duration) {
        var _this = this.context;
        _this.isCanvasPreviouslyExpanded = false;

        this.zoomer.scale(1);
        this.zoomer.ratioY = 1;
        this.zoomer.ratioX = 1;
        this.zoomer.translate([0, 0]);
        this.zoomer.duration = duration || 0;
        this.zoomer.event(element || _this.element);
    },

    rerun: function rerun(element) {
        var _this = this.context;
        this.zoomer.event(element || _this.element);
    }
});

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _class = __webpack_require__(21);

var _class2 = _interopRequireDefault(_class);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

exports.default = _class2.default.extend({

  init: function init(context) {
    this.context = context;
    this._isCreated = null;
    this.actionsQueue = {};
    this.entityTrails = {};
    this.trailsData = [];
    this.trailsInProgress = {};
    this.activePromises = {};
    this.trailTransitions = {};
    this.delayedIterations = {};
    this.drawingQueue = {};
  },

  toggle: function toggle(arg) {
    var _context = this.context;
    if (arg) {

      _context._trails.create().then(function () {
        _context._trails.run(["findVisible", "reveal", "opacityHandler"]);
      });
    } else {
      _context._trails.run("remove");
      _context.model.marker.select.forEach(function (d) {
        d.trailStartTime = null;
      });
    }
  },

  create: function create(selection) {
    var _context = this.context;
    var _this = this;
    var KEY = _context.KEY;
    var TIMEDIM = _context.TIMEDIM;
    this._isCreated = new Promise(function (resolve, reject) {
      //quit if the function is called accidentally
      if (!_context.model.ui.chart.trails) return;

      var timePoints = _context.model.time.getAllSteps();

      //work with marker.select (all selected entities), if no particular selection is specified
      var promises = [];
      selection = selection == null ? _context.model.marker.select : [selection];
      _this._clearActions(selection);
      _this.trailsData = _context.model.marker.select.map(function (d) {
        var r = {
          status: "created",
          selectedEntityData: d
        };
        r[KEY] = d[KEY];
        return r;
      });
      _this.trailTransitions = {};
      var _trails = _context.bubbleContainer.selectAll('g.vzb-bc-entity.entity-trail').data(_this.trailsData, function (d) {
        return d[KEY];
      });

      _trails.exit().remove();
      _trails.enter().insert("g", function (d) {
        return this.querySelector(".bubble-" + d[KEY]);
      }).attr("class", function (d) {
        return "vzb-bc-entity entity-trail trail-" + d[KEY];
      });
      _trails.each(function (d, index) {
        // used for prevent move trail start time forward when we have empty values at end of time range
        var trail = this;
        promises.push(new Promise(function (resolve, reject) {
          var trailSegmentData = timePoints.map(function (m) {
            return {
              t: m,
              key: d[KEY]
            };
          });
          _this.entityTrails[d[KEY]] = d3.select(trail).selectAll("g").data(trailSegmentData).classed("vzb-invisible", true);

          _this.entityTrails[d[KEY]].exit().remove();

          _this.entityTrails[d[KEY]].enter().append("g").attr("class", "vzb-bc-trailsegment").on("mouseover", function (segment, index) {
            if (utils.isTouchDevice()) return;

            var pointer = {};
            pointer[KEY] = segment.key;
            pointer[TIMEDIM] = segment.t;

            _context._axisProjections(pointer);
            _context._labels.highlight(d, true);
            var text = _context.model.time.formatDate(segment.t);
            var selectedData = utils.find(_context.model.marker.select, function (f) {
              return f[KEY] == d[KEY];
            });
            _context.model.marker.getFrame(pointer[TIMEDIM], function (values) {
              var x = _context.xScale(values.axis_x[pointer[KEY]]);
              var y = _context.yScale(values.axis_y[pointer[KEY]]);
              var s = utils.areaToRadius(_context.sScale(values.size[pointer[KEY]]));
              var c = values.color[pointer[KEY]] != null ? _context.cScale(values.color[pointer[KEY]]) : _context.COLOR_WHITEISH;
              if (text !== selectedData.trailStartTime) {
                _context._setTooltip(text, x, y, s + 3, c);
              }
              _context._setBubbleCrown(x, y, s, c);
              _context.model.marker.getModelObject("highlight").trigger('change', { 'size': values.size[pointer[KEY]], 'color': values.color[pointer[KEY]] });
            });
            //change opacity to OPACITY_HIGHLT = 1.0;
            d3.select(this).style("opacity", 1.0);
          }).on("mouseout", function (segment, index) {
            if (utils.isTouchDevice()) return;
            _context._axisProjections();
            _context._setTooltip();
            _context._setBubbleCrown();
            _context._labels.highlight(null, false);
            _context.model.marker.getModelObject("highlight").trigger('change', null);
            d3.select(this).style("opacity", _context.model.marker.opacityRegular);
          }).each(function (segment, index) {
            var view = d3.select(this);
            view.append("circle");
            view.append("line");
          });
          resolve();
        }));
      });
      if (promises.length > 0) {
        Promise.all(promises).then(function (segments) {
          resolve(true);
        });
      } else {
        resolve(true);
      }
    });
    return this._isCreated;
  },

  /**
   * add actions for each selected entities
   * @param selections
   * @param actions
   * @private
   */
  _addActions: function _addActions(selections, actions) {
    var _context = this.context;
    var _this = this;
    var KEY = _context.KEY;

    selections.forEach(function (d) {
      if (!_this.actionsQueue[d[KEY]]) _this.actionsQueue[d[KEY]] = [];
      _this.actionsQueue[d[KEY]] = [].concat(_this.actionsQueue[d[KEY]].filter(function (value) {
        return actions.indexOf(value) == -1;
      }), actions);
    });
  },

  _clearActions: function _clearActions(selections) {
    var _context = this.context;
    var _this = this;
    var KEY = _context.KEY;

    selections.forEach(function (d) {
      if (!_this.actionsQueue[d[KEY]]) _this.actionsQueue[d[KEY]] = [];
      _this.actionsQueue[d[KEY]] = [];
      _this.drawingQueue[d[KEY]] = {};
      _this.delayedIterations[d[KEY]] = {};
      if (!_this.activePromises[d[KEY]]) _this.activePromises[d[KEY]] = [];
      utils.forEach(_this.activePromises[d[KEY]], function (promise, key) {
        if (promise.status === "pending") promise.reject();
      });
      _this.trailsInProgress[d[KEY]] = null;
      _this.activePromises[d[KEY]] = [];
    });
  },

  _getNextAction: function _getNextAction(key) {
    return this.actionsQueue[key].shift();
  },

  run: function run(actions, selection, duration) {
    var _context = this.context;
    var _this = this;
    var KEY = _context.KEY;
    if (!this._isCreated || _context.model.time.splash) return;
    if (typeof actions == "string") actions = [actions];

    this._isCreated.then(function () {
      //quit if function is called accidentally
      if ((!_context.model.ui.chart.trails || !_context.model.marker.select.length) && actions != "remove") return;

      if (!duration) duration = 0;

      //work with marker.select (all selected entities), if no particular selection is specified
      selection = selection == null ? _context.model.marker.select : [selection];
      for (var i = 0; i < actions.length; i++) {
        if (["resize", "recolor"].indexOf(actions[i]) != -1) {
          var action = actions.splice(i, 1).pop();
          --i;
          _this.trailsData.forEach(function (d) {
            var trail = _this.entityTrails[d[KEY]];
            _context._trails["_" + action](trail, duration, d);
          });
        }
      }
      if (actions.length == 0) {
        return;
      }
      _this._addActions(selection, actions);
      _this.trailsData.forEach(function (d) {
        if (actions.indexOf('findVisible') != -1) {
          _this.drawingQueue[d[KEY]] = {};
          _this.delayedIterations[d[KEY]] = {};
        }
        var trail = _this.entityTrails[d[KEY]];
        //do all the actions over "trail"
        var executeSequential = function executeSequential(index) {
          // some function can be async, but we should run next when previous completed
          var action = _this._getNextAction(d[KEY]);
          if (action) {
            _this.trailsInProgress[d[KEY]] = action;
            var response = _context._trails["_" + action](trail, duration, d);
            if (response && response instanceof Promise) {
              response.then(function () {
                _this.trailsInProgress[d[KEY]] = null;
                executeSequential(index + 1);
              }, function () {
                _this.trailsInProgress[d[KEY]] = null;
              });
            } else {
              _this.trailsInProgress[d[KEY]] = null;
              executeSequential(index + 1);
            }
          }
        };
        if (!_this.trailsInProgress[d[KEY]]) {
          executeSequential(0);
        }
      });
    });
  },

  _remove: function _remove(trail, duration, d) {
    this.actionsQueue[d[this.context.KEY]] = [];
    if (trail) {
      // TODO: in some reason run twice
      d3.select(this.entityTrails[d[this.context.KEY]].node().parentNode).remove();
      this.entityTrails[d[this.context.KEY]] = null;
    }
  },

  _resize: function _resize(trail, duration, d) {
    var _context = this.context;
    if (_context.model.time.splash) {
      return;
    }
    //    this._isCreated.then(function() {
    var updateLabel = false;

    trail.each(function (segment, index) {

      if (segment.valueY == null || segment.valueX == null || segment.valueS == null) return;

      var view = d3.select(this);
      if (duration) {
        view.select("circle").transition().duration(duration).ease("linear").attr("cy", _context.yScale(segment.valueY)).attr("cx", _context.xScale(segment.valueX)).attr("r", utils.areaToRadius(_context.sScale(segment.valueS)));
      } else {
        view.select("circle").interrupt().attr("cy", _context.yScale(segment.valueY)).attr("cx", _context.xScale(segment.valueX)).attr("r", utils.areaToRadius(_context.sScale(segment.valueS))).transition();
      }

      if (!updateLabel && !segment.transparent) {
        updateLabel = true;
        _context._labels.updateLabelOnlyPosition(d, null, { 'scaledS0': utils.areaToRadius(_context.sScale(segment.valueS)) });
      }

      if (!segment.next) return;
      var next = segment.next;
      if (next == null) return;
      if (next.valueY == null || next.valueX == null) return;

      var lineLength = Math.sqrt(Math.pow(_context.xScale(segment.valueX) - _context.xScale(next.valueX), 2) + Math.pow(_context.yScale(segment.valueY) - _context.yScale(next.valueY), 2));
      if (duration) {
        view.select("line").transition().duration(duration).ease("linear").attr("x1", _context.xScale(next.valueX)).attr("y1", _context.yScale(next.valueY)).attr("x2", _context.xScale(segment.valueX)).attr("y2", _context.yScale(segment.valueY)).style("stroke-dasharray", lineLength).style("stroke-dashoffset", utils.areaToRadius(_context.sScale(segment.valueS)));
      } else {
        view.select("line").interrupt().attr("x1", _context.xScale(next.valueX)).attr("y1", _context.yScale(next.valueY)).attr("x2", _context.xScale(segment.valueX)).attr("y2", _context.yScale(segment.valueY)).style("stroke-dasharray", lineLength).style("stroke-dashoffset", utils.areaToRadius(_context.sScale(segment.valueS))).transition();
      }
    });
  },

  _recolor: function _recolor(trail, duration, d) {
    var _context = this.context;

    trail.each(function (segment, index) {

      var view = d3.select(this);

      var strokeColor = _context.model.marker.color.which == "geo.world_4region" ?
      //use predefined shades for color palette for "geo.world_4region" (hardcoded)
      _context.model.marker.color.getColorShade({
        colorID: segment.valueC,
        shadeID: "shade"
      }) :
      //otherwise use color of the bubble with a fallback to bubble stroke color (blackish)
      segment.valueC != null ? _context.cScale(segment.valueC) : _context.COLOR_BLACKISH;

      view.select("circle")
      //.transition().duration(duration).ease("linear")
      .style("fill", segment.valueC != null ? _context.cScale(segment.valueC) : _context.COLOR_WHITEISH);
      view.select("line")
      //.transition().duration(duration).ease("linear")
      .style("stroke", strokeColor);
    });
  },

  _opacityHandler: function _opacityHandler(trail, duration, d) {
    var _context = this.context;

    trail.each(function (segment, index) {

      var view = d3.select(this);

      view
      //.transition().duration(duration).ease("linear")
      .style("opacity", d.opacity || _context.model.marker.opacityRegular);
    });
  },

  _findVisible: function _findVisible(trail, duration, d) {
    var _context = this.context;
    var _this = this;
    var KEY = _context.KEY;
    return new Promise(function (resolve, reject) {
      new Promise(function (resolve1, reject1) {
        if (!d.limits) {
          _context.model.marker.getEntityLimits(d[KEY]).then(function (limits) {
            d.limits = limits;
            resolve1();
          });
        } else {
          resolve1();
        }
      }).then(function () {
        if (!d.selectedEntityData.trailStartTime) {
          d.selectedEntityData.trailStartTime = _context.model.time.formatDate(_context.time);
        }
        var trailStartTime = _context.model.time.parse("" + d.selectedEntityData.trailStartTime);
        if (_context.time - trailStartTime < 0 || d.limits.min - trailStartTime > 0) {
          if (_context.time - trailStartTime < 0) {
            // move trail start time with trail label back if need
            d.selectedEntityData.trailStartTime = _context.model.time.formatDate(d3.max([_context.time, d.limits.min]));
            trailStartTime = _context.model.time.parse("" + d.selectedEntityData.trailStartTime);
          } else {
            // move trail start time with trail label to start time if need
            d.selectedEntityData.trailStartTime = _context.model.time.formatDate(d.limits.min);
            trailStartTime = _context.model.time.parse("" + d.selectedEntityData.trailStartTime);
          }
          var cache = _context._labels.cached[d[KEY]];
          var valueS = _context.frame.size[d[KEY]];
          var valueC = _context.frame.color[d[KEY]];
          cache.labelX0 = _context.frame.axis_x[d[KEY]];
          cache.labelY0 = _context.frame.axis_y[d[KEY]];
          cache.scaledS0 = valueS || valueS === 0 ? utils.areaToRadius(_context.sScale(valueS)) : null;
          cache.scaledC0 = valueC != null ? _context.cScale(valueC) : _context.COLOR_WHITEISH;
          _context._updateLabel(d, 0, _context.frame.axis_x[d[KEY]], _context.frame.axis_y[d[KEY]], _context.frame.size[d[KEY]], _context.frame.color[d[KEY]], _context.frame.label[d[KEY]], _context.frame.size_label[d[KEY]], 0, true);
        }
        trail.each(function (segment, index) {
          // segment is transparent if it is after current time or before trail StartTime
          var segmentVisibility = segment.transparent;
          segment.transparent = d.selectedEntityData.trailStartTime == null || segment.t - _context.time > 0 || trailStartTime - segment.t > 0
          //no trail segment should be visible if leading bubble is shifted backwards, beyond start time
          || d.selectedEntityData.trailStartTime - _context.model.time.formatDate(_context.time) >= 0;
          // always update nearest 2 points
          if (segmentVisibility != segment.transparent || Math.abs(_context.model.time.formatDate(segment.t) - _context.model.time.formatDate(_context.time)) < 2) segment.visibilityChanged = true; // segment changed, so need to update it
          if (segment.transparent) {
            d3.select(trail[0][index]).classed("vzb-invisible", segment.transparent);
          }
        });
        _this.drawingQueue[d[KEY]] = {};
        _this.delayedIterations[d[KEY]] = {};
        resolve();
      });
    });
  },

  _abortAnimation: function _abortAnimation() {
    var _context = this.context;
    var _this = this;
    var KEY = _context.KEY;
    _this.trailsData.forEach(function (d) {
      if (_this.trailTransitions[d[KEY]]) {
        _this.trailTransitions[d[KEY]].select('line').interrupt().transition();
      }
    });
  },

  _reveal: function _reveal(trail, duration, d) {
    var _context = this.context;
    var _this = this;
    var KEY = _context.KEY;
    d.status = "reveal";
    var trailStartTime = _context.model.time.parse("" + d.selectedEntityData.trailStartTime);
    var generateTrailSegment = function generateTrailSegment(trail, index, nextIndex, level) {
      return new Promise(function (resolve, reject) {
        var view = d3.select(trail[0][index]);

        var segment = view.datum();

        //console.log(d[KEY] + " transparent: " + segment.transparent + " vis_changed:" + segment.visibilityChanged);
        if (nextIndex - index == 1) {
          if (segment.transparent) {
            view.classed("vzb-invisible", segment.transparent);
            return resolve();
          } else if (!segment.visibilityChanged) {
            // pass segment if it is not changed
            return resolve();
          }
        }
        _context.model.marker.getFrame(segment.t, function (frame) {
          if (d.status != "reveal") return resolve();
          if (!frame) return resolve();
          segment.valueY = frame.axis_y[d[KEY]];
          segment.valueX = frame.axis_x[d[KEY]];
          segment.valueS = frame.size[d[KEY]];
          segment.valueC = frame.color[d[KEY]];

          if (segment.valueY == null || segment.valueX == null || segment.valueS == null) {
            return resolve();
          } else {
            // fix label position if it not in correct place
            if (trailStartTime && trailStartTime.toString() == segment.t.toString()) {
              var cache = _context._labels.cached[d[KEY]];
              cache.labelX0 = segment.valueX;
              cache.labelY0 = segment.valueY;
              var valueS = segment.valueS;
              cache.scaledS0 = valueS || valueS === 0 ? utils.areaToRadius(_context.sScale(valueS)) : null;
              cache.scaledC0 = segment.valueC != null ? _context.cScale(segment.valueC) : _context.COLOR_WHITEISH;
              _context._updateLabel(d, index, segment.valueX, segment.valueY, segment.valueS, segment.valueC, frame.label[d[KEY]], frame.size_label[d[KEY]], 0, true);
            }
            view.select("circle")
            //.transition().duration(duration).ease("linear")
            .attr("cy", _context.yScale(segment.valueY)).attr("cx", _context.xScale(segment.valueX)).attr("r", utils.areaToRadius(_context.sScale(segment.valueS))).style("fill", segment.valueC != null ? _context.cScale(segment.valueC) : _context.COLOR_WHITEISH);

            view.select("line").attr("x2", _context.xScale(segment.valueX)).attr("y2", _context.yScale(segment.valueY)).attr("x1", _context.xScale(segment.valueX)).attr("y1", _context.yScale(segment.valueY));

            // last point should have data for line but it is invisible
            if (_context.time - segment.t > 0) {
              segment.visibilityChanged = false;
              view.classed("vzb-invisible", segment.transparent);
            } else {
              view.classed("vzb-invisible", true);
            }

            if (!trail[0][nextIndex] || _context.time.toString() == segment.t.toString()) {
              return resolve();
            } else {
              var next = d3.select(trail[0][nextIndex]);
              var nextSegment = next.datum();
              nextSegment.previous = segment;
              segment.next = nextSegment;
              var nextTime = nextSegment.t;
              if (_context.time - nextSegment.t < 0) {
                // time is not equal start of year
                segment.visibilityChanged = true; // redraw needed next time because line not have full length
                nextTime = _context.time;
              }
              _context.model.marker.getFrame(nextTime, function (nextFrame) {
                if (d.status != "reveal") return resolve();
                if (!nextFrame || segment.valueY == null || segment.valueX == null || segment.valueS == null) {
                  return resolve();
                } else {
                  if (nextFrame.axis_x[d[KEY]] == null || nextFrame.axis_y[d[KEY]] == null) {
                    return resolve();
                  } else {
                    nextSegment.valueY = nextFrame.axis_y[d[KEY]];
                    nextSegment.valueX = nextFrame.axis_x[d[KEY]];
                    nextSegment.valueS = nextFrame.size[d[KEY]];
                    nextSegment.valueC = nextFrame.color[d[KEY]];

                    _this.trailTransitions[d[KEY]] = view;
                    var strokeColor = _context.model.marker.color.which == "geo.world_4region" ?
                    //use predefined shades for color palette for "geo.world_4region" (hardcoded)
                    _context.model.marker.color.getColorShade({
                      colorID: segment.valueC,
                      shadeID: "shade"
                    }) :
                    //otherwise use color of the bubble with a fallback to bubble stroke color (blackish)
                    segment.valueC != null ? _context.cScale(segment.valueC) : _context.COLOR_BLACKISH;

                    var lineLength = Math.sqrt(Math.pow(_context.xScale(segment.valueX) - _context.xScale(nextFrame.axis_x[d[KEY]]), 2) + Math.pow(_context.yScale(segment.valueY) - _context.yScale(nextFrame.axis_y[d[KEY]]), 2));
                    view.select("line").transition().duration(duration).ease("linear").attr("x1", _context.xScale(nextSegment.valueX)).attr("y1", _context.yScale(nextSegment.valueY)).attr("x2", _context.xScale(segment.valueX)).attr("y2", _context.yScale(segment.valueY)).style("stroke-dasharray", lineLength).style("stroke-dashoffset", utils.areaToRadius(_context.sScale(segment.valueS))).style("stroke", strokeColor);
                    if (nextIndex - index > 1) {
                      addNewIntervals(index, nextIndex);
                      return resolve();
                    } else {
                      return resolve();
                    }
                  }
                }
              });
            }
          }
        });
      });
    };
    var addPointBetween = function addPointBetween(previousIndex, nextIndex, index) {
      return new Promise(function (resolve, reject) {
        var previous = d3.select(trail[0][previousIndex]);
        var next = d3.select(trail[0][nextIndex]);
        var view = d3.select(trail[0][index]);
        var previousSegment = previous.datum();
        var nextSegment = next.datum();
        var segment = view.datum();

        if (!previousSegment.previous && !previousSegment.next || !nextSegment.previous && !nextSegment.next) {
          // segment data cleared by create action  
          return resolve();
        }

        _context.model.marker.getFrame(segment.t, function (frame) {
          if (d.status != "reveal") return resolve();
          if (!frame || typeof frame.axis_x == "undefined" || frame.axis_x[d[KEY]] == null || typeof frame.axis_y == "undefined" || frame.axis_y[d[KEY]] == null) {
            utils.warn("Frame for trail missed: " + segment.t);
            return resolve();
          }
          segment.valueY = frame.axis_y[d[KEY]];
          segment.valueX = frame.axis_x[d[KEY]];
          segment.valueS = frame.size[d[KEY]];
          segment.valueC = frame.color[d[KEY]];

          segment.previous = previousSegment;
          segment.next = nextSegment;
          previousSegment.next = segment;
          nextSegment.previous = segment;

          if (segment.valueY == null || segment.valueX == null || segment.valueS == null) {
            utils.warn("Data for trail point missed: " + segment.t);
            return resolve();
          }

          var strokeColor = _context.model.marker.color.which == "geo.world_4region" ?
          //use predefined shades for color palette for "geo.world_4region" (hardcoded)
          _context.model.marker.color.getColorShade({
            colorID: segment.valueC,
            shadeID: "shade"
          }) :
          //otherwise use color of the bubble with a fallback to bubble stroke color (blackish)
          segment.valueC != null ? _context.cScale(segment.valueC) : _context.COLOR_BLACKISH;

          var firstLineLength = Math.sqrt(Math.pow(_context.xScale(previousSegment.valueX) - _context.xScale(segment.valueX), 2) + Math.pow(_context.yScale(previousSegment.valueY) - _context.yScale(segment.valueX), 2));

          previous.select("line").transition().duration(duration).ease("linear").attr("x1", _context.xScale(segment.valueX)).attr("y1", _context.yScale(segment.valueY)).attr("x2", _context.xScale(previousSegment.valueX)).attr("y2", _context.yScale(previousSegment.valueY)).style("stroke-dasharray", firstLineLength).style("stroke-dashoffset", utils.areaToRadius(_context.sScale(previousSegment.valueS))).style("stroke", strokeColor);

          view.classed("vzb-invisible", segment.transparent);

          if (!segment.transparent) {
            view.select("circle")
            //.transition().duration(duration).ease("linear")
            .attr("cy", _context.yScale(segment.valueY)).attr("cx", _context.xScale(segment.valueX)).attr("r", utils.areaToRadius(_context.sScale(segment.valueS))).style("fill", segment.valueC != null ? _context.cScale(segment.valueC) : _context.COLOR_WHITEISH);

            var secondLineLength = Math.sqrt(Math.pow(_context.xScale(segment.valueX) - _context.xScale(nextSegment.valueX), 2) + Math.pow(_context.yScale(segment.valueY) - _context.yScale(nextSegment.valueY), 2));

            view.select("line").transition().duration(duration).ease("linear").attr("x1", _context.xScale(nextSegment.valueX)).attr("y1", _context.yScale(nextSegment.valueY)).attr("x2", _context.xScale(segment.valueX)).attr("y2", _context.yScale(segment.valueY)).style("stroke-dasharray", secondLineLength).style("stroke-dashoffset", utils.areaToRadius(_context.sScale(segment.valueS))).style("stroke", strokeColor);
          }
          addNewIntervals(previousIndex, index, nextIndex);
          resolve();
        });
      });
    };
    var addNewIntervals = function addNewIntervals(previousIndex, index, nextIndex) {
      var mediumIndex;
      if (index - previousIndex > 1) {
        mediumIndex = getPointBetween(previousIndex, index);
        _this.delayedIterations[d[KEY]][previousIndex] = {
          first: previousIndex,
          next: index,
          medium: mediumIndex
        };
      }
      if (nextIndex && nextIndex - index > 1) {
        mediumIndex = getPointBetween(index, nextIndex);
        _this.delayedIterations[d[KEY]][index] = {
          first: index,
          next: nextIndex,
          medium: mediumIndex
        };
      }
    };
    var getPointBetween = function getPointBetween(previous, next) {
      return Math.round(previous + (next - previous) / 2);
    };

    var _generateKeys = function _generateKeys(d, trail, div) {
      var response = [];
      var min = 0,
          max = 0;
      var maxValue = d3.min([d.limits.max, _context.time]);
      var minValue = d3.max([d.limits.min, _context.model.time.parse("" + d.selectedEntityData.trailStartTime)]);
      utils.forEach(trail[0], function (segment, index) {
        var data = segment.__data__;
        if (data.t - minValue == 0) {
          min = index;
        } else if (data.t - maxValue == 0) {
          max = index;
        } else {
          if (data.t > minValue && data.t < maxValue) {
            if (_context.model.time.formatDate(data.t) % div == 0 || data.next && data.previous) {
              response.push(index);
            }
          }
        }
      });
      response.unshift(min);
      if (max > 0) {
        response.push(max);
      }
      return response;
    };

    var processPoints = function processPoints() {
      return new Promise(function (resolve, reject) {
        var processPoint = function processPoint() {
          var pointIndex = Object.keys(_this.drawingQueue[d[KEY]])[Math.floor(Math.random() * Object.keys(_this.drawingQueue[d[KEY]]).length)];
          var point = JSON.parse(JSON.stringify(_this.drawingQueue[d[KEY]][pointIndex]));
          delete _this.drawingQueue[d[KEY]][pointIndex];
          addPointBetween(point.first, point.next, point.medium).then(function () {
            if (Object.keys(_this.drawingQueue[d[KEY]]).length > 0) {
              processPoint();
            } else {
              resolve();
            }
          });
        };
        if (Object.keys(_this.drawingQueue[d[KEY]]).length > 0) {
          processPoint(_this.drawingQueue[d[KEY]]);
        } else {
          resolve();
        }
      });
    };

    return new Promise(function (resolve, reject) {
      /**
       * iteration for each point from first segment to last
       * @param trail
       * @param index
       */
      var generateTrails = function generateTrails(trail, index) {
        if (index < 0 || index >= trail[0].length) {
          return resolve();
        }
        generateTrailSegment(trail, index, index + 1).then(function () {
          generateTrails(trail, index + 1);
        }, function () {
          return resolve();
        });
      };

      /**
       * recursive iteration for drawing point between points calculated in previous step
       */
      var processPointsBetween = function processPointsBetween() {
        processPoints().then(function () {
          if (Object.keys(_this.delayedIterations[d[KEY]]).length == 0) {
            return resolve();
          } else {
            _this.drawingQueue[d[KEY]] = _this.delayedIterations[d[KEY]];
            _this.delayedIterations[d[KEY]] = {};
            processPointsBetween();
          }
        }, function () {
          return resolve();
        });
      };

      if (_context.model.marker.framesAreReady()) {
        generateTrails(trail, 0);
      } else {
        _this.delayedIterations[d[KEY]] = {};
        _this.drawingQueue[d[KEY]] = {};
        var trailKeys = _generateKeys(d, trail, 50);
        var segments = [];
        if (trailKeys.length <= 1) {
          return resolve();
        }

        _this.delayedIterations[d[KEY]] = {};
        for (var i = 0; i < trailKeys.length - 1; i++) {
          segments.push(generateTrailSegment(trail, trailKeys[i], trailKeys[i + 1], 1));
        }
        Promise.all(segments).then(function () {
          if (Object.keys(_this.delayedIterations[d[KEY]]).length == 0) {
            resolve();
          } else {
            _this.drawingQueue[d[KEY]] = _this.delayedIterations[d[KEY]];
            _this.delayedIterations[d[KEY]] = {};
            processPointsBetween();
          }
        }, function () {
          resolve();
        });
      }
    });
  }
});

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _labels = __webpack_require__(86);

var _labels2 = _interopRequireDefault(_labels);

var _iconset = __webpack_require__(10);

var _topojson = __webpack_require__(213);

var _topojson2 = _interopRequireDefault(_topojson);

var _d3Geo = __webpack_require__(135);

var _d3Geo2 = _interopRequireDefault(_d3Geo);

var _d = __webpack_require__(66);

var _d2 = _interopRequireDefault(_d);

var _globals = __webpack_require__(44);

var _globals2 = _interopRequireDefault(_globals);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

//import Selectlist from 'bubblemap-selectlist';

//BUBBLE MAP CHART COMPONENT
var BubbleMapComponent = _component2.default.extend({
  /**
   * Initializes the component (Bubble Map Chart).
   * Executed once before any template is rendered.
   * @param {Object} config The config passed to the component
   * @param {Object} context The component's parent
   */
  init: function init(config, context) {
    this.name = 'bubblemap';
    this.template = __webpack_require__(447);
    this.bubblesDrawing = null;

    //http://stackoverflow.com/questions/11381673/detecting-a-mobile-browser
    var mobileAndTabletcheck = function mobileAndTabletcheck() {
      var check = false;
      (function (a) {
        if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) check = true;
      })(navigator.userAgent || navigator.vendor || window.opera);
      return check;
    };
    this.isMobile = mobileAndTabletcheck();

    //define expected models for this component
    this.model_expects = [{
      name: "time",
      type: "time"
    }, {
      name: "entities",
      type: "entities"
    }, {
      name: "marker",
      type: "model"
    }, {
      name: "locale",
      type: "locale"
    }, {
      name: "ui",
      type: "ui"
    }];

    var _this = this;
    this.model_binds = {
      "change:time.value": function changeTimeValue(evt) {
        if (!_this._readyOnce) return;
        _this.model.marker.getFrame(_this.model.time.value, _this.frameChanged.bind(_this));
      },
      "change:marker.highlight": function changeMarkerHighlight(evt) {
        if (!_this._readyOnce) return;
        _this.highlightMarkers();
        _this.updateOpacity();
      },
      "change:marker": function changeMarker(evt, path) {
        // bubble size change is processed separately
        if (!_this._readyOnce) return;

        if (path.indexOf("scaleType") > -1) {
          _this.ready();
        }
      },
      'change:marker.size.extent': function changeMarkerSizeExtent(evt, path) {
        //console.log("EVENT change:marker:size:max");
        if (!_this._readyOnce || !_this.entityBubbles) return;
        _this.updateMarkerSizeLimits();
        _this.redrawDataPoints(null, false);
      },
      "change:marker.color.palette": function changeMarkerColorPalette(evt, path) {
        if (!_this._readyOnce) return;
        _this.redrawDataPoints(null, false);
      },
      "change:marker.select": function changeMarkerSelect(evt) {
        if (!_this._readyOnce) return;
        _this.selectMarkers();
        _this.redrawDataPoints(null, false);
        _this.updateOpacity();
        _this.updateDoubtOpacity();
      },
      "change:marker.opacitySelectDim": function changeMarkerOpacitySelectDim(evt) {
        _this.updateOpacity();
      },
      "change:marker.opacityRegular": function changeMarkerOpacityRegular(evt) {
        _this.updateOpacity();
      }
    };

    //this._selectlist = new Selectlist(this);

    //contructor is the same as any component
    this._super(config, context);

    this.sScale = null;
    this.cScale = d3.scale.category10();

    _this.COLOR_WHITEISH = "#fdfdfd";

    (0, _d3Geo2.default)();

    this._labels = new _labels2.default(this);
    this._labels.config({
      CSS_PREFIX: 'vzb-bmc',
      LABELS_CONTAINER_CLASS: 'vzb-bmc-labels',
      LINES_CONTAINER_CLASS: 'vzb-bmc-lines',
      SUPPRESS_HIGHLIGHT_DURING_PLAY: false
    });
  },

  /**
   * DOM is ready
   */
  readyOnce: function readyOnce() {

    this.element = d3.select(this.element);

    this.graph = this.element.select('.vzb-bmc-graph');
    this.mapSvg = this.element.select('.vzb-bmc-map-background');

    this.bubbleContainerCrop = this.graph.select('.vzb-bmc-bubbles-crop');
    this.bubbleContainer = this.graph.select('.vzb-bmc-bubbles');
    this.labelListContainer = this.graph.select('.vzb-bmc-bubble-labels');
    this.dataWarningEl = this.graph.select(".vzb-data-warning");

    this.yTitleEl = this.graph.select(".vzb-bmc-axis-y-title");
    this.cTitleEl = this.graph.select(".vzb-bmc-axis-c-title");
    this.yInfoEl = this.graph.select(".vzb-bmc-axis-y-info");
    this.cInfoEl = this.graph.select(".vzb-bmc-axis-c-info");

    this.entityBubbles = null;
    this.tooltip = this.element.select('.vzb-bmc-tooltip');

    // year background
    this.yearEl = this.graph.select('.vzb-bmc-year');
    this.year = new _d2.default(this.yearEl);
    this.year.setConditions({ xAlign: 'left', yAlign: 'bottom' });

    var _this = this;
    this.on("resize", function () {
      //return if updatesize exists with error
      if (_this.updateSize()) return;
      _this.updateMarkerSizeLimits();
      _this._labels.updateSize();
      _this.redrawDataPoints();
      //_this._selectlist.redraw();
    });

    this.initMap();

    this.KEY = this.model.entities.getDimension();
    this.TIMEDIM = this.model.time.getDimension();

    this.updateUIStrings();

    this.wScale = d3.scale.linear().domain(this.model.ui.datawarning.doubtDomain).range(this.model.ui.datawarning.doubtRange);

    this._labels.readyOnce();
  },

  /*
   * Both model and DOM are ready
   */
  ready: function ready() {
    var _this = this;
    this.updateUIStrings();
    this.updateIndicators();
    this.updateSize();
    this.updateMarkerSizeLimits();
    this.model.marker.getFrame(this.model.time.value, function (values, time) {
      // TODO: temporary fix for case when after data loading time changed on validation
      if (time.toString() != _this.model.time.value.toString()) {
        utils.defer(function () {
          _this.ready();
        });
        return;
      } // frame is outdated

      if (!values) return;
      _this.values = values;
      _this.updateEntities();
      _this.updateTime();
      _this._labels.ready();
      _this.redrawDataPoints();
      _this.highlightMarkers();
      _this.selectMarkers();
      //    this._selectlist.redraw();
      _this.updateDoubtOpacity();
      _this.updateOpacity();
    });
  },

  frameChanged: function frameChanged(frame, time) {
    if (time.toString() != this.model.time.value.toString()) return; // frame is outdated
    if (!frame) return;

    this.values = frame;
    this.updateTime();
    this.updateDoubtOpacity();
    this.redrawDataPoints(null, false);
  },

  updateUIStrings: function updateUIStrings() {
    var _this = this;

    this.translator = this.model.locale.getTFunction();
    var conceptPropsS = _this.model.marker.size.getConceptprops();
    var conceptPropsC = _this.model.marker.color.getConceptprops();

    this.strings = {
      title: {
        S: conceptPropsS.name,
        C: conceptPropsC.name
      }
    };

    this.yTitleEl.select("text").text(this.translator("buttons/size") + ": " + this.strings.title.S).on("click", function () {
      _this.parent.findChildByName("gapminder-treemenu").markerID("size").alignX(_this.model.locale.isRTL() ? "right" : "left").alignY("top").updateView().toggle();
    });

    this.cTitleEl.select("text").text(this.translator("buttons/color") + ": " + this.strings.title.C).on("click", function () {
      _this.parent.findChildByName("gapminder-treemenu").markerID("color").alignX(_this.model.locale.isRTL() ? "right" : "left").alignY("top").updateView().toggle();
    });

    utils.setIcon(this.dataWarningEl, _iconset.warn).select("svg").attr("width", "0px").attr("height", "0px");
    this.dataWarningEl.append("text").attr("text-anchor", "end").text(this.translator("hints/dataWarning"));

    this.dataWarningEl.on("click", function () {
      _this.parent.findChildByName("gapminder-datawarning").toggle();
    }).on("mouseover", function () {
      _this.updateDoubtOpacity(1);
    }).on("mouseout", function () {
      _this.updateDoubtOpacity();
    });

    this.yInfoEl.html(_iconset.question).select("svg").attr("width", "0px").attr("height", "0px");

    //TODO: move away from UI strings, maybe to ready or ready once
    this.yInfoEl.on("click", function () {
      _this.parent.findChildByName("gapminder-datanotes").pin();
    });
    this.yInfoEl.on("mouseover", function () {
      var rect = this.getBBox();
      var coord = utils.makeAbsoluteContext(this, this.farthestViewportElement)(rect.x - 10, rect.y + rect.height + 10);
      var toolRect = _this.root.element.getBoundingClientRect();
      var chartRect = _this.element.node().getBoundingClientRect();
      _this.parent.findChildByName("gapminder-datanotes").setHook('size').show().setPos(coord.x + chartRect.left - toolRect.left, coord.y);
    });
    this.yInfoEl.on("mouseout", function () {
      _this.parent.findChildByName("gapminder-datanotes").hide();
    });

    this.cInfoEl.html(_iconset.question).select("svg").attr("width", "0px").attr("height", "0px");

    //TODO: move away from UI strings, maybe to ready or ready once
    this.cInfoEl.on("click", function () {
      _this.parent.findChildByName("gapminder-datanotes").pin();
    });
    this.cInfoEl.on("mouseover", function () {
      var rect = this.getBBox();
      var coord = utils.makeAbsoluteContext(this, this.farthestViewportElement)(rect.x - 10, rect.y + rect.height + 10);
      var toolRect = _this.root.element.getBoundingClientRect();
      var chartRect = _this.element.node().getBoundingClientRect();
      _this.parent.findChildByName("gapminder-datanotes").setHook('color').show().setPos(coord.x + chartRect.left - toolRect.left, coord.y);
    });
    this.cInfoEl.on("mouseout", function () {
      _this.parent.findChildByName("gapminder-datanotes").hide();
    });
  },

  // show size number on title when hovered on a bubble
  updateTitleNumbers: function updateTitleNumbers() {
    var _this = this;

    var mobile; // if is mobile device and only one bubble is selected, update the ytitle for the bubble
    if (_this.isMobile && _this.model.marker.select && _this.model.marker.select.length === 1) {
      mobile = _this.model.marker.select[0];
    }

    if (_this.hovered || mobile) {
      var conceptPropsS = _this.model.marker.size.getConceptprops();
      var conceptPropsC = _this.model.marker.color.getConceptprops();

      var hovered = _this.hovered || mobile;
      var formatterS = _this.model.marker.size.getTickFormatter();
      var formatterC = _this.model.marker.color.getTickFormatter();

      var unitS = conceptPropsS.unit || "";
      var unitC = conceptPropsC.unit || "";

      var valueS = _this.values.size[hovered[_this.KEY]];
      var valueC = _this.values.color[hovered[_this.KEY]];

      //resolve value for color from the color legend model
      if (_this.model.marker.color.isDiscrete() && valueC) {
        valueC = this.model.marker.color.getColorlegendMarker().label.getItems()[valueC] || "";
      }

      _this.yTitleEl.select("text").text(_this.translator("buttons/size") + ": " + formatterS(valueS) + " " + unitS);

      _this.cTitleEl.select("text").text(_this.translator("buttons/color") + ": " + (valueC || valueC === 0 ? formatterC(valueC) + " " + unitC : _this.translator("hints/nodata")));

      this.yInfoEl.classed("vzb-hidden", true);
      this.cInfoEl.classed("vzb-hidden", true);
    } else {
      this.yTitleEl.select("text").text(this.translator("buttons/size") + ": " + this.strings.title.S);
      this.cTitleEl.select("text").text(this.translator("buttons/color") + ": " + this.strings.title.C);

      this.yInfoEl.classed("vzb-hidden", false);
      this.cInfoEl.classed("vzb-hidden", false || this.cTitleEl.classed('vzb-hidden'));
    }
  },

  updateDoubtOpacity: function updateDoubtOpacity(opacity) {
    if (opacity == null) opacity = this.wScale(+this.time.getUTCFullYear().toString());
    if (this.someSelected) opacity = 1;
    this.dataWarningEl.style("opacity", opacity);
  },

  updateOpacity: function updateOpacity() {
    var _this = this;
    /*
    this.entityBubbles.classed("vzb-selected", function (d) {
        return _this.model.marker.isSelected(d);
    });
    */

    var OPACITY_HIGHLT = 1.0;
    var OPACITY_HIGHLT_DIM = .3;
    var OPACITY_SELECT = this.model.marker.opacityRegular;
    var OPACITY_REGULAR = this.model.marker.opacityRegular;
    var OPACITY_SELECT_DIM = this.model.marker.opacitySelectDim;

    this.entityBubbles.style("opacity", function (d) {

      if (_this.someHighlighted) {
        //highlight or non-highlight
        if (_this.model.marker.isHighlighted(d)) return OPACITY_HIGHLT;
      }

      if (_this.someSelected) {
        //selected or non-selected
        return _this.model.marker.isSelected(d) ? OPACITY_SELECT : OPACITY_SELECT_DIM;
      }

      if (_this.someHighlighted) return OPACITY_HIGHLT_DIM;

      return OPACITY_REGULAR;
    });

    this.entityBubbles.classed("vzb-selected", function (d) {
      return _this.model.marker.isSelected(d);
    });

    var nonSelectedOpacityZero = _this.model.marker.opacitySelectDim < .01;

    // when pointer events need update...
    if (nonSelectedOpacityZero !== this.nonSelectedOpacityZero) {
      this.entityBubbles.style("pointer-events", function (d) {
        return !_this.someSelected || !nonSelectedOpacityZero || _this.model.marker.isSelected(d) ? "visible" : "none";
      });
    }

    this.nonSelectedOpacityZero = _this.model.marker.opacitySelectDim < .01;
  },

  /**
   * Changes labels for indicators
   */
  updateIndicators: function updateIndicators() {
    this.sScale = this.model.marker.size.getScale();
    this.cScale = this.model.marker.color.getScale();
  },

  /**
   * Updates entities
   */
  updateEntities: function updateEntities() {

    var _this = this;
    var KEY = this.KEY;
    var TIMEDIM = this.TIMEDIM;

    var getKeys = function getKeys(prefix) {
      prefix = prefix || "";
      return _this.model.marker.getKeys().map(function (d) {
        var pointer = {};
        pointer[KEY] = d[KEY];
        pointer[TIMEDIM] = endTime;
        pointer.sortValue = _this.values.size[d[KEY]] || 0;
        pointer[KEY] = prefix + d[KEY];
        return pointer;
      }).sort(function (a, b) {
        return b.sortValue - a.sortValue;
      });
    };

    // get array of GEOs, sorted by the size hook
    // that makes larger bubbles go behind the smaller ones
    var endTime = this.model.time.end;
    this.model.marker.setVisible(getKeys.call(this));

    //unselecting bubbles with no data is used for the scenario when
    //some bubbles are selected and user would switch indicator.
    //bubbles would disappear but selection would stay
    if (!this.model.time.splash) {
      this.unselectBubblesWithNoData();
    }

    // TODO: add to csv
    //Africa 9.1021° N, 18.2812°E
    //Europe 53.0000° N, 9.0000° E
    //Asia 49.8380° N, 105.8203° E
    //north American 48.1667° N and longitude 100.1667° W
    /*
    var pos = {
      "afr": {lat: 9.1, lng: 18.3},
      "eur": {lat: 53.0, lng: 9.0},
      "asi": {lat: 49.8, lng: 105.8},
      "ame": {lat: 48.2, lng: -100.2},
    };
    */

    this.entityBubbles = this.bubbleContainer.selectAll('.vzb-bmc-bubble').data(this.model.marker.getVisible(), function (d) {
      return d[KEY];
    }).order();

    //exit selection
    this.entityBubbles.exit().remove();

    //enter selection -- init circles
    this.entityBubbles.enter().append("circle").attr("class", "vzb-bmc-bubble").on("mouseover", function (d, i) {
      if (utils.isTouchDevice()) return;
      _this._interact()._mouseover(d, i);
    }).on("mouseout", function (d, i) {
      if (utils.isTouchDevice()) return;
      _this._interact()._mouseout(d, i);
    }).on("click", function (d, i) {
      if (utils.isTouchDevice()) return;
      _this._interact()._click(d, i);
      _this.highlightMarkers();
    }).onTap(function (d, i) {
      _this._interact()._click(d, i);
      d3.event.stopPropagation();
    }).onLongTap(function (d, i) {});
  },

  unselectBubblesWithNoData: function unselectBubblesWithNoData(frame) {
    var _this = this;
    var KEY = this.KEY;
    if (!frame) frame = this.values;

    if (!frame || !frame.size) return;

    this.model.marker.select.forEach(function (d) {
      if (!frame.size[d[KEY]] && frame.size[d[KEY]] !== 0) _this.model.marker.selectMarker(d);
    });
  },

  redrawDataPoints: function redrawDataPoints(duration, reposition) {
    var _this = this;
    if (!duration) duration = this.duration;
    if (!reposition) reposition = true;
    if (!this.entityBubbles) return utils.warn("redrawDataPoints(): no entityBubbles defined. likely a premature call, fix it!");
    this.entityBubbles.each(function (d, index) {
      var view = d3.select(this);

      var valueX = _this.values.hook_lng[d[_this.KEY]];
      var valueY = _this.values.hook_lat[d[_this.KEY]];
      var valueS = _this.values.size[d[_this.KEY]];
      var valueC = _this.values.color[d[_this.KEY]];
      var valueL = _this.values.label[d[_this.KEY]];

      d.hidden_1 = d.hidden;
      d.hidden = !valueS && valueS !== 0 || valueX == null || valueY == null;

      if (d.hidden !== d.hidden_1) {
        if (duration) {
          view.transition().duration(duration).ease("linear").style("opacity", 0).each("end", function () {
            return view.classed("vzb-hidden", d.hidden).style("opacity", _this.model.marker.opacityRegular);
          });
        } else {
          view.classed("vzb-hidden", d.hidden);
        }
      }
      if (!d.hidden) {

        d.r = utils.areaToRadius(_this.sScale(valueS || 0));
        d.label = valueL;

        view.classed("vzb-hidden", false).attr("fill", valueC != null ? _this.cScale(valueC) : _this.COLOR_WHITEISH);

        if (reposition) {
          d.cLoc = _this.skew(_this.projection([valueX || 0, valueY || 0]));

          view.attr("cx", d.cLoc[0]).attr("cy", d.cLoc[1]);
        }

        if (duration) {
          view.transition().duration(duration).ease("linear").attr("r", d.r);
        } else {
          view.interrupt().attr("r", d.r).transition();
        }

        _this._updateLabel(d, index, d.cLoc[0], d.cLoc[1], valueS, valueC, d.label, duration);
      } else {
        _this._updateLabel(d, index, 0, 0, valueS, valueC, valueL, duration);
      }
    });
  },

  /*
   * UPDATE TIME:
   * Ideally should only update when time or data changes
   */
  updateTime: function updateTime() {
    var _this = this;

    this.time_1 = this.time == null ? this.model.time.value : this.time;
    this.time = this.model.time.value;
    this.duration = this.model.time.playing && this.time - this.time_1 > 0 ? this.model.time.delayAnimations : 0;
    this.year.setText(this.model.time.formatDate(this.time), this.duration);

    //possibly update the exact value in size title
    this.updateTitleNumbers();
  },

  fitSizeOfTitles: function fitSizeOfTitles() {

    //reset font sizes first to make the measurement consistent
    var yTitleText = this.yTitleEl.select("text").style("font-size", null);
    var cTitleText = this.cTitleEl.select("text").style("font-size", null);

    var yTitleText = this.yTitleEl.select("text");
    var cTitleText = this.cTitleEl.select("text");

    var yTitleBB = yTitleText.node().getBBox();
    var cTitleBB = this.cTitleEl.classed('vzb-hidden') ? yTitleBB : cTitleText.node().getBBox();

    var font = Math.max(parseInt(yTitleText.style("font-size")), parseInt(cTitleText.style("font-size"))) * this.width / Math.max(yTitleBB.width, cTitleBB.width);

    if (Math.max(yTitleBB.width, cTitleBB.width) > this.width) {
      yTitleText.style("font-size", font + "px");
      cTitleText.style("font-size", font + "px");
    } else {

      // Else - reset the font size to default so it won't get stuck
      yTitleText.style("font-size", null);
      cTitleText.style("font-size", null);
    }
  },

  initMap: function initMap() {
    if (!this.topology) utils.warn("bubble map afterPreload: missing country shapes " + this.topology);

    // http://bl.ocks.org/mbostock/d4021aa4dccfd65edffd patterson
    // http://bl.ocks.org/mbostock/3710566 robinson
    // map background

    //stage

    this.projection = d3.geo[this.model.ui.map.projection]();

    this.mapPath = d3.geo.path().projection(this.projection);

    this.mapGraph = this.element.select(".vzb-bmc-map-graph");
    this.mapGraph.html('');

    this.mapGeo = _topojson2.default.feature(this.topology, this.topology.objects[this.model.ui.map.topology_object.surface]);
    var boundaries = _topojson2.default.mesh(this.topology, this.topology.objects[this.model.ui.map.topology_object.boundaries], function (a, b) {
      return a !== b;
    });

    // project to bounding box https://bl.ocks.org/mbostock/4707858
    this.projection.scale(1).translate([0, 0]);

    this.mapBounds = this.mapPath.bounds(this.mapGeo);

    this.mapGraph.insert("path", ".graticule").datum(this.mapGeo).attr("class", "land");

    this.mapGraph.insert("path", ".graticule").datum(boundaries).attr("class", "boundary");
  },

  profiles: {
    small: {
      margin: { top: 10, right: 10, left: 10, bottom: 0 },
      infoElHeight: 16,
      minRadius: 0.5,
      maxRadius: 30
    },
    medium: {
      margin: { top: 20, right: 20, left: 20, bottom: 30 },
      infoElHeight: 20,
      minRadius: 1,
      maxRadius: 55
    },
    large: {
      margin: { top: 30, right: 30, left: 30, bottom: 35 },
      infoElHeight: 22,
      minRadius: 1,
      maxRadius: 65
    }
  },

  presentationProfileChanges: {
    medium: {
      infoElHeight: 26
    },
    large: {
      infoElHeight: 32
    }
  },

  /**
   * Executes everytime the container or vizabi is resized
   * Ideally,it contains only operations related to size
   */
  updateSize: function updateSize() {

    this.activeProfile = this.getActiveProfile(this.profiles, this.presentationProfileChanges);
    var margin = this.activeProfile.margin;

    this.height = parseInt(this.element.style("height"), 10) - margin.top - margin.bottom || 0;
    this.width = parseInt(this.element.style("width"), 10) - margin.left - margin.right || 0;

    if (this.height <= 0 || this.width <= 0) return utils.warn("Bubble map updateSize() abort: vizabi container is too little or has display:none");

    this.repositionElements();
    this.rescaleMap();
  },

  repositionElements: function repositionElements() {

    var margin = this.activeProfile.margin,
        infoElHeight = this.activeProfile.infoElHeight,
        isRTL = this.model.locale.isRTL();

    this.graph.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    this.year.setConditions({
      widthRatio: 2 / 10
    });
    this.year.resize(this.width, this.height);

    this.yTitleEl.style("font-size", infoElHeight).attr("transform", "translate(" + (isRTL ? this.width : 0) + "," + margin.top + ")");

    var yTitleBB = this.yTitleEl.select("text").node().getBBox();

    //hide the second line about color in large profile or when color is constant
    this.cTitleEl.attr("transform", "translate(" + (isRTL ? this.width : 0) + "," + (margin.top + yTitleBB.height) + ")").classed("vzb-hidden", this.getLayoutProfile() === "large" || this.model.marker.color.use == "constant");

    var warnBB = this.dataWarningEl.select("text").node().getBBox();
    this.dataWarningEl.select("svg").attr("width", warnBB.height * 0.75).attr("height", warnBB.height * 0.75).attr("x", -warnBB.width - warnBB.height * 1.2).attr("y", -warnBB.height * 0.65);

    this.dataWarningEl.attr("transform", "translate(" + this.width + "," + (this.height - warnBB.height * 0.5) + ")").select("text");

    if (this.yInfoEl.select('svg').node()) {
      var titleBBox = this.yTitleEl.node().getBBox();
      var translate = d3.transform(this.yTitleEl.attr('transform')).translate;
      var hTranslate = isRTL ? titleBBox.x + translate[0] - infoElHeight * 1.4 : titleBBox.x + translate[0] + titleBBox.width + infoElHeight * .4;

      this.yInfoEl.select('svg').attr("width", infoElHeight).attr("height", infoElHeight);
      this.yInfoEl.attr('transform', 'translate(' + hTranslate + ',' + (translate[1] - infoElHeight * 0.8) + ')');
    }

    this.cInfoEl.classed("vzb-hidden", this.cTitleEl.classed("vzb-hidden"));

    if (!this.cInfoEl.classed("vzb-hidden") && this.cInfoEl.select('svg').node()) {
      var titleBBox = this.cTitleEl.node().getBBox();
      var translate = d3.transform(this.cTitleEl.attr('transform')).translate;
      var hTranslate = isRTL ? titleBBox.x + translate[0] - infoElHeight * 1.4 : titleBBox.x + translate[0] + titleBBox.width + infoElHeight * .4;

      this.cInfoEl.select('svg').attr("width", infoElHeight).attr("height", infoElHeight);
      this.cInfoEl.attr('transform', 'translate(' + hTranslate + ',' + (translate[1] - infoElHeight * 0.8) + ')');
    }
  },

  rescaleMap: function rescaleMap() {

    var offset = this.model.ui.map.offset;
    var margin = this.activeProfile.margin;

    // scale to aspect ratio 
    // http://bl.ocks.org/mbostock/4707858
    var s = this.model.ui.map.scale / Math.max((this.mapBounds[1][0] - this.mapBounds[0][0]) / this.width, (this.mapBounds[1][1] - this.mapBounds[0][1]) / this.height),


    // dimensions of the map itself (regardless of cropping)
    mapWidth = s * (this.mapBounds[1][0] - this.mapBounds[0][0]),
        mapHeight = s * (this.mapBounds[1][1] - this.mapBounds[0][1]),


    // dimensions of the viewport in which the map is shown (can be bigger or smaller than map)
    viewPortHeight = mapHeight * (1 + offset.top + offset.bottom),
        viewPortWidth = mapWidth * (1 + offset.left + offset.right),
        mapTopOffset = mapHeight * offset.top,
        mapLeftOffset = mapWidth * offset.left,


    // translate projection to the middle of map
    t = [(mapWidth - s * (this.mapBounds[1][0] + this.mapBounds[0][0])) / 2, (mapHeight - s * (this.mapBounds[1][1] + this.mapBounds[0][1])) / 2];

    this.projection.scale(s).translate(t);

    this.mapGraph.selectAll('path').attr("d", this.mapPath);

    // handle scale to fit case
    var widthScale, heightScale;
    if (!this.model.ui.map.preserveAspectRatio) {

      // wrap viewBox around viewport so map scales to fit viewport
      var viewBoxHeight = viewPortHeight;
      var viewBoxWidth = viewPortWidth;

      // viewport is complete area (apart from scaling)
      viewPortHeight = this.height * this.model.ui.map.scale;
      viewPortWidth = this.width * this.model.ui.map.scale;

      this.mapSvg.attr('preserveAspectRatio', 'none').attr('viewBox', [0, 0, viewBoxWidth, viewBoxHeight].join(' '));

      //            ratio between map, viewport and offset (for bubbles)
      widthScale = viewPortWidth / mapWidth / (1 + offset.left + offset.right);
      heightScale = viewPortHeight / mapHeight / (1 + offset.top + offset.bottom);
    } else {

      // no scaling needed
      widthScale = 1;
      heightScale = 1;
    }

    // internal offset against parent container (mapSvg)
    this.mapGraph.attr('transform', 'translate(' + mapLeftOffset + ',' + mapTopOffset + ')');

    // resize and put in center
    this.mapSvg.style("transform", "translate3d(" + (margin.left + (this.width - viewPortWidth) / 2) + "px," + (margin.top + (this.height - viewPortHeight) / 2) + "px,0)").attr('width', viewPortWidth).attr('height', viewPortHeight);

    // set skew function used for bubbles in chart
    var _this = this;
    this.skew = function () {
      var w = _this.width;
      var h = _this.height;
      //input pixel loc after projection, return pixel loc after skew;
      return function (points) {
        //      input       scale         translate                    translate offset
        var x = points[0] * widthScale + (w - viewPortWidth) / 2 + mapLeftOffset * widthScale;
        var y = points[1] * heightScale + (h - viewPortHeight) / 2 + mapTopOffset * heightScale;
        return [x, y];
      };
    }();
  },

  updateMarkerSizeLimits: function updateMarkerSizeLimits() {
    var _this = this;
    var extent = this.model.marker.size.extent || [0, 1];

    var minRadius = this.activeProfile.minRadius;
    var maxRadius = this.activeProfile.maxRadius;

    this.minRadius = Math.max(maxRadius * extent[0], minRadius);
    this.maxRadius = Math.max(maxRadius * extent[1], minRadius);

    if (this.model.marker.size.scaleType !== "ordinal") {
      this.sScale.range([utils.radiusToArea(_this.minRadius), utils.radiusToArea(_this.maxRadius)]);
    } else {
      this.sScale.rangePoints([utils.radiusToArea(_this.minRadius), utils.radiusToArea(_this.maxRadius)], 0).range();
    }
  },

  _interact: function _interact() {
    var _this = this;

    return {
      _mouseover: function _mouseover(d, i) {
        if (_this.model.time.dragging) return;

        _this.model.marker.highlightMarker(d);

        _this.hovered = d;
        //put the exact value in the size title
        _this.updateTitleNumbers();
        _this.fitSizeOfTitles();

        if (_this.model.marker.isSelected(d)) {
          // if selected, not show hover tooltip
          _this._setTooltip();
        } else {
          //position tooltip
          _this._setTooltip(d);
        }
      },
      _mouseout: function _mouseout(d, i) {
        if (_this.model.time.dragging) return;
        _this._setTooltip();
        _this.hovered = null;
        _this.updateTitleNumbers();
        _this.fitSizeOfTitles();
        _this.model.marker.clearHighlighted();
      },
      _click: function _click(d, i) {
        _this.model.marker.selectMarker(d);
      }
    };
  },

  highlightMarkers: function highlightMarkers() {
    var _this = this;
    this.someHighlighted = this.model.marker.highlight.length > 0;

    if (utils.isTouchDevice()) {
      if (this.someHighlighted) {
        _this.hovered = this.model.marker.highlight[0];
      } else {
        _this.hovered = null;
      }
      _this.updateTitleNumbers();
      _this.fitSizeOfTitles();
    }

    //      if (!this.selectList || !this.someSelected) return;
    //      this.selectList.classed("vzb-highlight", function (d) {
    //          return _this.model.entities.isHighlighted(d);
    //      });
    //      this.selectList.each(function (d, i) {
    //        d3.select(this).selectAll(".vzb-bmc-label-x")
    //          .classed("vzb-invisible", function(n) {
    //            return !_this.model.entities.isHighlighted(d);
    //          });
    //
    //      });
  },

  _updateLabel: function _updateLabel(d, index, valueX, valueY, valueS, valueC, valueL, duration) {
    var _this = this;
    var KEY = this.KEY;
    if (d[KEY] == _this.druging) return;
    if (duration == null) duration = _this.duration;

    // only for selected entities
    if (_this.model.marker.isSelected(d)) {

      var showhide = d.hidden !== d.hidden_1;
      var valueLST = null;
      var cache = {};
      cache.labelX0 = valueX / this.width;
      cache.labelY0 = valueY / this.height;
      cache.scaledS0 = valueS ? utils.areaToRadius(_this.sScale(valueS)) : null;
      cache.scaledC0 = valueC != null ? _this.cScale(valueC) : _this.COLOR_WHITEISH;

      this._labels.updateLabel(d, index, cache, valueX / this.width, valueY / this.height, valueS, valueC, valueL, valueLST, duration, showhide);
    }
  },

  selectMarkers: function selectMarkers() {
    var _this = this;
    var KEY = this.KEY;
    this.someSelected = this.model.marker.select.length > 0;

    //      this._selectlist.rebuild();
    if (utils.isTouchDevice()) {
      _this._labels.showCloseCross(null, false);
      if (_this.someHighlighted) {
        _this.model.marker.clearHighlighted();
      } else {
        _this.updateTitleNumbers();
        _this.fitSizeOfTitles();
      }
    } else {
      // hide recent hover tooltip
      if (!_this.hovered || _this.model.marker.isSelected(_this.hovered)) {
        _this._setTooltip();
      }
    }

    this.nonSelectedOpacityZero = false;
  },

  _setTooltip: function _setTooltip(d) {
    var _this = this;
    if (d) {
      var tooltipText = d.label;
      var x = d.cLoc[0];
      var y = d.cLoc[1];
      var offset = d.r;
      var mouse = d3.mouse(this.graph.node()).map(function (d) {
        return parseInt(d);
      });
      var xPos,
          yPos,
          xSign = -1,
          ySign = -1,
          xOffset = 0,
          yOffset = 0;

      if (offset) {
        xOffset = offset * .71; // .71 - sin and cos for 315
        yOffset = offset * .71;
      }
      //position tooltip
      this.tooltip.classed("vzb-hidden", false)
      //.attr("style", "left:" + (mouse[0] + 50) + "px;top:" + (mouse[1] + 50) + "px")
      .selectAll("text").text(tooltipText);

      var contentBBox = this.tooltip.select('text')[0][0].getBBox();
      if (x - xOffset - contentBBox.width < 0) {
        xSign = 1;
        x += contentBBox.width + 5; // corrective to the block Radius and text padding
      } else {
        x -= 5; // corrective to the block Radius and text padding
      }
      if (y - yOffset - contentBBox.height < 0) {
        ySign = 1;
        y += contentBBox.height;
      } else {
        y -= 11; // corrective to the block Radius and text padding
      }
      if (offset) {
        xPos = x + xOffset * xSign;
        yPos = y + yOffset * ySign; // 5 and 11 - corrective to the block Radius and text padding
      } else {
        xPos = x + xOffset * xSign; // .71 - sin and cos for 315
        yPos = y + yOffset * ySign; // 5 and 11 - corrective to the block Radius and text padding
      }
      this.tooltip.attr("transform", "translate(" + (xPos ? xPos : mouse[0]) + "," + (yPos ? yPos : mouse[1]) + ")");

      this.tooltip.select('rect').attr("width", contentBBox.width + 8).attr("height", contentBBox.height * 1.2).attr("x", -contentBBox.width - 4).attr("y", -contentBBox.height * .85).attr("rx", contentBBox.height * .2).attr("ry", contentBBox.height * .2);
    } else {

      this.tooltip.classed("vzb-hidden", true);
    }
  },

  preload: function preload() {
    var _this = this;

    var shape_path = this.model.ui.map.path ? this.model.ui.map.path : _globals2.default.ext_resources.host + _globals2.default.ext_resources.preloadPath + "world-50m.json";

    return new Promise(function (resolve, reject) {
      d3.json(shape_path, function (error, json) {
        if (error) return console.warn("Failed loading json " + shape_path + ". " + error);
        _this.topology = json;
        resolve();
      });
    });
  }

});

exports.default = BubbleMapComponent;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

//DONUT CHART COMPONENT
/*!
 * VIZABI DONUT CHART
 */

var DonutComponent = _component2.default.extend('donut', {

  init: function init(config, context) {
    var _this = this;

    this.name = 'donutchart';
    this.template = '<div class="vzb-donutchart"><svg class="vzb-donutchart-svg"></svg></div>';

    //define expected models for this component
    this.model_expects = [{
      name: "time",
      type: "time"
    }, {
      name: "marker",
      type: "model"
    }];

    //bind the function updateTime() to the change of time value in the model
    this.model_binds = {
      "change:time:value": function changeTimeValue(evt) {
        if (!_this._readyOnce) return;
        //fetch the time from the model and update the text on screen
        _this.time = _this.model.time.value;
        _this.yearEl.text(_this.timeFormatter(_this.time));
        _this.redraw();
      }
    };

    //call the prototype constructor of the component
    this._super(config, context);

    //init variables for d3 pie layout
    this.colorScale = null;
    this.arc = d3.svg.arc();
    this.pie = d3.layout.pie().sort(null).value(function (d) {
      return d.pop;
    });
  },

  /**
   * DOM is ready and the model is ready -- happens once on the load and never again
   */
  readyOnce: function readyOnce() {
    var _this = this;

    //link DOM elements to the variables
    this.element = d3.select(this.element);
    this.svgEl = this.element.select("svg").append("g");
    this.yearEl = this.svgEl.append("text").attr("class", "year").style({ 'font-size': '4em' });
    this.titleEl = this.svgEl.append("text").attr("class", "title").style({ 'font-size': '2em' });

    //bind the resize() and updateTime() events to container resize
    this.on("resize", function () {
      _this.resize();
      _this.redraw();
    });

    //run a startup sequence
    this.resize();
    this.update();
    this.redraw();
  },

  /**
   * Populate the visuals according to the number of entities
   */
  update: function update() {
    this.timeFormatter = this.model.time.formatters.data("%Y");
    this.colorScale = this.model.marker.color.getScale();

    this.titleEl.text("Population");
    this.keys = this.model.marker.getKeys();

    this.entities = this.svgEl.selectAll('.vzb-dc-entity').data(this.keys);

    //exit selection
    this.entities.exit().remove();

    //enter selection
    this.entities.enter().append("g").attr("class", "vzb-dc-entity").each(function () {
      d3.select(this).append("path");
      d3.select(this).append("text").attr("class", "label").style({ 'font-size': '1.2em' });
    });
  },

  /**
   * Updates the visuals
   */
  redraw: function redraw() {
    var _this = this;

    //request the values for the current time from the model
    this.values = this.model.marker.getValues({ time: _this.time }, ["geo"]);

    //prepare the data
    var data = this.keys.map(function (d) {
      return {
        geo: d.geo,
        pop: _this.values.axis[d.geo],
        color: _this.values.color[d.geo],
        label: _this.values.label[d.geo]
      };
    });

    data = this.pie(data);

    //set the properties of the donuts and text labels
    this.entities.data(data).select("path").attr("d", this.arc).style("fill", function (d) {
      return _this.colorScale(d.data.color);
    }).style("stroke", "white");

    this.entities.select("text").style({
      'text-transform': 'capitalize'
    }).attr("transform", function (d) {
      return "translate(" + _this.arc.centroid(d) + ")";
    }).text(function (d) {
      return d.data.geo;
    });
  },

  /**
   * Executes every time the container or vizabi is resized
   */
  resize: function resize() {

    var height = parseInt(this.element.style("height"), 10) || 0;
    var width = parseInt(this.element.style("width"), 10) || 0;
    var min = Math.min(height, width);

    if (height <= 0 || width <= 0) return utils.warn("Donut chart resize() abort: vizabi container is too little or has display:none");

    this.svgEl.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
    this.titleEl.attr("y", "-0.1em");
    this.yearEl.attr("y", "0.1em");

    this.arc.outerRadius(min / 2 * 0.9).innerRadius(min / 2 - min * 0.1);
  }

});

exports.default = DonutComponent;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
    value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _component = __webpack_require__(2);

var _component2 = _interopRequireDefault(_component);

var _iconset = __webpack_require__(10);

var _svgexport = __webpack_require__(136);

var _svgexport2 = _interopRequireDefault(_svgexport);

var _d = __webpack_require__(40);

var _d2 = _interopRequireDefault(_d);

var _mountainchartMath = __webpack_require__(225);

var _mountainchartMath2 = _interopRequireDefault(_mountainchartMath);

var _mountainchartSelectlist = __webpack_require__(227);

var _mountainchartSelectlist2 = _interopRequireDefault(_mountainchartSelectlist);

var _mountainchartProbe = __webpack_require__(226);

var _mountainchartProbe2 = _interopRequireDefault(_mountainchartProbe);

var _d3 = __webpack_require__(66);

var _d4 = _interopRequireDefault(_d3);

var _globals = __webpack_require__(44);

var _globals2 = _interopRequireDefault(_globals);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

/**
* VIZABI MOUNTAINCHART
* This graph displays income distribution in the world
*
* Original code:
* Angie https://github.com/angieskazka
*
* Contributions:
* IncoCode https://github.com/IncoCode/
* Arthur https://github.com/arthurcamara1
*
* Developed in Gapminder Foundation, 2015
*/

var THICKNESS_THRESHOLD = 0.001;
var COLOR_WHITEISH = "#d3d3d3";

//MOUNTAIN CHART COMPONENT
var MountainChartComponent = _component2.default.extend({

    /**
     * Initialize the component
     * Executed once before any template is rendered.
     * @param {Object} config The config passed to the component
     * @param {Object} context The component's parent
     */
    init: function init(config, context) {

        var _this = this;
        this.name = "mountainchart";
        this.template = __webpack_require__(450);

        //define expected models for this component
        this.model_expects = [{ name: "time", type: "time" }, { name: "entities", type: "entities" }, { name: "marker", type: "model" }, { name: "locale", type: "locale" }, { name: "ui", type: "ui" }];

        //attach event listeners to the model items
        this.model_binds = {
            "change:time.value": function changeTimeValue(evt) {
                if (!_this._readyOnce) return;
                _this.model.marker.getFrame(_this.model.time.value, _this.frameChanged.bind(_this));
            },
            "change:time.playing": function changeTimePlaying(evt) {
                // this listener is a patch for fixing #1228. time.js doesn't produce the last event
                // with playing == false when paused softly
                if (!_this.model.time.playing) {
                    _this.redrawDataPoints();
                }
            },
            "change:marker.axis_x.xScaleFactor": function changeMarkerAxis_xXScaleFactor() {
                _this.ready();
            },
            "change:marker.axis_x.xScaleShift": function changeMarkerAxis_xXScaleShift() {
                _this.ready();
            },
            "change:marker.axis_x.tailFatX": function changeMarkerAxis_xTailFatX() {
                _this.ready();
            },
            "change:marker.axis_x.tailCutX": function changeMarkerAxis_xTailCutX() {
                _this.ready();
            },
            "change:marker.axis_x.tailFade": function changeMarkerAxis_xTailFade() {
                _this.ready();
            },
            "change:ui.chart.probeX": function changeUiChartProbeX() {
                _this.ready();
            },
            "change:ui.chart.showProbeX": function changeUiChartShowProbeX() {
                _this.ready();
            },
            "change:ui.chart.xPoints": function changeUiChartXPoints() {
                _this.ready();
            },
            "change:ui.chart.xLogStops": function changeUiChartXLogStops() {
                _this.updateSize();
            },
            "change:ui.chart.yMaxMethod": function changeUiChartYMaxMethod() {
                _this._adjustMaxY({ force: true });
                _this.redrawDataPoints();
            },
            "change:time.record": function changeTimeRecord(evt) {
                if (_this.model.time.record) {
                    _this._export.open(this.element, this.name);
                } else {
                    _this._export.reset();
                }
            },
            "change:marker.highlight": function changeMarkerHighlight(evt) {
                if (!_this._readyOnce) return;
                _this.highlightMarkers();
                _this.updateOpacity();
            },
            "change:marker.select": function changeMarkerSelect(evt) {
                if (!_this._readyOnce) return;
                _this.selectMarkers();
                _this._selectlist.redraw();
                _this.updateOpacity();
                _this.updateDoubtOpacity();
                _this.redrawDataPoints();
            },
            "change:marker.opacitySelectDim": function changeMarkerOpacitySelectDim(evt) {
                _this.updateOpacity();
            },
            "change:marker.opacityRegular": function changeMarkerOpacityRegular(evt) {
                _this.updateOpacity();
            },
            "change:marker": function changeMarker(evt, path) {
                if (!_this._readyOnce) return;
                if (path.indexOf("scaleType") > -1) {
                    _this.ready();
                    return;
                }
                if (path.indexOf("zoomedMin") > -1 || path.indexOf("zoomedMax") > -1) {
                    _this.zoomToMaxMin();
                    _this.redrawDataPoints();
                    _this._probe.redraw();
                    return;
                }
            },
            "change:marker.group": function changeMarkerGroup(evt, path) {
                if (!_this._readyOnce) return;
                if (path.indexOf("group.merge") > -1) return;
                _this.ready();
            },
            "change:marker.group.merge": function changeMarkerGroupMerge(evt) {
                if (!_this._readyOnce) return;
                _this.updatePointers();
                _this.redrawDataPoints();
            },
            "change:marker.stack": function changeMarkerStack(evt) {
                if (!_this._readyOnce) return;
                _this.ready();
            },
            "change:marker.color.palette": function changeMarkerColorPalette(evt) {
                if (!_this._readyOnce) return;
                _this.redrawDataPointsOnlyColors();
                _this._selectlist.redraw();
            }
        };

        this._super(config, context);

        this._math = new _mountainchartMath2.default(this);
        this._export = new _svgexport2.default(this);
        this._export.prefix("vzb-mc-").deleteClasses(["vzb-mc-mountains-mergestacked", "vzb-mc-mountains-mergegrouped", "vzb-mc-mountains", "vzb-mc-year", "vzb-mc-mountains-labels", "vzb-mc-axis-labels"]);
        this._probe = new _mountainchartProbe2.default(this);
        this._selectlist = new _mountainchartSelectlist2.default(this);

        // define path generator
        this.area = d3.svg.area().interpolate("basis").x(function (d) {
            return _this.xScale(_this._math.rescale(d.x));
        }).y0(function (d) {
            return _this.yScale(d.y0);
        }).y1(function (d) {
            return _this.yScale(d.y0 + d.y);
        });

        //define d3 stack layout
        this.stack = d3.layout.stack().order("reverse").values(function (d) {
            return _this.cached[d.KEY()];
        }).out(function out(d, y0, y) {
            d.y0 = y0;
        });

        // init internal variables
        this.xScale = null;
        this.yScale = null;
        this.cScale = null;

        this.xAxis = (0, _d2.default)();

        this.rangeRatio = 1;
        this.rangeShift = 0;
        this.cached = {};
        this.mesh = [];
        this.yMax = 0;
    },

    domReady: function domReady() {
        var _this = this;

        // reference elements
        this.element = d3.select(this.element);
        this.graph = this.element.select(".vzb-mc-graph");
        this.xAxisEl = this.graph.select(".vzb-mc-axis-x");
        this.xTitleEl = this.graph.select(".vzb-mc-axis-x-title");
        this.yTitleEl = this.graph.select(".vzb-mc-axis-y-title");
        this.infoEl = this.graph.select(".vzb-mc-axis-info");
        this.dataWarningEl = this.graph.select(".vzb-data-warning");

        this.yearEl = this.graph.select(".vzb-mc-year");
        this.year = new _d4.default(this.yearEl);

        this.mountainMergeStackedContainer = this.graph.select(".vzb-mc-mountains-mergestacked");
        this.mountainMergeGroupedContainer = this.graph.select(".vzb-mc-mountains-mergegrouped");
        this.mountainAtomicContainer = this.graph.select(".vzb-mc-mountains");
        this.mountainLabelContainer = this.graph.select(".vzb-mc-mountains-labels");
        this.tooltip = this.element.select(".vzb-mc-tooltip");
        this.eventAreaEl = this.element.select(".vzb-mc-eventarea");
        this.probeEl = this.element.select(".vzb-mc-probe");
        this.probeLineEl = this.probeEl.select("line");
        this.probeTextEl = this.probeEl.selectAll("text");

        this.element.onTap(function (d, i) {
            _this._interact()._mouseout(d, i);
        });
    },

    afterPreload: function afterPreload() {
        var _this = this;

        var yearNow = _this.model.time.formatDate(this.model.time.value);
        var yearEnd = _this.model.time.formatDate(this.model.time.end);

        this._math.xScaleFactor = this.model.marker.axis_x.xScaleFactor;
        this._math.xScaleShift = this.model.marker.axis_x.xScaleShift;

        if (!this.precomputedShapes || !this.precomputedShapes[yearNow] || !this.precomputedShapes[yearEnd]) return;

        var yMax = this.precomputedShapes[this.model.ui.chart.yMaxMethod == "immediate" ? yearNow : yearEnd].yMax;
        var shape = this.precomputedShapes[yearNow].shape;

        if (!yMax || !shape || shape.length === 0) return;

        this.xScale = d3.scale.log().domain([this.model.marker.axis_x.domainMin, this.model.marker.axis_x.domainMax]);
        this.yScale = d3.scale.linear().domain([0, Math.round(yMax)]);

        _this.updateSize(shape.length);
        _this.zoomToMaxMin();

        shape = shape.map(function (m, i) {
            return { x: _this.mesh[i], y0: 0, y: +m };
        });

        this.mountainAtomicContainer.selectAll(".vzb-mc-prerender").data([0]).enter().append("path").attr("class", "vzb-mc-prerender").style("fill", "pink").style("opacity", 0).attr("d", _this.area(shape)).transition().duration(1000).ease("linear").style("opacity", 1);
    },

    readyOnce: function readyOnce() {

        this.eventAreaEl.on("mousemove", function () {
            if (_this.model.time.dragging) return;
            if (!_this.model.ui.chart.showProbeX) return;
            _this._probe.redraw({
                level: _this.xScale.invert(d3.mouse(this)[0]),
                full: true
            });
        }).on("mouseout", function () {
            if (_this.model.time.dragging) return;
            if (!_this.model.ui.chart.showProbeX) return;
            _this._probe.redraw();
        });

        var _this = this;
        this.on("resize", function () {
            //console.log("acting on resize");
            //return if updatesize exists with error
            if (_this.updateSize()) return;
            _this.updatePointers(); // respawn is needed
            _this.redrawDataPoints();
            _this._selectlist.redraw();
            _this._probe.redraw();
        });

        this.KEY = this.model.entities.getDimension();
        this.TIMEDIM = this.model.time.getDimension();

        this.mountainAtomicContainer.select(".vzb-mc-prerender").remove();
        this.year.setText(this.model.time.formatDate(this.model.time.value));
        this.wScale = d3.scale.linear().domain(this.model.ui.datawarning.doubtDomain).range(this.model.ui.datawarning.doubtRange);
    },

    ready: function ready() {
        //console.log("ready")
        var _this = this;

        this._math.xScaleFactor = this.model.marker.axis_x.xScaleFactor;
        this._math.xScaleShift = this.model.marker.axis_x.xScaleShift;

        this.updateUIStrings();
        this.updateIndicators();
        this.model.marker.getFrame(this.model.time.value, function (values) {
            if (!values) return;
            _this.values = values;
            _this.updateEntities();
            _this.updateSize();
            _this.zoomToMaxMin();
            _this._spawnMasks();
            _this.updateTime();
            _this.updatePointers();
            _this._adjustMaxY({ force: true });
            _this.redrawDataPoints();
            _this.redrawDataPointsOnlyColors();
            _this.highlightMarkers();
            _this.selectMarkers();
            _this._selectlist.redraw();
            _this.updateOpacity();
            _this.updateDoubtOpacity();
            _this._probe.redraw();
        });
    },

    frameChanged: function frameChanged(frame, time) {
        if (time.toString() != this.model.time.value.toString()) return; // frame is outdated
        this.values = frame;
        this.updateTime();
        this.updatePointers();
        this.redrawDataPoints();
        this._selectlist.redraw();
        this._probe.redraw();
        this.updateDoubtOpacity();
    },

    updateSize: function updateSize(meshLength) {

        var margin, infoElHeight;
        var padding = 2;

        var profiles = {
            small: {
                margin: { top: 10, right: 10, left: 10, bottom: 18 },
                infoElHeight: 16
            },
            medium: {
                margin: { top: 20, right: 20, left: 20, bottom: 30 },
                infoElHeight: 20
            },
            large: {
                margin: { top: 30, right: 30, left: 30, bottom: 35 },
                infoElHeight: 22
            }
        };

        var presentationProfileChanges = {
            medium: {
                margin: { top: 20, right: 20, left: 20, bottom: 50 },
                infoElHeight: 26
            },
            large: {
                margin: { top: 30, right: 30, left: 30, bottom: 50 },
                infoElHeight: 32
            }
        };

        this.activeProfile = this.getActiveProfile(profiles, presentationProfileChanges);
        margin = this.activeProfile.margin;
        infoElHeight = this.activeProfile.infoElHeight;

        //mesure width and height
        this.height = parseInt(this.element.style("height"), 10) - margin.top - margin.bottom || 0;
        this.width = parseInt(this.element.style("width"), 10) - margin.left - margin.right || 0;

        if (this.height <= 0 || this.width <= 0) return utils.warn("Mountain chart updateSize() abort: vizabi container is too little or has display:none");

        //graph group is shifted according to margins (while svg element is at 100 by 100%)
        this.graph.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

        var isRTL = this.model.locale.isRTL();

        var yearLabelOptions = {
            topOffset: this.getLayoutProfile() === "large" ? margin.top * 2 : 0,
            xAlign: this.getLayoutProfile() === "large" ? isRTL ? 'left' : 'right' : 'center',
            yAlign: this.getLayoutProfile() === "large" ? 'top' : 'center',
            widthRatio: this.getLayoutProfile() === "large" ? 3 / 8 : 8 / 10
        };

        //year is centered and resized
        this.year.setConditions(yearLabelOptions).resize(this.width, this.height);

        //update scales to the new range
        this.yScale.range([this.height, 0]);
        this.xScale.range([this.rangeShift, this.width * this.rangeRatio + this.rangeShift]);

        //need to know scale type of X to move on
        var scaleType = this._readyOnce ? this.model.marker.axis_x.scaleType : "log";

        //axis is updated
        this.xAxis.scale(this.xScale).orient("bottom").tickSize(6, 0).tickPadding(9).tickSizeMinor(3, 0).labelerOptions({
            scaleType: scaleType,
            toolMargin: margin,
            pivotingLimit: margin.bottom * 1.5,
            method: this.xAxis.METHOD_REPEATING,
            stops: this._readyOnce ? this.model.ui.chart.xLogStops : [1],
            formatter: this.model.marker.axis_x.getTickFormatter()
        });

        this.xAxisEl.attr("transform", "translate(0," + this.height + ")").call(this.xAxis);

        this.xTitleEl.select("text").attr("transform", "translate(" + this.width + "," + this.height + ")").attr("dy", "-0.36em");

        this.yTitleEl.style("font-size", infoElHeight + "px").attr("transform", "translate(" + (isRTL ? this.width : 0) + "," + margin.top + ")");

        var warnBB = this.dataWarningEl.select("text").node().getBBox();
        this.dataWarningEl.select("svg").attr("width", warnBB.height).attr("height", warnBB.height).attr("x", warnBB.height * .1).attr("y", -warnBB.height * 1.0 + 1);

        this.dataWarningEl.attr("transform", "translate(" + (isRTL ? this.width - warnBB.width - warnBB.height * 2 : 0) + "," + (margin.top + warnBB.height * 1.5) + ")").select("text").attr("dx", warnBB.height * 1.5);

        if (this.infoEl.select('svg').node()) {
            var titleBBox = this.yTitleEl.node().getBBox();
            var translate = d3.transform(this.yTitleEl.attr('transform')).translate;
            var hTranslate = isRTL ? titleBBox.x + translate[0] - infoElHeight * 1.4 : titleBBox.x + translate[0] + titleBBox.width + infoElHeight * .4;

            this.infoEl.select('svg').attr("width", infoElHeight + "px").attr("height", infoElHeight + "px");
            this.infoEl.attr('transform', 'translate(' + hTranslate + ',' + (translate[1] - infoElHeight * .8) + ')');
        }

        this.eventAreaEl.attr("y", this.height).attr("width", this.width).attr("height", margin.bottom);

        if (!meshLength) meshLength = this.model.ui.chart.xPoints;
        this.mesh = this._math.generateMesh(meshLength, scaleType, this.xScale.domain());
    },

    zoomToMaxMin: function zoomToMaxMin() {
        var _this = this;

        if (this.model.marker.axis_x.zoomedMin == null || this.model.marker.axis_x.zoomedMax == null) return;

        var x1 = this.xScale(this.model.marker.axis_x.zoomedMin);
        var x2 = this.xScale(this.model.marker.axis_x.zoomedMax);

        this.rangeRatio = this.width / (x2 - x1) * this.rangeRatio;
        this.rangeShift = (this.rangeShift - x1) / (x2 - x1) * this.width;

        this.xScale.range([this.rangeShift, this.width * this.rangeRatio + this.rangeShift]);

        this.xAxisEl.call(this.xAxis);
    },

    updateUIStrings: function updateUIStrings() {
        var _this = this;

        this.translator = this.model.locale.getTFunction();
        var xConceptprops = this.model.marker.axis_x.getConceptprops();

        this.xTitleEl.select("text").text(this.translator("unit/mountainchart_hardcoded_income_per_day"));

        this.yTitleEl.select("text").text(this.translator("mount/title"));

        utils.setIcon(this.dataWarningEl, _iconset.warn).select("svg").attr("width", "0px").attr("height", "0px");
        this.dataWarningEl.append("text").text(this.translator("hints/dataWarning"));

        utils.setIcon(this.infoEl, _iconset.question).select("svg").attr("width", "0px").attr("height", "0px");

        //TODO: move away from UI strings, maybe to ready or ready once
        this.infoEl.on("click", function () {
            _this.parent.findChildByName("gapminder-datanotes").pin();
        });
        this.infoEl.on("mouseover", function () {
            var rect = this.getBBox();
            var coord = utils.makeAbsoluteContext(this, this.farthestViewportElement)(rect.x - 10, rect.y + rect.height + 10);
            var toolRect = _this.root.element.getBoundingClientRect();
            var chartRect = _this.element.node().getBoundingClientRect();
            _this.parent.findChildByName("gapminder-datanotes").setHook('axis_y').show().setPos(coord.x + chartRect.left - toolRect.left, coord.y);
        });
        this.infoEl.on("mouseout", function () {
            _this.parent.findChildByName("gapminder-datanotes").hide();
        });

        this.dataWarningEl.on("click", function () {
            _this.parent.findChildByName("gapminder-datawarning").toggle();
        }).on("mouseover", function () {
            _this.updateDoubtOpacity(1);
        }).on("mouseout", function () {
            _this.updateDoubtOpacity();
        });
    },

    updateDoubtOpacity: function updateDoubtOpacity(opacity) {
        if (opacity == null) opacity = this.wScale(+this.time.getUTCFullYear().toString());
        if (this.someSelected) opacity = 1;
        this.dataWarningEl.style("opacity", opacity);
    },

    updateIndicators: function updateIndicators() {
        var _this = this;

        //fetch scales, or rebuild scales if there are none, then fetch
        this.yScale = this.model.marker.axis_y.getScale();
        this.xScale = this.model.marker.axis_x.getScale();
        this.cScale = this.model.marker.color.getScale();

        this.xAxis.tickFormat(_this.model.marker.axis_x.getTickFormatter());
    },

    updateEntities: function updateEntities() {
        var _this = this;

        // construct pointers
        this.mountainPointers = this.model.marker.getKeys().filter(function (d) {
            return 1 && _this.values.axis_x[d[_this.KEY]] && _this.values.axis_y[d[_this.KEY]] && _this.values.axis_s[d[_this.KEY]];
        }).map(function (d) {
            var pointer = {};
            pointer[_this.KEY] = d[_this.KEY];
            pointer.KEY = function () {
                return this[_this.KEY];
            };
            pointer.sortValue = [_this.values.axis_y[pointer.KEY()] || 0, 0];
            pointer.aggrLevel = 0;
            return pointer;
        });

        //TODO: optimise this!
        this.groupedPointers = d3.nest().key(function (d) {
            return _this.model.marker.stack.use === "property" ? _this.values.stack[d.KEY()] : _this.values.group[d.KEY()];
        }).sortValues(function (a, b) {
            return b.sortValue[0] - a.sortValue[0];
        }).entries(this.mountainPointers);

        var groupManualSort = this.model.marker.group.manualSorting;
        this.groupedPointers.forEach(function (group) {
            var groupSortValue = d3.sum(group.values.map(function (m) {
                return m.sortValue[0];
            }));

            if (groupManualSort && groupManualSort.length > 1) groupSortValue = groupManualSort.length - 1 - groupManualSort.indexOf(group.key);

            group.values.forEach(function (d) {
                d.sortValue[1] = groupSortValue;
            });

            group[_this.model.entities.getDimension()] = group.key; // hack to get highlihgt and selection work
            group.KEY = function () {
                return this.key;
            };
            group.aggrLevel = 1;
        });

        var sortGroupKeys = {};
        _this.groupedPointers.map(function (m) {
            sortGroupKeys[m.key] = m.values[0].sortValue[1];
        });

        // update the stacked pointers
        if (_this.model.marker.stack.which === "none") {
            this.stackedPointers = [];
            this.mountainPointers.sort(function (a, b) {
                return b.sortValue[0] - a.sortValue[0];
            });
        } else {
            this.stackedPointers = d3.nest().key(function (d) {
                return _this.values.stack[d.KEY()];
            }).key(function (d) {
                return _this.values.group[d.KEY()];
            }).sortKeys(function (a, b) {
                return sortGroupKeys[b] - sortGroupKeys[a];
            }).sortValues(function (a, b) {
                return b.sortValue[0] - a.sortValue[0];
            }).entries(this.mountainPointers);

            this.mountainPointers.sort(function (a, b) {
                return b.sortValue[1] - a.sortValue[1];
            });

            this.stackedPointers.forEach(function (stack) {
                stack.KEY = function () {
                    return this.key;
                };
                stack[_this.model.entities.getDimension()] = stack.key; // hack to get highlihgt and selection work
                stack.aggrLevel = 2;
            });
        }

        //bind the data to DOM elements
        this.mountainsMergeStacked = this.mountainAtomicContainer.selectAll(".vzb-mc-mountain.vzb-mc-aggrlevel2").data(this.stackedPointers);
        this.mountainsMergeGrouped = this.mountainAtomicContainer.selectAll(".vzb-mc-mountain.vzb-mc-aggrlevel1").data(this.groupedPointers);
        this.mountainsAtomic = this.mountainAtomicContainer.selectAll(".vzb-mc-mountain.vzb-mc-aggrlevel0").data(this.mountainPointers);

        //exit selection -- remove shapes
        this.mountainsMergeStacked.exit().remove();
        this.mountainsMergeGrouped.exit().remove();
        this.mountainsAtomic.exit().remove();

        //enter selection -- add shapes
        this.mountainsMergeStacked.enter().append("path").attr("class", "vzb-mc-mountain vzb-mc-aggrlevel2");
        this.mountainsMergeGrouped.enter().append("path").attr("class", "vzb-mc-mountain vzb-mc-aggrlevel1");
        this.mountainsAtomic.enter().append("path").attr("class", "vzb-mc-mountain vzb-mc-aggrlevel0");

        //add interaction
        this.mountains = this.mountainAtomicContainer.selectAll(".vzb-mc-mountain");

        this.mountains.on("mousemove", function (d, i) {
            if (utils.isTouchDevice()) return;
            _this._interact()._mousemove(d, i);
        }).on("mouseout", function (d, i) {
            if (utils.isTouchDevice()) return;
            _this._interact()._mouseout(d, i);
        }).on("click", function (d, i) {
            if (utils.isTouchDevice()) return;
            _this._interact()._click(d, i);
            _this.highlightMarkers();
        }).onTap(function (d, i) {
            _this._interact()._click(d, i);
            d3.event.stopPropagation();
        }).onLongTap(function (d, i) {});
    },

    _interact: function _interact() {
        var _this = this;

        return {
            _mousemove: function _mousemove(d, i) {
                if (_this.model.time.dragging || _this.model.time.playing) return;

                _this.model.marker.highlightMarker(d);

                var mouse = d3.mouse(_this.graph.node()).map(function (d) {
                    return parseInt(d);
                });

                //position tooltip
                _this._setTooltip(d.key ? _this.model.marker.color.getColorlegendMarker().label.getItems()[d.key] : _this.values.label[d.KEY()]);
                _this._selectlist.showCloseCross(d, true);
            },
            _mouseout: function _mouseout(d, i) {
                if (_this.model.time.dragging || _this.model.time.playing) return;

                _this._setTooltip("");
                _this.model.marker.clearHighlighted();
                _this._selectlist.showCloseCross(d, false);
            },
            _click: function _click(d, i) {
                if (_this.model.time.dragging || _this.model.time.playing) return;

                _this.model.marker.selectMarker(d);
            }
        };
    },

    highlightMarkers: function highlightMarkers() {
        var _this = this;
        this.someHighlighted = this.model.marker.highlight.length > 0;

        if (!this.selectList || !this.someSelected) return;
        this.selectList.classed("vzb-highlight", function (d) {
            return _this.model.marker.isHighlighted(d);
        });
    },

    selectMarkers: function selectMarkers() {
        var _this = this;
        this.someSelected = this.model.marker.select.length > 0;

        this._selectlist.rebuild();
        this.nonSelectedOpacityZero = false;
    },

    _sumLeafPointersByMarker: function _sumLeafPointersByMarker(branch, marker) {
        var _this = this;
        if (!branch.key) return _this.values[marker][branch.KEY()];
        return d3.sum(branch.values.map(function (m) {
            return _this._sumLeafPointersByMarker(m, marker);
        }));
    },

    updateOpacity: function updateOpacity() {
        var _this = this;
        //if(!duration)duration = 0;

        var OPACITY_HIGHLT = 1.0;
        var OPACITY_HIGHLT_DIM = .3;
        var OPACITY_SELECT = this.model.marker.opacityRegular;
        var OPACITY_REGULAR = this.model.marker.opacityRegular;
        var OPACITY_SELECT_DIM = this.model.marker.opacitySelectDim;

        this.mountains.style("opacity", function (d) {

            if (_this.someHighlighted) {
                //highlight or non-highlight
                if (_this.model.marker.isHighlighted(d)) return OPACITY_HIGHLT;
            }

            if (_this.someSelected) {
                //selected or non-selected
                return _this.model.marker.isSelected(d) ? OPACITY_SELECT : OPACITY_SELECT_DIM;
            }

            if (_this.someHighlighted) return OPACITY_HIGHLT_DIM;

            return OPACITY_REGULAR;
        });

        this.mountains.classed("vzb-selected", function (d) {
            return _this.model.marker.isSelected(d);
        });

        var nonSelectedOpacityZero = _this.model.marker.opacitySelectDim < .01;

        // when pointer events need update...
        if (nonSelectedOpacityZero !== this.nonSelectedOpacityZero) {
            this.mountainsAtomic.style("pointer-events", function (d) {
                return !_this.someSelected || !nonSelectedOpacityZero || _this.model.marker.isSelected(d) ? "visible" : "none";
            });
        }

        this.nonSelectedOpacityZero = _this.model.marker.opacitySelectDim < .01;
    },

    updateTime: function updateTime() {
        var _this = this;

        this.time_1 = this.time == null ? this.model.time.value : this.time;
        this.time = this.model.time.value;
        this.duration = this.model.time.playing && this.time - this.time_1 > 0 ? this.model.time.delayAnimations : 0;
        this.year.setText(this.model.time.formatDate(this.time), this.duration);
    },

    updatePointers: function updatePointers() {
        var _this = this;
        this.yMax = 0;

        //spawn the original mountains
        this.mountainPointers.forEach(function (d, i) {
            var vertices = _this._spawn(_this.values, d);
            _this.cached[d.KEY()] = vertices;
            d.hidden = vertices.length === 0;
        });

        //recalculate stacking
        if (_this.model.marker.stack.which !== "none") {
            this.stackedPointers.forEach(function (group) {
                var toStack = [];
                group.values.forEach(function (subgroup) {
                    toStack = toStack.concat(subgroup.values.filter(function (f) {
                        return !f.hidden;
                    }));
                });
                _this.stack(toStack);
            });
        }

        this.mountainPointers.forEach(function (d) {
            d.yMax = d3.max(_this.cached[d.KEY()].map(function (m) {
                return m.y0 + m.y;
            }));
            if (_this.yMax < d.yMax) _this.yMax = d.yMax;
        });

        var mergeGrouped = _this.model.marker.group.merge;
        var mergeStacked = _this.model.marker.stack.merge;
        //var dragOrPlay = (_this.model.time.dragging || _this.model.time.playing) && this.model.marker.stack.which !== "none";

        //if(mergeStacked){
        this.stackedPointers.forEach(function (d) {
            var firstLast = _this._getFirstLastPointersInStack(d);
            _this.cached[d.key] = _this._getVerticesOfaMergedShape(firstLast);
            _this.values.color[d.key] = "_default";
            _this.values.axis_y[d.key] = _this._sumLeafPointersByMarker(d, "axis_y");
            d.yMax = firstLast.first.yMax;
        });
        //} else if (mergeGrouped || dragOrPlay){
        this.groupedPointers.forEach(function (d) {
            var firstLast = _this._getFirstLastPointersInStack(d);
            _this.cached[d.key] = _this._getVerticesOfaMergedShape(firstLast);
            _this.values.color[d.key] = _this.values.color[firstLast.first.KEY()];
            _this.values.axis_y[d.key] = _this._sumLeafPointersByMarker(d, "axis_y");
            d.yMax = firstLast.first.yMax;
        });
        //}

        if (!mergeStacked && !mergeGrouped && this.model.marker.stack.use === "property") {
            this.groupedPointers.forEach(function (d) {
                var visible = d.values.filter(function (f) {
                    return !f.hidden;
                });
                d.yMax = visible[0].yMax;
                d.values.forEach(function (e) {
                    e.yMaxGroup = d.yMax;
                });
            });
        }
    },

    _getFirstLastPointersInStack: function _getFirstLastPointersInStack(group) {
        var _this = this;

        var visible, visible2;

        if (group.values[0].values) {
            visible = group.values[0].values.filter(function (f) {
                return !f.hidden;
            });
            visible2 = group.values[group.values.length - 1].values.filter(function (f) {
                return !f.hidden;
            });
            var first = visible[0];
            var last = visible2[visible2.length - 1];
        } else {
            visible = group.values.filter(function (f) {
                return !f.hidden;
            });
            var first = visible[0];
            var last = visible[visible.length - 1];
        }

        if (!visible.length || visible2 && !visible2.length) utils.warn('mountain chart failed to generate shapes. check the incoming data');

        return {
            first: first,
            last: last
        };
    },

    _getVerticesOfaMergedShape: function _getVerticesOfaMergedShape(arg) {
        var _this = this;

        var first = arg.first.KEY();
        var last = arg.last.KEY();

        return _this.mesh.map(function (m, i) {
            var y = _this.cached[first][i].y0 + _this.cached[first][i].y - _this.cached[last][i].y0;
            var y0 = _this.cached[last][i].y0;
            return {
                x: m,
                y0: y0,
                y: y
            };
        });
    },

    _spawnMasks: function _spawnMasks() {
        var _this = this;

        var tailFatX = this._math.unscale(this.model.marker.axis_x.tailFatX);
        var tailCutX = this._math.unscale(this.model.marker.axis_x.tailCutX);
        var tailFade = this.model.marker.axis_x.tailFade;
        var k = 2 * Math.PI / (Math.log(tailFatX) - Math.log(tailCutX));
        var m = Math.PI - Math.log(tailFatX) * k;

        this.spawnMask = [];
        this.cosineShape = [];
        this.cosineArea = 0;

        this.mesh.map(function (dX, i) {
            _this.spawnMask[i] = dX < tailCutX ? 1 : dX > tailFade * 7 ? 0 : Math.exp((tailCutX - dX) / tailFade);
            _this.cosineShape[i] = dX > tailCutX && dX < tailFatX ? 1 + Math.cos(Math.log(dX) * k + m) : 0;
            _this.cosineArea += _this.cosineShape[i];
        });
    },

    _spawn: function _spawn(values, d) {
        var _this = this;

        var norm = values.axis_y[d.KEY()];
        var sigma = _this._math.giniToSigma(values.axis_s[d.KEY()]);
        var mu = _this._math.gdpToMu(values.axis_x[d.KEY()], sigma);

        if (!norm || !mu || !sigma) return [];

        var distribution = [];
        var acc = 0;

        this.mesh.map(function (dX, i) {
            distribution[i] = _this._math.pdf.lognormal(dX, mu, sigma);
            acc += _this.spawnMask[i] * distribution[i];
        });

        var result = this.mesh.map(function (dX, i) {
            return {
                x: dX,
                y0: 0,
                y: norm * (distribution[i] * (1 - _this.spawnMask[i]) + _this.cosineShape[i] / _this.cosineArea * acc)
            };
        });

        return result;
    },

    _adjustMaxY: function _adjustMaxY(options) {
        if (!options) options = {};
        var _this = this;
        var method = this.model.ui.chart.yMaxMethod;

        if (method !== "immediate" && !options.force) return;
        if (method === "latest") {
            var prevValues = _this.values;
            _this.model.marker.getFrame(_this.model.time.end, function (values) {
                if (!values) return;

                _this.values = values;
                _this.updatePointers();
                _this.values = prevValues;
                _this.yScale.domain([0, Math.round(_this.yMax)]);
                _this.updatePointers();
            });
        } else {
            if (!_this.yMax) utils.warn("Setting yMax to " + _this.yMax + ". You failed again :-/");
            _this.yScale.domain([0, Math.round(_this.yMax)]);
        }
    },

    redrawDataPoints: function redrawDataPoints() {
        var _this = this;
        var mergeGrouped = this.model.marker.group.merge;
        var mergeStacked = this.model.marker.stack.merge;
        var stackMode = this.model.marker.stack.which;
        //it's important to know if the chart is dragging or playing at the moment.
        //because if that is the case, the mountain chart will merge the stacked entities to save performance
        var dragOrPlay = (this.model.time.dragging || this.model.time.playing) &&
        //never merge when no entities are stacked
        stackMode !== "none";

        this._adjustMaxY();

        this.mountainsMergeStacked.each(function (d) {
            var view = d3.select(this);
            var hidden = !mergeStacked;
            _this._renderShape(view, d.KEY(), hidden);
        });

        this.mountainsMergeGrouped.each(function (d) {
            var view = d3.select(this);
            var hidden = !mergeGrouped && !dragOrPlay || mergeStacked && !_this.model.marker.isSelected(d);
            _this._renderShape(view, d.KEY(), hidden);
        });

        this.mountainsAtomic.each(function (d, i) {
            var view = d3.select(this);
            var hidden = d.hidden || (mergeGrouped || mergeStacked || dragOrPlay) && !_this.model.marker.isSelected(d);
            _this._renderShape(view, d.KEY(), hidden);
        });

        if (stackMode === "none") {
            this.mountainsAtomic.sort(function (a, b) {
                return b.yMax - a.yMax;
            });
        } else if (stackMode === "all") {
            // do nothing if everything is stacked

        } else {
            if (mergeGrouped || dragOrPlay) {
                // this.mountainsMergeGrouped.sort(function (a, b) {
                //     return b.yMax - a.yMax;
                // });
            } else {
                this.mountainsAtomic.sort(function (a, b) {
                    return b.yMaxGroup - a.yMaxGroup;
                });
            }
        }

        // exporting shapes for shape preloader. is needed once in a while
        // if (!this.shapes) this.shapes = {}
        // this.shapes[this.model.time.value.getUTCFullYear()] = {
        //     yMax: d3.format(".2e")(_this.yMax),
        //     shape: _this.cached["all"].map(function (d) {return d3.format(".2e")(d.y);})
        // }
    },

    redrawDataPointsOnlyColors: function redrawDataPointsOnlyColors() {
        var _this = this;
        if (!this.mountains) return utils.warn("redrawDataPointsOnlyColors(): no mountains  defined. likely a premature call, fix it!");
        var isColorUseIndicator = this.model.marker.color.use === "indicator";
        this.mountains.style("fill", function (d) {
            return _this.values.color[d.KEY()] ? isColorUseIndicator && _this.values.color[d.KEY()] == "_default" ? _this.model.marker.color.palette["_default"] : _this.cScale(_this.values.color[d.KEY()]) : COLOR_WHITEISH;
        });
    },

    _renderShape: function _renderShape(view, key, hidden) {
        var stack = this.model.marker.stack.which;
        var _this = this;

        view.classed("vzb-hidden", hidden);

        if (hidden) {
            if (stack !== "none") view.style("stroke-opacity", 0);
            return;
        }

        var filter = {};
        filter[this.KEY] = key;
        if (this.model.marker.isSelected(filter)) {
            view.attr("d", this.area(this.cached[key].filter(function (f) {
                return f.y > _this.values.axis_y[key] * THICKNESS_THRESHOLD;
            })));
        } else {
            view.attr("d", this.area(this.cached[key]));
        }

        //color use indicator suggests that this should be updated on every timeframe
        if (this.model.marker.color.use === "indicator") {
            view.style("fill", _this.values.color[key] ? _this.values.color[key] !== "_default" ? _this.cScale(_this.values.color[key]) : _this.model.marker.color.palette["_default"] : COLOR_WHITEISH);
        }

        if (stack !== "none") view.transition().duration(Math.random() * 900 + 100).ease("circle").style("stroke-opacity", .5);

        if (this.model.time.record) this._export.write({
            type: "path",
            id: key,
            time: this.model.time.value.getUTCFullYear(),
            fill: this.cScale(this.values.color[key]),
            d: this.area(this.cached[key])
        });
    },

    _setTooltip: function _setTooltip(tooltipText) {
        if (tooltipText) {
            var mouse = d3.mouse(this.graph.node()).map(function (d) {
                return parseInt(d);
            });

            //position tooltip
            this.tooltip.classed("vzb-hidden", false).attr("transform", "translate(" + mouse[0] + "," + mouse[1] + ")").selectAll("text").attr("text-anchor", "middle").attr("alignment-baseline", "middle").text(tooltipText);

            var contentBBox = this.tooltip.select("text")[0][0].getBBox();

            this.tooltip.select("rect").attr("width", contentBBox.width + 8).attr("height", contentBBox.height + 8).attr("x", -contentBBox.width - 25).attr("y", -contentBBox.height - 25).attr("rx", contentBBox.height * .2).attr("ry", contentBBox.height * .2);

            this.tooltip.selectAll("text").attr("x", -contentBBox.width - 25 + (contentBBox.width + 8) / 2).attr("y", -contentBBox.height - 25 + (contentBBox.height + 11) / 2); // 11 is 8 for margin + 3 for strokes
            var translateX = mouse[0] - contentBBox.width - 25 > 0 ? mouse[0] : contentBBox.width + 25;
            var translateY = mouse[1] - contentBBox.height - 25 > 0 ? mouse[1] : contentBBox.height + 25;
            this.tooltip.attr("transform", "translate(" + translateX + "," + translateY + ")");
        } else {

            this.tooltip.classed("vzb-hidden", true);
        }
    },

    preload: function preload() {
        var shape_path = _globals2.default.ext_resources.shapePath ? _globals2.default.ext_resources.shapePath : _globals2.default.ext_resources.host + _globals2.default.ext_resources.preloadPath + "mc_precomputed_shapes.json";

        var _this = this;

        return new Promise(function (resolve, reject) {

            d3.json(shape_path, function (error, json) {
                if (error) return console.warn("Failed loading json " + shape_path + ". " + error);
                _this.precomputedShapes = json;
                resolve();
            });
        });
    }

});

exports.default = MountainChartComponent;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
    value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _class = __webpack_require__(21);

var _class2 = _interopRequireDefault(_class);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

var MCMath = _class2.default.extend({

    init: function init(context) {
        this.context = context;

        this.xScaleFactor = 1;
        this.xScaleShift = 0;
    },

    rescale: function rescale(x) {
        return Math.exp(this.xScaleFactor * Math.log(x) + this.xScaleShift);
    },
    unscale: function unscale(x) {
        return Math.exp((Math.log(x) - this.xScaleShift) / this.xScaleFactor);
    },

    generateMesh: function generateMesh(length, scaleType, domain) {
        // span a uniform mesh across the entire X scale
        // if the scale is log, the mesh would be exponentially distorted to look uniform

        var rangeFrom = scaleType === "linear" ? domain[0] : Math.log(this.unscale(domain[0]));

        var rangeTo = scaleType === "linear" ? domain[1] : Math.log(this.unscale(domain[1]));

        var rangeStep = (rangeTo - rangeFrom) / length;

        var mesh = d3.range(rangeFrom, rangeTo, rangeStep).concat(rangeTo);

        if (scaleType !== "linear") {
            mesh = mesh.map(function (dX) {
                return Math.exp(dX);
            });
        } else {
            mesh = mesh.filter(function (dX) {
                return dX > 0;
            });
        }

        return mesh;
    },

    gdpToMu: function gdpToMu(gdp, sigma, xScaleFactor, xScaleShift) {
        // converting gdp per capita per day into MU for lognormal distribution
        // see https://en.wikipedia.org/wiki/Log-normal_distribution
        return Math.log(gdp / 365) - sigma * sigma / 2;
    },

    giniToSigma: function giniToSigma(gini) {
        // The ginis are turned into std deviation.
        // Mattias uses this formula in Excel: stddev = NORMSINV( ((gini/100)+1)/2 )*2^0.5
        return this.normsinv((gini / 100 + 1) / 2) * Math.pow(2, 0.5);
    },

    // this function returns PDF values for a specified distribution
    pdf: {
        normal: function normal(x, mu, sigma) {
            return Math.exp(-.5 * Math.log(2 * Math.PI) - Math.log(sigma) - Math.pow(x - mu, 2) / (2 * sigma * sigma));
        },
        lognormal: function lognormal(x, mu, sigma) {
            return Math.exp(-.5 * Math.log(2 * Math.PI) //should not be different for the two scales- (scaleType=="linear"?Math.log(x):0)
            - Math.log(sigma) - Math.pow(Math.log(x) - mu, 2) / (2 * sigma * sigma));
        }
    },

    normsinv: function normsinv(p) {
        //
        // Lower tail quantile for standard normal distribution function.
        //
        // This function returns an approximation of the inverse cumulative
        // standard normal distribution function.  I.e., given P, it returns
        // an approximation to the X satisfying P = Pr{Z <= X} where Z is a
        // random variable from the standard normal distribution.
        //
        // The algorithm uses a minimax approximation by rational functions
        // and the result has a relative error whose absolute value is less
        // than 1.15e-9.
        //
        // Author:      Peter John Acklam
        // (Javascript version by Alankar Misra @ Digital Sutras (alankar@digitalsutras.com))
        // Time-stamp:  2003-05-05 05:15:14
        // E-mail:      pjacklam@online.no
        // WWW URL:     http://home.online.no/~pjacklam

        // Taken from http://home.online.no/~pjacklam/notes/invnorm/index.html
        // adapted from Java code

        // An algorithm with a relative error less than 1.15*10-9 in the entire region.

        // Coefficients in rational approximations
        var a = [-3.969683028665376e+01, 2.209460984245205e+02, -2.759285104469687e+02, 1.383577518672690e+02, -3.066479806614716e+01, 2.506628277459239e+00];
        var b = [-5.447609879822406e+01, 1.615858368580409e+02, -1.556989798598866e+02, 6.680131188771972e+01, -1.328068155288572e+01];
        var c = [-7.784894002430293e-03, -3.223964580411365e-01, -2.400758277161838e+00, -2.549732539343734e+00, 4.374664141464968e+00, 2.938163982698783e+00];
        var d = [7.784695709041462e-03, 3.224671290700398e-01, 2.445134137142996e+00, 3.754408661907416e+00];

        // Define break-points.
        var plow = .02425;
        var phigh = 1 - plow;

        // Rational approximation for lower region:
        if (p < plow) {
            var q = Math.sqrt(-2 * Math.log(p));
            return (((((c[0] * q + c[1]) * q + c[2]) * q + c[3]) * q + c[4]) * q + c[5]) / ((((d[0] * q + d[1]) * q + d[2]) * q + d[3]) * q + 1);
        }

        // Rational approximation for upper region:
        if (phigh < p) {
            var q = Math.sqrt(-2 * Math.log(1 - p));
            return -(((((c[0] * q + c[1]) * q + c[2]) * q + c[3]) * q + c[4]) * q + c[5]) / ((((d[0] * q + d[1]) * q + d[2]) * q + d[3]) * q + 1);
        }

        // Rational approximation for central region:
        var q = p - .5;
        var r = q * q;
        return (((((a[0] * r + a[1]) * r + a[2]) * r + a[3]) * r + a[4]) * r + a[5]) * q / (((((b[0] * r + b[1]) * r + b[2]) * r + b[3]) * r + b[4]) * r + 1);
    }

});

exports.default = MCMath;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
    value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _class = __webpack_require__(21);

var _class2 = _interopRequireDefault(_class);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

var MCProbe = _class2.default.extend({

    init: function init(context) {
        this.context = context;
    },

    redraw: function redraw(options) {
        var _this = this.context;
        if (!options) options = {};

        if (!options.level) options.level = _this.model.ui.chart.probeX;

        _this.probeEl.classed("vzb-hidden", !options.level || !_this.model.ui.chart.showProbeX);
        if (!options.level) return;

        _this.xAxisEl.call(_this.xAxis.highlightValue(options.full ? options.level : "none"));

        var sumValue = 0;
        var totalArea = 0;
        var leftArea = 0;

        var _computeAreas = function _computeAreas(d) {
            sumValue += _this.values.axis_y[d.KEY()];
            _this.cached[d.KEY()].forEach(function (d) {
                totalArea += d.y;
                if (_this._math.rescale(d.x) < options.level) leftArea += d.y;
            });
        };

        if (_this.model.marker.stack.which === "all") {
            _this.stackedPointers.forEach(_computeAreas);
        } else if (_this.model.marker.stack.which === "none") {
            _this.mountainPointers.forEach(_computeAreas);
        } else {
            _this.groupedPointers.forEach(_computeAreas);
        }

        var formatter1 = d3.format(".3r");
        var formatter2 = _this.model.marker.axis_y.getTickFormatter();
        _this.heightOfLabels = _this.heightOfLabels || .66 * _this.height;

        _this.probeTextEl.each(function (d, i) {
            if (i !== 8) return;
            var view = d3.select(this);

            if (!options.full && _this.model.ui.chart.probeX == _this.model.marker.axis_x.tailFatX) {

                view.text(_this.translator("mount/extremepoverty")).classed("vzb-hidden", false).attr("x", -_this.height).attr("y", _this.xScale(options.level)).attr("dy", "-1.15em").attr("dx", "0.5em").attr("transform", "rotate(-90)");

                _this.heightOfLabels = _this.height - view.node().getBBox().width - view.node().getBBox().height * 1.75;
            } else {
                view.classed("vzb-hidden", true);
            }
        });

        _this.probeTextEl.each(function (d, i) {
            if (i === 8) return;
            var view = d3.select(this);

            var string;
            if (i === 0 || i === 4) string = formatter1(leftArea / totalArea * 100) + "%";
            if (i === 1 || i === 5) string = formatter1(100 - leftArea / totalArea * 100) + "%";
            if (i === 2 || i === 6) string = formatter2(sumValue * leftArea / totalArea);
            if (i === 3 || i === 7) string = formatter2(sumValue * (1 - leftArea / totalArea)) + " " + _this.translator("mount/people");

            view.text(string).classed("vzb-hidden", !options.full && i !== 0 && i !== 4).attr("x", _this.xScale(options.level) + ([0, 4, 2, 6].indexOf(i) > -1 ? -6 : +5)).attr("y", _this.heightOfLabels).attr("dy", [0, 1, 4, 5].indexOf(i) > -1 ? 0 : "1.5em");
        });

        _this.probeLineEl.attr("x1", _this.xScale(options.level)).attr("x2", _this.xScale(options.level)).attr("y1", _this.height + 6).attr("y2", 0);
    }

});

exports.default = MCProbe;

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

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _class = __webpack_require__(21);

var _class2 = _interopRequireDefault(_class);

var _iconset = __webpack_require__(10);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

var MCSelectList = _class2.default.extend({

  init: function init(context) {
    this.context = context;
  },

  rebuild: function rebuild(data) {
    var _this = this.context;
    var _local = this;

    var listData = _this.mountainPointers.concat(_this.groupedPointers).concat(_this.stackedPointers).filter(function (f) {
      return _this.model.marker.isSelected(f);
    }).sort(function (a, b) {
      if (a.sortValue && b.sortValue) {
        if (a.sortValue[1] === b.sortValue[1]) {
          return d3.descending(a.sortValue[0], b.sortValue[0]);
        }
        return d3.descending(a.sortValue[1], b.sortValue[1]);
      } else {
        if (a.aggrLevel != b.aggrLevel) {
          return d3.descending(a.aggrLevel, b.aggrLevel);
        } else if (a.aggrLevel && b.aggrLevel) {
          return d3.descending(a.yMax, b.yMax);
        } else {
          return 0;
        }
      }
    });
    _this.selectList = _this.mountainLabelContainer.selectAll("g.vzb-mc-label").data(utils.unique(listData, function (d) {
      return d.KEY();
    }));
    _this.selectList.exit().remove();
    _this.selectList.enter().append("g").attr("class", "vzb-mc-label").each(function (d, i) {
      var label = d3.select(this);
      label.append("circle").attr('class', 'vzb-mc-label-legend');
      label.append("text").attr("class", "vzb-mc-label-shadow vzb-mc-label-text");
      label.append("text").attr("class", "vzb-mc-label-text");
      label.append("g").attr("class", "vzb-mc-label-x vzb-label-shadow vzb-invisible").on("click", function (d, i) {
        if (utils.isTouchDevice()) return;
        d3.event.stopPropagation();
        _this.model.marker.clearHighlighted();
        _this.model.marker.selectMarker(d);
        d3.event.stopPropagation();
      }).onTap(function (d, i) {
        d3.select("#" + d.geo + "-label-" + _this._id).remove();
        _this.model.marker.clearHighlighted();
        _this.model.marker.selectMarker(d);
      });
      var labelCloseGroup = label.select("g.vzb-mc-label-x");
      if (!utils.isTouchDevice()) {
        utils.setIcon(labelCloseGroup, _iconset.close).select("svg").attr("class", "vzb-mc-label-x-icon").attr("width", "0px").attr("height", "0px");

        labelCloseGroup.insert("circle", "svg");
      } else {
        labelCloseGroup.append("rect");
        labelCloseGroup.append("text").attr("class", "vzb-mc-label-x-text").text("Deselect");
      }
    }).on("mousemove", function (d, i) {
      if (utils.isTouchDevice()) return;
      _local.showCloseCross(d, true);
      _this.model.marker.highlightMarker(d);
    }).on("mouseout", function (d, i) {
      if (utils.isTouchDevice()) return;
      _local.showCloseCross(d, false);
      _this.model.marker.clearHighlighted();
    }).on("click", function (d, i) {
      if (utils.isTouchDevice()) return;
      _this.model.marker.clearHighlighted();
      _this.model.marker.selectMarker(d);
    });
  },

  redraw: function redraw() {
    var _this = this.context;
    if (!_this.selectList || !_this.someSelected) return;

    var sample = _this.mountainLabelContainer.append("g").attr("class", "vzb-mc-label").append("text").text("0");
    var fontHeight = sample[0][0].getBBox().height * 1.2;
    var fontSizeToFontHeight = parseFloat(sample.style("font-size")) / fontHeight;
    d3.select(sample[0][0].parentNode).remove();
    var formatter = _this.model.marker.axis_y.getTickFormatter();

    var titleHeight = _this.yTitleEl.select("text").node().getBBox().height || 0;

    var maxFontHeight = (_this.height - titleHeight * 3) / (_this.selectList.data().length + 2);
    if (fontHeight > maxFontHeight) fontHeight = maxFontHeight;

    var currentAggrLevel = "null";
    var aggrLevelSpacing = 0;

    var groupLabels = _this.model.marker.color.getColorlegendMarker().label.getItems();

    var isRTL = _this.model.locale.isRTL();

    _this.selectList.attr("transform", function (d, i) {
      if (d.aggrLevel != currentAggrLevel) aggrLevelSpacing += fontHeight;
      var spacing = fontHeight * i + titleHeight * 1.5 + aggrLevelSpacing;
      currentAggrLevel = d.aggrLevel;
      return "translate(" + (isRTL ? _this.width : 0) + "," + spacing + ")";
    }).each(function (d, i) {

      var view = d3.select(this).attr("id", d.geo + '-label-' + _this._id);
      var name = "";
      if (d.key) {
        name = d.key === "all" ? _this.translator("mount/merging/world") : groupLabels[d.key];
      } else {
        name = _this.values.label[d.KEY()];
      }

      var number = _this.values.axis_y[d.KEY()];

      var string = name + ": " + formatter(number) + (i === 0 ? " " + _this.translator("mount/people") : "");

      var text = view.selectAll(".vzb-mc-label-text").attr("x", (isRTL ? -1 : 1) * fontHeight).attr("y", fontHeight).text(string).style("font-size", fontHeight === maxFontHeight ? fontHeight * fontSizeToFontHeight + "px" : null);

      var contentBBox = text[0][0].getBBox();

      var closeGroup = view.select(".vzb-mc-label-x");

      if (utils.isTouchDevice()) {
        var closeTextBBox = closeGroup.select("text").node().getBBox();
        closeGroup.classed("vzb-revert-color", true).select(".vzb-mc-label-x-text").classed("vzb-revert-color", true).attr("x", contentBBox.width + contentBBox.height * 1.12 + closeTextBBox.width * .5).attr("y", contentBBox.height * .55);

        closeGroup.select("rect").attr("width", closeTextBBox.width + contentBBox.height * .6).attr("height", contentBBox.height).attr("x", contentBBox.width + contentBBox.height * .9).attr("y", 0).attr("rx", contentBBox.height * .25).attr("ry", contentBBox.height * .25);
      } else {
        closeGroup.attr("x", contentBBox.width + contentBBox.height * 1.1).attr("y", contentBBox.height / 3);

        closeGroup.select("circle").attr("r", contentBBox.height * .4).attr("cx", (isRTL ? -1 : 1) * (contentBBox.width + contentBBox.height * 1.1)).attr("cy", contentBBox.height / 3);

        closeGroup.select("svg").attr("x", (isRTL ? -1 : 1) * (contentBBox.width + contentBBox.height * (1.1 - (isRTL ? -.4 : .4)))).attr("y", contentBBox.height * (1 / 3 - .4)).attr("width", contentBBox.height * .8).attr("height", contentBBox.height * .8);
      }

      view.select(".vzb-mc-label-legend").attr("r", fontHeight / 3).attr("cx", (isRTL ? -1 : 1) * fontHeight * .4).attr("cy", fontHeight / 1.5).style("fill", _this.cScale(_this.values.color[d.KEY()]));

      view.onTap(function (d, i) {
        d3.event.stopPropagation();
        _this.model.marker.highlightMarker(d);
        setTimeout(function () {
          _this.model.marker.unhighlightMarker(d);
        }, 2000);
      });
    });
  },

  showCloseCross: function showCloseCross(d, show) {
    var _this = this.context;
    var KEY = _this.KEY;
    //show the little cross on the selected label
    _this.selectList.filter(function (f) {
      return f[KEY] == d[KEY];
    }).select(".vzb-mc-label-x").classed("vzb-invisible", !show);
  }

});

exports.default = MCSelectList;

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

__webpack_require__(237);
module.exports = __webpack_require__(34).RegExp.escape;

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

var isObject = __webpack_require__(6)
  , isArray  = __webpack_require__(97)
  , SPECIES  = __webpack_require__(7)('species');

module.exports = function(original){
  var C;
  if(isArray(original)){
    C = original.constructor;
    // cross-realm fallback
    if(typeof C == 'function' && (C === Array || isArray(C.prototype)))C = undefined;
    if(isObject(C)){
      C = C[SPECIES];
      if(C === null)C = undefined;
    }
  } return C === undefined ? Array : C;
};

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

// 9.4.2.3 ArraySpeciesCreate(originalArray, length)
var speciesConstructor = __webpack_require__(229);

module.exports = function(original, length){
  return new (speciesConstructor(original))(length);
};

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

"use strict";
'use strict';
var anObject    = __webpack_require__(3)
  , toPrimitive = __webpack_require__(33)
  , NUMBER      = 'number';

module.exports = function(hint){
  if(hint !== 'string' && hint !== NUMBER && hint !== 'default')throw TypeError('Incorrect hint');
  return toPrimitive(anObject(this), hint != NUMBER);
};

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

// all enumerable object keys, includes symbols
var getKeys = __webpack_require__(53)
  , gOPS    = __webpack_require__(80)
  , pIE     = __webpack_require__(69);
module.exports = function(it){
  var result     = getKeys(it)
    , getSymbols = gOPS.f;
  if(getSymbols){
    var symbols = getSymbols(it)
      , isEnum  = pIE.f
      , i       = 0
      , key;
    while(symbols.length > i)if(isEnum.call(it, key = symbols[i++]))result.push(key);
  } return result;
};

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

var getKeys   = __webpack_require__(53)
  , toIObject = __webpack_require__(20);
module.exports = function(object, el){
  var O      = toIObject(object)
    , keys   = getKeys(O)
    , length = keys.length
    , index  = 0
    , key;
  while(length > index)if(O[key = keys[index++]] === el)return key;
};

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

"use strict";
'use strict';
var path      = __webpack_require__(235)
  , invoke    = __webpack_require__(76)
  , aFunction = __webpack_require__(16);
module.exports = function(/* ...pargs */){
  var fn     = aFunction(this)
    , length = arguments.length
    , pargs  = Array(length)
    , i      = 0
    , _      = path._
    , holder = false;
  while(length > i)if((pargs[i] = arguments[i++]) === _)holder = true;
  return function(/* ...args */){
    var that = this
      , aLen = arguments.length
      , j = 0, k = 0, args;
    if(!holder && !aLen)return invoke(fn, pargs, that);
    args = pargs.slice();
    if(holder)for(;length > j; j++)if(args[j] === _)args[j] = arguments[k++];
    while(aLen > k)args.push(arguments[k++]);
    return invoke(fn, args, that);
  };
};

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

module.exports = __webpack_require__(4);

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

module.exports = function(regExp, replace){
  var replacer = replace === Object(replace) ? function(part){
    return replace[part];
  } : replace;
  return function(it){
    return String(it).replace(regExp, replacer);
  };
};

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

// https://github.com/benjamingr/RexExp.escape
var $export = __webpack_require__(0)
  , $re     = __webpack_require__(236)(/[\\^$*+?.()|[\]{}]/g, '\\$&');

$export($export.S, 'RegExp', {escape: function escape(it){ return $re(it); }});


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

// 22.1.3.3 Array.prototype.copyWithin(target, start, end = this.length)
var $export = __webpack_require__(0);

$export($export.P, 'Array', {copyWithin: __webpack_require__(152)});

__webpack_require__(60)('copyWithin');

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

"use strict";
'use strict';
var $export = __webpack_require__(0)
  , $every  = __webpack_require__(31)(4);

$export($export.P + $export.F * !__webpack_require__(30)([].every, true), 'Array', {
  // 22.1.3.5 / 15.4.4.16 Array.prototype.every(callbackfn [, thisArg])
  every: function every(callbackfn /* , thisArg */){
    return $every(this, callbackfn, arguments[1]);
  }
});

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

// 22.1.3.6 Array.prototype.fill(value, start = 0, end = this.length)
var $export = __webpack_require__(0);

$export($export.P, 'Array', {fill: __webpack_require__(89)});

__webpack_require__(60)('fill');

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

"use strict";
'use strict';
var $export = __webpack_require__(0)
  , $filter = __webpack_require__(31)(2);

$export($export.P + $export.F * !__webpack_require__(30)([].filter, true), 'Array', {
  // 22.1.3.7 / 15.4.4.20 Array.prototype.filter(callbackfn [, thisArg])
  filter: function filter(callbackfn /* , thisArg */){
    return $filter(this, callbackfn, arguments[1]);
  }
});

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

"use strict";
'use strict';
// 22.1.3.9 Array.prototype.findIndex(predicate, thisArg = undefined)
var $export = __webpack_require__(0)
  , $find   = __webpack_require__(31)(6)
  , KEY     = 'findIndex'
  , forced  = true;
// Shouldn't skip holes
if(KEY in [])Array(1)[KEY](function(){ forced = false; });
$export($export.P + $export.F * forced, 'Array', {
  findIndex: function findIndex(callbackfn/*, that = undefined */){
    return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
  }
});
__webpack_require__(60)(KEY);

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

"use strict";
'use strict';
// 22.1.3.8 Array.prototype.find(predicate, thisArg = undefined)
var $export = __webpack_require__(0)
  , $find   = __webpack_require__(31)(5)
  , KEY     = 'find'
  , forced  = true;
// Shouldn't skip holes
if(KEY in [])Array(1)[KEY](function(){ forced = false; });
$export($export.P + $export.F * forced, 'Array', {
  find: function find(callbackfn/*, that = undefined */){
    return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
  }
});
__webpack_require__(60)(KEY);

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

"use strict";
'use strict';
var $export  = __webpack_require__(0)
  , $forEach = __webpack_require__(31)(0)
  , STRICT   = __webpack_require__(30)([].forEach, true);

$export($export.P + $export.F * !STRICT, 'Array', {
  // 22.1.3.10 / 15.4.4.18 Array.prototype.forEach(callbackfn [, thisArg])
  forEach: function forEach(callbackfn /* , thisArg */){
    return $forEach(this, callbackfn, arguments[1]);
  }
});

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

"use strict";
'use strict';
var ctx            = __webpack_require__(35)
  , $export        = __webpack_require__(0)
  , toObject       = __webpack_require__(13)
  , call           = __webpack_require__(161)
  , isArrayIter    = __webpack_require__(96)
  , toLength       = __webpack_require__(12)
  , createProperty = __webpack_require__(90)
  , getIterFn      = __webpack_require__(113);

$export($export.S + $export.F * !__webpack_require__(78)(function(iter){ Array.from(iter); }), 'Array', {
  // 22.1.2.1 Array.from(arrayLike, mapfn = undefined, thisArg = undefined)
  from: function from(arrayLike/*, mapfn = undefined, thisArg = undefined*/){
    var O       = toObject(arrayLike)
      , C       = typeof this == 'function' ? this : Array
      , aLen    = arguments.length
      , mapfn   = aLen > 1 ? arguments[1] : undefined
      , mapping = mapfn !== undefined
      , index   = 0
      , iterFn  = getIterFn(O)
      , length, result, step, iterator;
    if(mapping)mapfn = ctx(mapfn, aLen > 2 ? arguments[2] : undefined, 2);
    // if object isn't iterable or it's array with default iterator - use simple case
    if(iterFn != undefined && !(C == Array && isArrayIter(iterFn))){
      for(iterator = iterFn.call(O), result = new C; !(step = iterator.next()).done; index++){
        createProperty(result, index, mapping ? call(iterator, mapfn, [step.value, index], true) : step.value);
      }
    } else {
      length = toLength(O.length);
      for(result = new C(length); length > index; index++){
        createProperty(result, index, mapping ? mapfn(O[index], index) : O[index]);
      }
    }
    result.length = index;
    return result;
  }
});


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

"use strict";
'use strict';
var $export       = __webpack_require__(0)
  , $indexOf      = __webpack_require__(72)(false)
  , $native       = [].indexOf
  , NEGATIVE_ZERO = !!$native && 1 / [1].indexOf(1, -0) < 0;

$export($export.P + $export.F * (NEGATIVE_ZERO || !__webpack_require__(30)($native)), 'Array', {
  // 22.1.3.11 / 15.4.4.14 Array.prototype.indexOf(searchElement [, fromIndex])
  indexOf: function indexOf(searchElement /*, fromIndex = 0 */){
    return NEGATIVE_ZERO
      // convert -0 to +0
      ? $native.apply(this, arguments) || 0
      : $indexOf(this, searchElement, arguments[1]);
  }
});

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

// 22.1.2.2 / 15.4.3.2 Array.isArray(arg)
var $export = __webpack_require__(0);

$export($export.S, 'Array', {isArray: __webpack_require__(97)});

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

"use strict";
'use strict';
// 22.1.3.13 Array.prototype.join(separator)
var $export   = __webpack_require__(0)
  , toIObject = __webpack_require__(20)
  , arrayJoin = [].join;

// fallback for not array-like strings
$export($export.P + $export.F * (__webpack_require__(68) != Object || !__webpack_require__(30)(arrayJoin)), 'Array', {
  join: function join(separator){
    return arrayJoin.call(toIObject(this), separator === undefined ? ',' : separator);
  }
});

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

"use strict";
'use strict';
var $export       = __webpack_require__(0)
  , toIObject     = __webpack_require__(20)
  , toInteger     = __webpack_require__(43)
  , toLength      = __webpack_require__(12)
  , $native       = [].lastIndexOf
  , NEGATIVE_ZERO = !!$native && 1 / [1].lastIndexOf(1, -0) < 0;

$export($export.P + $export.F * (NEGATIVE_ZERO || !__webpack_require__(30)($native)), 'Array', {
  // 22.1.3.14 / 15.4.4.15 Array.prototype.lastIndexOf(searchElement [, fromIndex])
  lastIndexOf: function lastIndexOf(searchElement /*, fromIndex = @[*-1] */){
    // convert -0 to +0
    if(NEGATIVE_ZERO)return $native.apply(this, arguments) || 0;
    var O      = toIObject(this)
      , length = toLength(O.length)
      , index  = length - 1;
    if(arguments.length > 1)index = Math.min(index, toInteger(arguments[1]));
    if(index < 0)index = length + index;
    for(;index >= 0; index--)if(index in O)if(O[index] === searchElement)return index || 0;
    return -1;
  }
});

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

"use strict";
'use strict';
var $export = __webpack_require__(0)
  , $map    = __webpack_require__(31)(1);

$export($export.P + $export.F * !__webpack_require__(30)([].map, true), 'Array', {
  // 22.1.3.15 / 15.4.4.19 Array.prototype.map(callbackfn [, thisArg])
  map: function map(callbackfn /* , thisArg */){
    return $map(this, callbackfn, arguments[1]);
  }
});

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

"use strict";
'use strict';
var $export        = __webpack_require__(0)
  , createProperty = __webpack_require__(90);

// WebKit Array.of isn't generic
$export($export.S + $export.F * __webpack_require__(5)(function(){
  function F(){}
  return !(Array.of.call(F) instanceof F);
}), 'Array', {
  // 22.1.2.3 Array.of( ...items)
  of: function of(/* ...args */){
    var index  = 0
      , aLen   = arguments.length
      , result = new (typeof this == 'function' ? this : Array)(aLen);
    while(aLen > index)createProperty(result, index, arguments[index++]);
    result.length = aLen;
    return result;
  }
});

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

"use strict";
'use strict';
var $export = __webpack_require__(0)
  , $reduce = __webpack_require__(154);

$export($export.P + $export.F * !__webpack_require__(30)([].reduceRight, true), 'Array', {
  // 22.1.3.19 / 15.4.4.22 Array.prototype.reduceRight(callbackfn [, initialValue])
  reduceRight: function reduceRight(callbackfn /* , initialValue */){
    return $reduce(this, callbackfn, arguments.length, arguments[1], true);
  }
});

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

"use strict";
'use strict';
var $export = __webpack_require__(0)
  , $reduce = __webpack_require__(154);

$export($export.P + $export.F * !__webpack_require__(30)([].reduce, true), 'Array', {
  // 22.1.3.18 / 15.4.4.21 Array.prototype.reduce(callbackfn [, initialValue])
  reduce: function reduce(callbackfn /* , initialValue */){
    return $reduce(this, callbackfn, arguments.length, arguments[1], false);
  }
});

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

"use strict";
'use strict';
var $export    = __webpack_require__(0)
  , html       = __webpack_require__(94)
  , cof        = __webpack_require__(28)
  , toIndex    = __webpack_require__(56)
  , toLength   = __webpack_require__(12)
  , arraySlice = [].slice;

// fallback for not array-like ES3 strings and DOM objects
$export($export.P + $export.F * __webpack_require__(5)(function(){
  if(html)arraySlice.call(html);
}), 'Array', {
  slice: function slice(begin, end){
    var len   = toLength(this.length)
      , klass = cof(this);
    end = end === undefined ? len : end;
    if(klass == 'Array')return arraySlice.call(this, begin, end);
    var start  = toIndex(begin, len)
      , upTo   = toIndex(end, len)
      , size   = toLength(upTo - start)
      , cloned = Array(size)
      , i      = 0;
    for(; i < size; i++)cloned[i] = klass == 'String'
      ? this.charAt(start + i)
      : this[start + i];
    return cloned;
  }
});

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

"use strict";
'use strict';
var $export = __webpack_require__(0)
  , $some   = __webpack_require__(31)(3);

$export($export.P + $export.F * !__webpack_require__(30)([].some, true), 'Array', {
  // 22.1.3.23 / 15.4.4.17 Array.prototype.some(callbackfn [, thisArg])
  some: function some(callbackfn /* , thisArg */){
    return $some(this, callbackfn, arguments[1]);
  }
});

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

"use strict";
'use strict';
var $export   = __webpack_require__(0)
  , aFunction = __webpack_require__(16)
  , toObject  = __webpack_require__(13)
  , fails     = __webpack_require__(5)
  , $sort     = [].sort
  , test      = [1, 2, 3];

$export($export.P + $export.F * (fails(function(){
  // IE8-
  test.sort(undefined);
}) || !fails(function(){
  // V8 bug
  test.sort(null);
  // Old WebKit
}) || !__webpack_require__(30)($sort)), 'Array', {
  // 22.1.3.25 Array.prototype.sort(comparefn)
  sort: function sort(comparefn){
    return comparefn === undefined
      ? $sort.call(toObject(this))
      : $sort.call(toObject(this), aFunction(comparefn));
  }
});

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

__webpack_require__(55)('Array');

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

// 20.3.3.1 / 15.9.4.4 Date.now()
var $export = __webpack_require__(0);

$export($export.S, 'Date', {now: function(){ return new Date().getTime(); }});

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

"use strict";
'use strict';
// 20.3.4.36 / 15.9.5.43 Date.prototype.toISOString()
var $export = __webpack_require__(0)
  , fails   = __webpack_require__(5)
  , getTime = Date.prototype.getTime;

var lz = function(num){
  return num > 9 ? num : '0' + num;
};

// PhantomJS / old WebKit has a broken implementations
$export($export.P + $export.F * (fails(function(){
  return new Date(-5e13 - 1).toISOString() != '0385-07-25T07:06:39.999Z';
}) || !fails(function(){
  new Date(NaN).toISOString();
})), 'Date', {
  toISOString: function toISOString(){
    if(!isFinite(getTime.call(this)))throw RangeError('Invalid time value');
    var d = this
      , y = d.getUTCFullYear()
      , m = d.getUTCMilliseconds()
      , s = y < 0 ? '-' : y > 9999 ? '+' : '';
    return s + ('00000' + Math.abs(y)).slice(s ? -6 : -4) +
      '-' + lz(d.getUTCMonth() + 1) + '-' + lz(d.getUTCDate()) +
      'T' + lz(d.getUTCHours()) + ':' + lz(d.getUTCMinutes()) +
      ':' + lz(d.getUTCSeconds()) + '.' + (m > 99 ? m : '0' + lz(m)) + 'Z';
  }
});

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

"use strict";
'use strict';
var $export     = __webpack_require__(0)
  , toObject    = __webpack_require__(13)
  , toPrimitive = __webpack_require__(33);

$export($export.P + $export.F * __webpack_require__(5)(function(){
  return new Date(NaN).toJSON() !== null || Date.prototype.toJSON.call({toISOString: function(){ return 1; }}) !== 1;
}), 'Date', {
  toJSON: function toJSON(key){
    var O  = toObject(this)
      , pv = toPrimitive(O);
    return typeof pv == 'number' && !isFinite(pv) ? null : O.toISOString();
  }
});

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

var TO_PRIMITIVE = __webpack_require__(7)('toPrimitive')
  , proto        = Date.prototype;

if(!(TO_PRIMITIVE in proto))__webpack_require__(17)(proto, TO_PRIMITIVE, __webpack_require__(231));

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

var DateProto    = Date.prototype
  , INVALID_DATE = 'Invalid Date'
  , TO_STRING    = 'toString'
  , $toString    = DateProto[TO_STRING]
  , getTime      = DateProto.getTime;
if(new Date(NaN) + '' != INVALID_DATE){
  __webpack_require__(18)(DateProto, TO_STRING, function toString(){
    var value = getTime.call(this);
    return value === value ? $toString.call(this) : INVALID_DATE;
  });
}

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

// 19.2.3.2 / 15.3.4.5 Function.prototype.bind(thisArg, args...)
var $export = __webpack_require__(0);

$export($export.P, 'Function', {bind: __webpack_require__(155)});

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

"use strict";
'use strict';
var isObject       = __webpack_require__(6)
  , getPrototypeOf = __webpack_require__(26)
  , HAS_INSTANCE   = __webpack_require__(7)('hasInstance')
  , FunctionProto  = Function.prototype;
// 19.2.3.6 Function.prototype[@@hasInstance](V)
if(!(HAS_INSTANCE in FunctionProto))__webpack_require__(9).f(FunctionProto, HAS_INSTANCE, {value: function(O){
  if(typeof this != 'function' || !isObject(O))return false;
  if(!isObject(this.prototype))return O instanceof this;
  // for environment w/o native `@@hasInstance` logic enough `instanceof`, but add this:
  while(O = getPrototypeOf(O))if(this.prototype === O)return true;
  return false;
}});

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

var dP         = __webpack_require__(9).f
  , createDesc = __webpack_require__(42)
  , has        = __webpack_require__(15)
  , FProto     = Function.prototype
  , nameRE     = /^\s*function ([^ (]*)/
  , NAME       = 'name';

var isExtensible = Object.isExtensible || function(){
  return true;
};

// 19.2.4.2 name
NAME in FProto || __webpack_require__(8) && dP(FProto, NAME, {
  configurable: true,
  get: function(){
    try {
      var that = this
        , name = ('' + that).match(nameRE)[1];
      has(that, NAME) || !isExtensible(that) || dP(that, NAME, createDesc(5, name));
      return name;
    } catch(e){
      return '';
    }
  }
});

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

// 20.2.2.3 Math.acosh(x)
var $export = __webpack_require__(0)
  , log1p   = __webpack_require__(163)
  , sqrt    = Math.sqrt
  , $acosh  = Math.acosh;

$export($export.S + $export.F * !($acosh
  // V8 bug: https://code.google.com/p/v8/issues/detail?id=3509
  && Math.floor($acosh(Number.MAX_VALUE)) == 710
  // Tor Browser bug: Math.acosh(Infinity) -> NaN 
  && $acosh(Infinity) == Infinity
), 'Math', {
  acosh: function acosh(x){
    return (x = +x) < 1 ? NaN : x > 94906265.62425156
      ? Math.log(x) + Math.LN2
      : log1p(x - 1 + sqrt(x - 1) * sqrt(x + 1));
  }
});

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

// 20.2.2.5 Math.asinh(x)
var $export = __webpack_require__(0)
  , $asinh  = Math.asinh;

function asinh(x){
  return !isFinite(x = +x) || x == 0 ? x : x < 0 ? -asinh(-x) : Math.log(x + Math.sqrt(x * x + 1));
}

// Tor Browser bug: Math.asinh(0) -> -0 
$export($export.S + $export.F * !($asinh && 1 / $asinh(0) > 0), 'Math', {asinh: asinh});

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

// 20.2.2.7 Math.atanh(x)
var $export = __webpack_require__(0)
  , $atanh  = Math.atanh;

// Tor Browser bug: Math.atanh(-0) -> 0 
$export($export.S + $export.F * !($atanh && 1 / $atanh(-0) < 0), 'Math', {
  atanh: function atanh(x){
    return (x = +x) == 0 ? x : Math.log((1 + x) / (1 - x)) / 2;
  }
});

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

// 20.2.2.9 Math.cbrt(x)
var $export = __webpack_require__(0)
  , sign    = __webpack_require__(101);

$export($export.S, 'Math', {
  cbrt: function cbrt(x){
    return sign(x = +x) * Math.pow(Math.abs(x), 1 / 3);
  }
});

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

// 20.2.2.11 Math.clz32(x)
var $export = __webpack_require__(0);

$export($export.S, 'Math', {
  clz32: function clz32(x){
    return (x >>>= 0) ? 31 - Math.floor(Math.log(x + 0.5) * Math.LOG2E) : 32;
  }
});

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

// 20.2.2.12 Math.cosh(x)
var $export = __webpack_require__(0)
  , exp     = Math.exp;

$export($export.S, 'Math', {
  cosh: function cosh(x){
    return (exp(x = +x) + exp(-x)) / 2;
  }
});

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

// 20.2.2.14 Math.expm1(x)
var $export = __webpack_require__(0)
  , $expm1  = __webpack_require__(100);

$export($export.S + $export.F * ($expm1 != Math.expm1), 'Math', {expm1: $expm1});

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

// 20.2.2.16 Math.fround(x)
var $export   = __webpack_require__(0)
  , sign      = __webpack_require__(101)
  , pow       = Math.pow
  , EPSILON   = pow(2, -52)
  , EPSILON32 = pow(2, -23)
  , MAX32     = pow(2, 127) * (2 - EPSILON32)
  , MIN32     = pow(2, -126);

var roundTiesToEven = function(n){
  return n + 1 / EPSILON - 1 / EPSILON;
};


$export($export.S, 'Math', {
  fround: function fround(x){
    var $abs  = Math.abs(x)
      , $sign = sign(x)
      , a, result;
    if($abs < MIN32)return $sign * roundTiesToEven($abs / MIN32 / EPSILON32) * MIN32 * EPSILON32;
    a = (1 + EPSILON32 / EPSILON) * $abs;
    result = a - (a - $abs);
    if(result > MAX32 || result != result)return $sign * Infinity;
    return $sign * result;
  }
});

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

// 20.2.2.17 Math.hypot([value1[, value2[, … ]]])
var $export = __webpack_require__(0)
  , abs     = Math.abs;

$export($export.S, 'Math', {
  hypot: function hypot(value1, value2){ // eslint-disable-line no-unused-vars
    var sum  = 0
      , i    = 0
      , aLen = arguments.length
      , larg = 0
      , arg, div;
    while(i < aLen){
      arg = abs(arguments[i++]);
      if(larg < arg){
        div  = larg / arg;
        sum  = sum * div * div + 1;
        larg = arg;
      } else if(arg > 0){
        div  = arg / larg;
        sum += div * div;
      } else sum += arg;
    }
    return larg === Infinity ? Infinity : larg * Math.sqrt(sum);
  }
});

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

// 20.2.2.18 Math.imul(x, y)
var $export = __webpack_require__(0)
  , $imul   = Math.imul;

// some WebKit versions fails with big numbers, some has wrong arity
$export($export.S + $export.F * __webpack_require__(5)(function(){
  return $imul(0xffffffff, 5) != -5 || $imul.length != 2;
}), 'Math', {
  imul: function imul(x, y){
    var UINT16 = 0xffff
      , xn = +x
      , yn = +y
      , xl = UINT16 & xn
      , yl = UINT16 & yn;
    return 0 | xl * yl + ((UINT16 & xn >>> 16) * yl + xl * (UINT16 & yn >>> 16) << 16 >>> 0);
  }
});

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

// 20.2.2.21 Math.log10(x)
var $export = __webpack_require__(0);

$export($export.S, 'Math', {
  log10: function log10(x){
    return Math.log(x) / Math.LN10;
  }
});

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

// 20.2.2.20 Math.log1p(x)
var $export = __webpack_require__(0);

$export($export.S, 'Math', {log1p: __webpack_require__(163)});

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

// 20.2.2.22 Math.log2(x)
var $export = __webpack_require__(0);

$export($export.S, 'Math', {
  log2: function log2(x){
    return Math.log(x) / Math.LN2;
  }
});

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

// 20.2.2.28 Math.sign(x)
var $export = __webpack_require__(0);

$export($export.S, 'Math', {sign: __webpack_require__(101)});

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

// 20.2.2.30 Math.sinh(x)
var $export = __webpack_require__(0)
  , expm1   = __webpack_require__(100)
  , exp     = Math.exp;

// V8 near Chromium 38 has a problem with very small numbers
$export($export.S + $export.F * __webpack_require__(5)(function(){
  return !Math.sinh(-2e-17) != -2e-17;
}), 'Math', {
  sinh: function sinh(x){
    return Math.abs(x = +x) < 1
      ? (expm1(x) - expm1(-x)) / 2
      : (exp(x - 1) - exp(-x - 1)) * (Math.E / 2);
  }
});

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

// 20.2.2.33 Math.tanh(x)
var $export = __webpack_require__(0)
  , expm1   = __webpack_require__(100)
  , exp     = Math.exp;

$export($export.S, 'Math', {
  tanh: function tanh(x){
    var a = expm1(x = +x)
      , b = expm1(-x);
    return a == Infinity ? 1 : b == Infinity ? -1 : (a - b) / (exp(x) + exp(-x));
  }
});

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

// 20.2.2.34 Math.trunc(x)
var $export = __webpack_require__(0);

$export($export.S, 'Math', {
  trunc: function trunc(it){
    return (it > 0 ? Math.floor : Math.ceil)(it);
  }
});

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

"use strict";
'use strict';
var global            = __webpack_require__(4)
  , has               = __webpack_require__(15)
  , cof               = __webpack_require__(28)
  , inheritIfRequired = __webpack_require__(95)
  , toPrimitive       = __webpack_require__(33)
  , fails             = __webpack_require__(5)
  , gOPN              = __webpack_require__(52).f
  , gOPD              = __webpack_require__(25).f
  , dP                = __webpack_require__(9).f
  , $trim             = __webpack_require__(64).trim
  , NUMBER            = 'Number'
  , $Number           = global[NUMBER]
  , Base              = $Number
  , proto             = $Number.prototype
  // Opera ~12 has broken Object#toString
  , BROKEN_COF        = cof(__webpack_require__(51)(proto)) == NUMBER
  , TRIM              = 'trim' in String.prototype;

// 7.1.3 ToNumber(argument)
var toNumber = function(argument){
  var it = toPrimitive(argument, false);
  if(typeof it == 'string' && it.length > 2){
    it = TRIM ? it.trim() : $trim(it, 3);
    var first = it.charCodeAt(0)
      , third, radix, maxCode;
    if(first === 43 || first === 45){
      third = it.charCodeAt(2);
      if(third === 88 || third === 120)return NaN; // Number('+0x1') should be NaN, old V8 fix
    } else if(first === 48){
      switch(it.charCodeAt(1)){
        case 66 : case 98  : radix = 2; maxCode = 49; break; // fast equal /^0b[01]+$/i
        case 79 : case 111 : radix = 8; maxCode = 55; break; // fast equal /^0o[0-7]+$/i
        default : return +it;
      }
      for(var digits = it.slice(2), i = 0, l = digits.length, code; i < l; i++){
        code = digits.charCodeAt(i);
        // parseInt parses a string to a first unavailable symbol
        // but ToNumber should return NaN if a string contains unavailable symbols
        if(code < 48 || code > maxCode)return NaN;
      } return parseInt(digits, radix);
    }
  } return +it;
};

if(!$Number(' 0o1') || !$Number('0b1') || $Number('+0x1')){
  $Number = function Number(value){
    var it = arguments.length < 1 ? 0 : value
      , that = this;
    return that instanceof $Number
      // check on 1..constructor(foo) case
      && (BROKEN_COF ? fails(function(){ proto.valueOf.call(that); }) : cof(that) != NUMBER)
        ? inheritIfRequired(new Base(toNumber(it)), that, $Number) : toNumber(it);
  };
  for(var keys = __webpack_require__(8) ? gOPN(Base) : (
    // ES3:
    'MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,' +
    // ES6 (in case, if modules with ES6 Number statics required before):
    'EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,' +
    'MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger'
  ).split(','), j = 0, key; keys.length > j; j++){
    if(has(Base, key = keys[j]) && !has($Number, key)){
      dP($Number, key, gOPD(Base, key));
    }
  }
  $Number.prototype = proto;
  proto.constructor = $Number;
  __webpack_require__(18)(global, NUMBER, $Number);
}

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

// 20.1.2.1 Number.EPSILON
var $export = __webpack_require__(0);

$export($export.S, 'Number', {EPSILON: Math.pow(2, -52)});

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

// 20.1.2.2 Number.isFinite(number)
var $export   = __webpack_require__(0)
  , _isFinite = __webpack_require__(4).isFinite;

$export($export.S, 'Number', {
  isFinite: function isFinite(it){
    return typeof it == 'number' && _isFinite(it);
  }
});

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

// 20.1.2.3 Number.isInteger(number)
var $export = __webpack_require__(0);

$export($export.S, 'Number', {isInteger: __webpack_require__(160)});

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

// 20.1.2.4 Number.isNaN(number)
var $export = __webpack_require__(0);

$export($export.S, 'Number', {
  isNaN: function isNaN(number){
    return number != number;
  }
});

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

// 20.1.2.5 Number.isSafeInteger(number)
var $export   = __webpack_require__(0)
  , isInteger = __webpack_require__(160)
  , abs       = Math.abs;

$export($export.S, 'Number', {
  isSafeInteger: function isSafeInteger(number){
    return isInteger(number) && abs(number) <= 0x1fffffffffffff;
  }
});

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

// 20.1.2.6 Number.MAX_SAFE_INTEGER
var $export = __webpack_require__(0);

$export($export.S, 'Number', {MAX_SAFE_INTEGER: 0x1fffffffffffff});

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

// 20.1.2.10 Number.MIN_SAFE_INTEGER
var $export = __webpack_require__(0);

$export($export.S, 'Number', {MIN_SAFE_INTEGER: -0x1fffffffffffff});

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

var $export     = __webpack_require__(0)
  , $parseFloat = __webpack_require__(170);
// 20.1.2.12 Number.parseFloat(string)
$export($export.S + $export.F * (Number.parseFloat != $parseFloat), 'Number', {parseFloat: $parseFloat});

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

var $export   = __webpack_require__(0)
  , $parseInt = __webpack_require__(171);
// 20.1.2.13 Number.parseInt(string, radix)
$export($export.S + $export.F * (Number.parseInt != $parseInt), 'Number', {parseInt: $parseInt});

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

"use strict";
'use strict';
var $export      = __webpack_require__(0)
  , toInteger    = __webpack_require__(43)
  , aNumberValue = __webpack_require__(151)
  , repeat       = __webpack_require__(108)
  , $toFixed     = 1..toFixed
  , floor        = Math.floor
  , data         = [0, 0, 0, 0, 0, 0]
  , ERROR        = 'Number.toFixed: incorrect invocation!'
  , ZERO         = '0';

var multiply = function(n, c){
  var i  = -1
    , c2 = c;
  while(++i < 6){
    c2 += n * data[i];
    data[i] = c2 % 1e7;
    c2 = floor(c2 / 1e7);
  }
};
var divide = function(n){
  var i = 6
    , c = 0;
  while(--i >= 0){
    c += data[i];
    data[i] = floor(c / n);
    c = (c % n) * 1e7;
  }
};
var numToString = function(){
  var i = 6
    , s = '';
  while(--i >= 0){
    if(s !== '' || i === 0 || data[i] !== 0){
      var t = String(data[i]);
      s = s === '' ? t : s + repeat.call(ZERO, 7 - t.length) + t;
    }
  } return s;
};
var pow = function(x, n, acc){
  return n === 0 ? acc : n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc);
};
var log = function(x){
  var n  = 0
    , x2 = x;
  while(x2 >= 4096){
    n += 12;
    x2 /= 4096;
  }
  while(x2 >= 2){
    n  += 1;
    x2 /= 2;
  } return n;
};

$export($export.P + $export.F * (!!$toFixed && (
  0.00008.toFixed(3) !== '0.000' ||
  0.9.toFixed(0) !== '1' ||
  1.255.toFixed(2) !== '1.25' ||
  1000000000000000128..toFixed(0) !== '1000000000000000128'
) || !__webpack_require__(5)(function(){
  // V8 ~ Android 4.3-
  $toFixed.call({});
})), 'Number', {
  toFixed: function toFixed(fractionDigits){
    var x = aNumberValue(this, ERROR)
      , f = toInteger(fractionDigits)
      , s = ''
      , m = ZERO
      , e, z, j, k;
    if(f < 0 || f > 20)throw RangeError(ERROR);
    if(x != x)return 'NaN';
    if(x <= -1e21 || x >= 1e21)return String(x);
    if(x < 0){
      s = '-';
      x = -x;
    }
    if(x > 1e-21){
      e = log(x * pow(2, 69, 1)) - 69;
      z = e < 0 ? x * pow(2, -e, 1) : x / pow(2, e, 1);
      z *= 0x10000000000000;
      e = 52 - e;
      if(e > 0){
        multiply(0, z);
        j = f;
        while(j >= 7){
          multiply(1e7, 0);
          j -= 7;
        }
        multiply(pow(10, j, 1), 0);
        j = e - 1;
        while(j >= 23){
          divide(1 << 23);
          j -= 23;
        }
        divide(1 << j);
        multiply(1, 1);
        divide(2);
        m = numToString();
      } else {
        multiply(0, z);
        multiply(1 << -e, 0);
        m = numToString() + repeat.call(ZERO, f);
      }
    }
    if(f > 0){
      k = m.length;
      m = s + (k <= f ? '0.' + repeat.call(ZERO, f - k) + m : m.slice(0, k - f) + '.' + m.slice(k - f));
    } else {
      m = s + m;
    } return m;
  }
});

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

"use strict";
'use strict';
var $export      = __webpack_require__(0)
  , $fails       = __webpack_require__(5)
  , aNumberValue = __webpack_require__(151)
  , $toPrecision = 1..toPrecision;

$export($export.P + $export.F * ($fails(function(){
  // IE7-
  return $toPrecision.call(1, undefined) !== '1';
}) || !$fails(function(){
  // V8 ~ Android 4.3-
  $toPrecision.call({});
})), 'Number', {
  toPrecision: function toPrecision(precision){
    var that = aNumberValue(this, 'Number#toPrecision: incorrect invocation!');
    return precision === undefined ? $toPrecision.call(that) : $toPrecision.call(that, precision); 
  }
});

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

// 19.1.3.1 Object.assign(target, source)
var $export = __webpack_require__(0);

$export($export.S + $export.F, 'Object', {assign: __webpack_require__(164)});

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

var $export = __webpack_require__(0)
// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])
$export($export.S, 'Object', {create: __webpack_require__(51)});

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

var $export = __webpack_require__(0);
// 19.1.2.3 / 15.2.3.7 Object.defineProperties(O, Properties)
$export($export.S + $export.F * !__webpack_require__(8), 'Object', {defineProperties: __webpack_require__(165)});

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

var $export = __webpack_require__(0);
// 19.1.2.4 / 15.2.3.6 Object.defineProperty(O, P, Attributes)
$export($export.S + $export.F * !__webpack_require__(8), 'Object', {defineProperty: __webpack_require__(9).f});

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

// 19.1.2.5 Object.freeze(O)
var isObject = __webpack_require__(6)
  , meta     = __webpack_require__(41).onFreeze;

__webpack_require__(32)('freeze', function($freeze){
  return function freeze(it){
    return $freeze && isObject(it) ? $freeze(meta(it)) : it;
  };
});

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

// 19.1.2.6 Object.getOwnPropertyDescriptor(O, P)
var toIObject                 = __webpack_require__(20)
  , $getOwnPropertyDescriptor = __webpack_require__(25).f;

__webpack_require__(32)('getOwnPropertyDescriptor', function(){
  return function getOwnPropertyDescriptor(it, key){
    return $getOwnPropertyDescriptor(toIObject(it), key);
  };
});

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

// 19.1.2.7 Object.getOwnPropertyNames(O)
__webpack_require__(32)('getOwnPropertyNames', function(){
  return __webpack_require__(166).f;
});

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

// 19.1.2.9 Object.getPrototypeOf(O)
var toObject        = __webpack_require__(13)
  , $getPrototypeOf = __webpack_require__(26);

__webpack_require__(32)('getPrototypeOf', function(){
  return function getPrototypeOf(it){
    return $getPrototypeOf(toObject(it));
  };
});

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

// 19.1.2.11 Object.isExtensible(O)
var isObject = __webpack_require__(6);

__webpack_require__(32)('isExtensible', function($isExtensible){
  return function isExtensible(it){
    return isObject(it) ? $isExtensible ? $isExtensible(it) : true : false;
  };
});

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

// 19.1.2.12 Object.isFrozen(O)
var isObject = __webpack_require__(6);

__webpack_require__(32)('isFrozen', function($isFrozen){
  return function isFrozen(it){
    return isObject(it) ? $isFrozen ? $isFrozen(it) : false : true;
  };
});

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

// 19.1.2.13 Object.isSealed(O)
var isObject = __webpack_require__(6);

__webpack_require__(32)('isSealed', function($isSealed){
  return function isSealed(it){
    return isObject(it) ? $isSealed ? $isSealed(it) : false : true;
  };
});

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

// 19.1.3.10 Object.is(value1, value2)
var $export = __webpack_require__(0);
$export($export.S, 'Object', {is: __webpack_require__(172)});

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

// 19.1.2.14 Object.keys(O)
var toObject = __webpack_require__(13)
  , $keys    = __webpack_require__(53);

__webpack_require__(32)('keys', function(){
  return function keys(it){
    return $keys(toObject(it));
  };
});

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

// 19.1.2.15 Object.preventExtensions(O)
var isObject = __webpack_require__(6)
  , meta     = __webpack_require__(41).onFreeze;

__webpack_require__(32)('preventExtensions', function($preventExtensions){
  return function preventExtensions(it){
    return $preventExtensions && isObject(it) ? $preventExtensions(meta(it)) : it;
  };
});

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

// 19.1.2.17 Object.seal(O)
var isObject = __webpack_require__(6)
  , meta     = __webpack_require__(41).onFreeze;

__webpack_require__(32)('seal', function($seal){
  return function seal(it){
    return $seal && isObject(it) ? $seal(meta(it)) : it;
  };
});

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

// 19.1.3.19 Object.setPrototypeOf(O, proto)
var $export = __webpack_require__(0);
$export($export.S, 'Object', {setPrototypeOf: __webpack_require__(103).set});

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

"use strict";
'use strict';
// 19.1.3.6 Object.prototype.toString()
var classof = __webpack_require__(67)
  , test    = {};
test[__webpack_require__(7)('toStringTag')] = 'z';
if(test + '' != '[object z]'){
  __webpack_require__(18)(Object.prototype, 'toString', function toString(){
    return '[object ' + classof(this) + ']';
  }, true);
}

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

var $export     = __webpack_require__(0)
  , $parseFloat = __webpack_require__(170);
// 18.2.4 parseFloat(string)
$export($export.G + $export.F * (parseFloat != $parseFloat), {parseFloat: $parseFloat});

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

var $export   = __webpack_require__(0)
  , $parseInt = __webpack_require__(171);
// 18.2.5 parseInt(string, radix)
$export($export.G + $export.F * (parseInt != $parseInt), {parseInt: $parseInt});

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

"use strict";
'use strict';
var LIBRARY            = __webpack_require__(50)
  , global             = __webpack_require__(4)
  , ctx                = __webpack_require__(35)
  , classof            = __webpack_require__(67)
  , $export            = __webpack_require__(0)
  , isObject           = __webpack_require__(6)
  , aFunction          = __webpack_require__(16)
  , anInstance         = __webpack_require__(49)
  , forOf              = __webpack_require__(61)
  , speciesConstructor = __webpack_require__(105)
  , task               = __webpack_require__(110).set
  , microtask          = __webpack_require__(102)()
  , PROMISE            = 'Promise'
  , TypeError          = global.TypeError
  , process            = global.process
  , $Promise           = global[PROMISE]
  , process            = global.process
  , isNode             = classof(process) == 'process'
  , empty              = function(){ /* empty */ }
  , Internal, GenericPromiseCapability, Wrapper;

var USE_NATIVE = !!function(){
  try {
    // correct subclassing with @@species support
    var promise     = $Promise.resolve(1)
      , FakePromise = (promise.constructor = {})[__webpack_require__(7)('species')] = function(exec){ exec(empty, empty); };
    // unhandled rejections tracking support, NodeJS Promise without it fails @@species test
    return (isNode || typeof PromiseRejectionEvent == 'function') && promise.then(empty) instanceof FakePromise;
  } catch(e){ /* empty */ }
}();

// helpers
var sameConstructor = function(a, b){
  // with library wrapper special case
  return a === b || a === $Promise && b === Wrapper;
};
var isThenable = function(it){
  var then;
  return isObject(it) && typeof (then = it.then) == 'function' ? then : false;
};
var newPromiseCapability = function(C){
  return sameConstructor($Promise, C)
    ? new PromiseCapability(C)
    : new GenericPromiseCapability(C);
};
var PromiseCapability = GenericPromiseCapability = function(C){
  var resolve, reject;
  this.promise = new C(function($$resolve, $$reject){
    if(resolve !== undefined || reject !== undefined)throw TypeError('Bad Promise constructor');
    resolve = $$resolve;
    reject  = $$reject;
  });
  this.resolve = aFunction(resolve);
  this.reject  = aFunction(reject);
};
var perform = function(exec){
  try {
    exec();
  } catch(e){
    return {error: e};
  }
};
var notify = function(promise, isReject){
  if(promise._n)return;
  promise._n = true;
  var chain = promise._c;
  microtask(function(){
    var value = promise._v
      , ok    = promise._s == 1
      , i     = 0;
    var run = function(reaction){
      var handler = ok ? reaction.ok : reaction.fail
        , resolve = reaction.resolve
        , reject  = reaction.reject
        , domain  = reaction.domain
        , result, then;
      try {
        if(handler){
          if(!ok){
            if(promise._h == 2)onHandleUnhandled(promise);
            promise._h = 1;
          }
          if(handler === true)result = value;
          else {
            if(domain)domain.enter();
            result = handler(value);
            if(domain)domain.exit();
          }
          if(result === reaction.promise){
            reject(TypeError('Promise-chain cycle'));
          } else if(then = isThenable(result)){
            then.call(result, resolve, reject);
          } else resolve(result);
        } else reject(value);
      } catch(e){
        reject(e);
      }
    };
    while(chain.length > i)run(chain[i++]); // variable length - can't use forEach
    promise._c = [];
    promise._n = false;
    if(isReject && !promise._h)onUnhandled(promise);
  });
};
var onUnhandled = function(promise){
  task.call(global, function(){
    var value = promise._v
      , abrupt, handler, console;
    if(isUnhandled(promise)){
      abrupt = perform(function(){
        if(isNode){
          process.emit('unhandledRejection', value, promise);
        } else if(handler = global.onunhandledrejection){
          handler({promise: promise, reason: value});
        } else if((console = global.console) && console.error){
          console.error('Unhandled promise rejection', value);
        }
      });
      // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should
      promise._h = isNode || isUnhandled(promise) ? 2 : 1;
    } promise._a = undefined;
    if(abrupt)throw abrupt.error;
  });
};
var isUnhandled = function(promise){
  if(promise._h == 1)return false;
  var chain = promise._a || promise._c
    , i     = 0
    , reaction;
  while(chain.length > i){
    reaction = chain[i++];
    if(reaction.fail || !isUnhandled(reaction.promise))return false;
  } return true;
};
var onHandleUnhandled = function(promise){
  task.call(global, function(){
    var handler;
    if(isNode){
      process.emit('rejectionHandled', promise);
    } else if(handler = global.onrejectionhandled){
      handler({promise: promise, reason: promise._v});
    }
  });
};
var $reject = function(value){
  var promise = this;
  if(promise._d)return;
  promise._d = true;
  promise = promise._w || promise; // unwrap
  promise._v = value;
  promise._s = 2;
  if(!promise._a)promise._a = promise._c.slice();
  notify(promise, true);
};
var $resolve = function(value){
  var promise = this
    , then;
  if(promise._d)return;
  promise._d = true;
  promise = promise._w || promise; // unwrap
  try {
    if(promise === value)throw TypeError("Promise can't be resolved itself");
    if(then = isThenable(value)){
      microtask(function(){
        var wrapper = {_w: promise, _d: false}; // wrap
        try {
          then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1));
        } catch(e){
          $reject.call(wrapper, e);
        }
      });
    } else {
      promise._v = value;
      promise._s = 1;
      notify(promise, false);
    }
  } catch(e){
    $reject.call({_w: promise, _d: false}, e); // wrap
  }
};

// constructor polyfill
if(!USE_NATIVE){
  // 25.4.3.1 Promise(executor)
  $Promise = function Promise(executor){
    anInstance(this, $Promise, PROMISE, '_h');
    aFunction(executor);
    Internal.call(this);
    try {
      executor(ctx($resolve, this, 1), ctx($reject, this, 1));
    } catch(err){
      $reject.call(this, err);
    }
  };
  Internal = function Promise(executor){
    this._c = [];             // <- awaiting reactions
    this._a = undefined;      // <- checked in isUnhandled reactions
    this._s = 0;              // <- state
    this._d = false;          // <- done
    this._v = undefined;      // <- value
    this._h = 0;              // <- rejection state, 0 - default, 1 - handled, 2 - unhandled
    this._n = false;          // <- notify
  };
  Internal.prototype = __webpack_require__(54)($Promise.prototype, {
    // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected)
    then: function then(onFulfilled, onRejected){
      var reaction    = newPromiseCapability(speciesConstructor(this, $Promise));
      reaction.ok     = typeof onFulfilled == 'function' ? onFulfilled : true;
      reaction.fail   = typeof onRejected == 'function' && onRejected;
      reaction.domain = isNode ? process.domain : undefined;
      this._c.push(reaction);
      if(this._a)this._a.push(reaction);
      if(this._s)notify(this, false);
      return reaction.promise;
    },
    // 25.4.5.1 Promise.prototype.catch(onRejected)
    'catch': function(onRejected){
      return this.then(undefined, onRejected);
    }
  });
  PromiseCapability = function(){
    var promise  = new Internal;
    this.promise = promise;
    this.resolve = ctx($resolve, promise, 1);
    this.reject  = ctx($reject, promise, 1);
  };
}

$export($export.G + $export.W + $export.F * !USE_NATIVE, {Promise: $Promise});
__webpack_require__(63)($Promise, PROMISE);
__webpack_require__(55)(PROMISE);
Wrapper = __webpack_require__(34)[PROMISE];

// statics
$export($export.S + $export.F * !USE_NATIVE, PROMISE, {
  // 25.4.4.5 Promise.reject(r)
  reject: function reject(r){
    var capability = newPromiseCapability(this)
      , $$reject   = capability.reject;
    $$reject(r);
    return capability.promise;
  }
});
$export($export.S + $export.F * (LIBRARY || !USE_NATIVE), PROMISE, {
  // 25.4.4.6 Promise.resolve(x)
  resolve: function resolve(x){
    // instanceof instead of internal slot check because we should fix it without replacement native Promise core
    if(x instanceof $Promise && sameConstructor(x.constructor, this))return x;
    var capability = newPromiseCapability(this)
      , $$resolve  = capability.resolve;
    $$resolve(x);
    return capability.promise;
  }
});
$export($export.S + $export.F * !(USE_NATIVE && __webpack_require__(78)(function(iter){
  $Promise.all(iter)['catch'](empty);
})), PROMISE, {
  // 25.4.4.1 Promise.all(iterable)
  all: function all(iterable){
    var C          = this
      , capability = newPromiseCapability(C)
      , resolve    = capability.resolve
      , reject     = capability.reject;
    var abrupt = perform(function(){
      var values    = []
        , index     = 0
        , remaining = 1;
      forOf(iterable, false, function(promise){
        var $index        = index++
          , alreadyCalled = false;
        values.push(undefined);
        remaining++;
        C.resolve(promise).then(function(value){
          if(alreadyCalled)return;
          alreadyCalled  = true;
          values[$index] = value;
          --remaining || resolve(values);
        }, reject);
      });
      --remaining || resolve(values);
    });
    if(abrupt)reject(abrupt.error);
    return capability.promise;
  },
  // 25.4.4.4 Promise.race(iterable)
  race: function race(iterable){
    var C          = this
      , capability = newPromiseCapability(C)
      , reject     = capability.reject;
    var abrupt = perform(function(){
      forOf(iterable, false, function(promise){
        C.resolve(promise).then(capability.resolve, reject);
      });
    });
    if(abrupt)reject(abrupt.error);
    return capability.promise;
  }
});

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

// 26.1.1 Reflect.apply(target, thisArgument, argumentsList)
var $export   = __webpack_require__(0)
  , aFunction = __webpack_require__(16)
  , anObject  = __webpack_require__(3)
  , rApply    = (__webpack_require__(4).Reflect || {}).apply
  , fApply    = Function.apply;
// MS Edge argumentsList argument is optional
$export($export.S + $export.F * !__webpack_require__(5)(function(){
  rApply(function(){});
}), 'Reflect', {
  apply: function apply(target, thisArgument, argumentsList){
    var T = aFunction(target)
      , L = anObject(argumentsList);
    return rApply ? rApply(T, thisArgument, L) : fApply.call(T, thisArgument, L);
  }
});

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

// 26.1.2 Reflect.construct(target, argumentsList [, newTarget])
var $export    = __webpack_require__(0)
  , create     = __webpack_require__(51)
  , aFunction  = __webpack_require__(16)
  , anObject   = __webpack_require__(3)
  , isObject   = __webpack_require__(6)
  , fails      = __webpack_require__(5)
  , bind       = __webpack_require__(155)
  , rConstruct = (__webpack_require__(4).Reflect || {}).construct;

// MS Edge supports only 2 arguments and argumentsList argument is optional
// FF Nightly sets third argument as `new.target`, but does not create `this` from it
var NEW_TARGET_BUG = fails(function(){
  function F(){}
  return !(rConstruct(function(){}, [], F) instanceof F);
});
var ARGS_BUG = !fails(function(){
  rConstruct(function(){});
});

$export($export.S + $export.F * (NEW_TARGET_BUG || ARGS_BUG), 'Reflect', {
  construct: function construct(Target, args /*, newTarget*/){
    aFunction(Target);
    anObject(args);
    var newTarget = arguments.length < 3 ? Target : aFunction(arguments[2]);
    if(ARGS_BUG && !NEW_TARGET_BUG)return rConstruct(Target, args, newTarget);
    if(Target == newTarget){
      // w/o altered newTarget, optimization for 0-4 arguments
      switch(args.length){
        case 0: return new Target;
        case 1: return new Target(args[0]);
        case 2: return new Target(args[0], args[1]);
        case 3: return new Target(args[0], args[1], args[2]);
        case 4: return new Target(args[0], args[1], args[2], args[3]);
      }
      // w/o altered newTarget, lot of arguments case
      var $args = [null];
      $args.push.apply($args, args);
      return new (bind.apply(Target, $args));
    }
    // with altered newTarget, not support built-in constructors
    var proto    = newTarget.prototype
      , instance = create(isObject(proto) ? proto : Object.prototype)
      , result   = Function.apply.call(Target, instance, args);
    return isObject(result) ? result : instance;
  }
});

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

// 26.1.3 Reflect.defineProperty(target, propertyKey, attributes)
var dP          = __webpack_require__(9)
  , $export     = __webpack_require__(0)
  , anObject    = __webpack_require__(3)
  , toPrimitive = __webpack_require__(33);

// MS Edge has broken Reflect.defineProperty - throwing instead of returning false
$export($export.S + $export.F * __webpack_require__(5)(function(){
  Reflect.defineProperty(dP.f({}, 1, {value: 1}), 1, {value: 2});
}), 'Reflect', {
  defineProperty: function defineProperty(target, propertyKey, attributes){
    anObject(target);
    propertyKey = toPrimitive(propertyKey, true);
    anObject(attributes);
    try {
      dP.f(target, propertyKey, attributes);
      return true;
    } catch(e){
      return false;
    }
  }
});

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

// 26.1.4 Reflect.deleteProperty(target, propertyKey)
var $export  = __webpack_require__(0)
  , gOPD     = __webpack_require__(25).f
  , anObject = __webpack_require__(3);

$export($export.S, 'Reflect', {
  deleteProperty: function deleteProperty(target, propertyKey){
    var desc = gOPD(anObject(target), propertyKey);
    return desc && !desc.configurable ? false : delete target[propertyKey];
  }
});

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

"use strict";
'use strict';
// 26.1.5 Reflect.enumerate(target)
var $export  = __webpack_require__(0)
  , anObject = __webpack_require__(3);
var Enumerate = function(iterated){
  this._t = anObject(iterated); // target
  this._i = 0;                  // next index
  var keys = this._k = []       // keys
    , key;
  for(key in iterated)keys.push(key);
};
__webpack_require__(98)(Enumerate, 'Object', function(){
  var that = this
    , keys = that._k
    , key;
  do {
    if(that._i >= keys.length)return {value: undefined, done: true};
  } while(!((key = keys[that._i++]) in that._t));
  return {value: key, done: false};
});

$export($export.S, 'Reflect', {
  enumerate: function enumerate(target){
    return new Enumerate(target);
  }
});

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

// 26.1.7 Reflect.getOwnPropertyDescriptor(target, propertyKey)
var gOPD     = __webpack_require__(25)
  , $export  = __webpack_require__(0)
  , anObject = __webpack_require__(3);

$export($export.S, 'Reflect', {
  getOwnPropertyDescriptor: function getOwnPropertyDescriptor(target, propertyKey){
    return gOPD.f(anObject(target), propertyKey);
  }
});

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

// 26.1.8 Reflect.getPrototypeOf(target)
var $export  = __webpack_require__(0)
  , getProto = __webpack_require__(26)
  , anObject = __webpack_require__(3);

$export($export.S, 'Reflect', {
  getPrototypeOf: function getPrototypeOf(target){
    return getProto(anObject(target));
  }
});

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

// 26.1.6 Reflect.get(target, propertyKey [, receiver])
var gOPD           = __webpack_require__(25)
  , getPrototypeOf = __webpack_require__(26)
  , has            = __webpack_require__(15)
  , $export        = __webpack_require__(0)
  , isObject       = __webpack_require__(6)
  , anObject       = __webpack_require__(3);

function get(target, propertyKey/*, receiver*/){
  var receiver = arguments.length < 3 ? target : arguments[2]
    , desc, proto;
  if(anObject(target) === receiver)return target[propertyKey];
  if(desc = gOPD.f(target, propertyKey))return has(desc, 'value')
    ? desc.value
    : desc.get !== undefined
      ? desc.get.call(receiver)
      : undefined;
  if(isObject(proto = getPrototypeOf(target)))return get(proto, propertyKey, receiver);
}

$export($export.S, 'Reflect', {get: get});

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

// 26.1.9 Reflect.has(target, propertyKey)
var $export = __webpack_require__(0);

$export($export.S, 'Reflect', {
  has: function has(target, propertyKey){
    return propertyKey in target;
  }
});

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

// 26.1.10 Reflect.isExtensible(target)
var $export       = __webpack_require__(0)
  , anObject      = __webpack_require__(3)
  , $isExtensible = Object.isExtensible;

$export($export.S, 'Reflect', {
  isExtensible: function isExtensible(target){
    anObject(target);
    return $isExtensible ? $isExtensible(target) : true;
  }
});

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

// 26.1.11 Reflect.ownKeys(target)
var $export = __webpack_require__(0);

$export($export.S, 'Reflect', {ownKeys: __webpack_require__(169)});

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

// 26.1.12 Reflect.preventExtensions(target)
var $export            = __webpack_require__(0)
  , anObject           = __webpack_require__(3)
  , $preventExtensions = Object.preventExtensions;

$export($export.S, 'Reflect', {
  preventExtensions: function preventExtensions(target){
    anObject(target);
    try {
      if($preventExtensions)$preventExtensions(target);
      return true;
    } catch(e){
      return false;
    }
  }
});

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

// 26.1.14 Reflect.setPrototypeOf(target, proto)
var $export  = __webpack_require__(0)
  , setProto = __webpack_require__(103);

if(setProto)$export($export.S, 'Reflect', {
  setPrototypeOf: function setPrototypeOf(target, proto){
    setProto.check(target, proto);
    try {
      setProto.set(target, proto);
      return true;
    } catch(e){
      return false;
    }
  }
});

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

// 26.1.13 Reflect.set(target, propertyKey, V [, receiver])
var dP             = __webpack_require__(9)
  , gOPD           = __webpack_require__(25)
  , getPrototypeOf = __webpack_require__(26)
  , has            = __webpack_require__(15)
  , $export        = __webpack_require__(0)
  , createDesc     = __webpack_require__(42)
  , anObject       = __webpack_require__(3)
  , isObject       = __webpack_require__(6);

function set(target, propertyKey, V/*, receiver*/){
  var receiver = arguments.length < 4 ? target : arguments[3]
    , ownDesc  = gOPD.f(anObject(target), propertyKey)
    , existingDescriptor, proto;
  if(!ownDesc){
    if(isObject(proto = getPrototypeOf(target))){
      return set(proto, propertyKey, V, receiver);
    }
    ownDesc = createDesc(0);
  }
  if(has(ownDesc, 'value')){
    if(ownDesc.writable === false || !isObject(receiver))return false;
    existingDescriptor = gOPD.f(receiver, propertyKey) || createDesc(0);
    existingDescriptor.value = V;
    dP.f(receiver, propertyKey, existingDescriptor);
    return true;
  }
  return ownDesc.set === undefined ? false : (ownDesc.set.call(receiver, V), true);
}

$export($export.S, 'Reflect', {set: set});

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

var global            = __webpack_require__(4)
  , inheritIfRequired = __webpack_require__(95)
  , dP                = __webpack_require__(9).f
  , gOPN              = __webpack_require__(52).f
  , isRegExp          = __webpack_require__(77)
  , $flags            = __webpack_require__(75)
  , $RegExp           = global.RegExp
  , Base              = $RegExp
  , proto             = $RegExp.prototype
  , re1               = /a/g
  , re2               = /a/g
  // "new" creates a new object, old webkit buggy here
  , CORRECT_NEW       = new $RegExp(re1) !== re1;

if(__webpack_require__(8) && (!CORRECT_NEW || __webpack_require__(5)(function(){
  re2[__webpack_require__(7)('match')] = false;
  // RegExp constructor can alter flags and IsRegExp works correct with @@match
  return $RegExp(re1) != re1 || $RegExp(re2) == re2 || $RegExp(re1, 'i') != '/a/i';
}))){
  $RegExp = function RegExp(p, f){
    var tiRE = this instanceof $RegExp
      , piRE = isRegExp(p)
      , fiU  = f === undefined;
    return !tiRE && piRE && p.constructor === $RegExp && fiU ? p
      : inheritIfRequired(CORRECT_NEW
        ? new Base(piRE && !fiU ? p.source : p, f)
        : Base((piRE = p instanceof $RegExp) ? p.source : p, piRE && fiU ? $flags.call(p) : f)
      , tiRE ? this : proto, $RegExp);
  };
  var proxy = function(key){
    key in $RegExp || dP($RegExp, key, {
      configurable: true,
      get: function(){ return Base[key]; },
      set: function(it){ Base[key] = it; }
    });
  };
  for(var keys = gOPN(Base), i = 0; keys.length > i; )proxy(keys[i++]);
  proto.constructor = $RegExp;
  $RegExp.prototype = proto;
  __webpack_require__(18)(global, 'RegExp', $RegExp);
}

__webpack_require__(55)('RegExp');

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

// @@match logic
__webpack_require__(74)('match', 1, function(defined, MATCH, $match){
  // 21.1.3.11 String.prototype.match(regexp)
  return [function match(regexp){
    'use strict';
    var O  = defined(this)
      , fn = regexp == undefined ? undefined : regexp[MATCH];
    return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[MATCH](String(O));
  }, $match];
});

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

// @@replace logic
__webpack_require__(74)('replace', 2, function(defined, REPLACE, $replace){
  // 21.1.3.14 String.prototype.replace(searchValue, replaceValue)
  return [function replace(searchValue, replaceValue){
    'use strict';
    var O  = defined(this)
      , fn = searchValue == undefined ? undefined : searchValue[REPLACE];
    return fn !== undefined
      ? fn.call(searchValue, O, replaceValue)
      : $replace.call(String(O), searchValue, replaceValue);
  }, $replace];
});

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

// @@search logic
__webpack_require__(74)('search', 1, function(defined, SEARCH, $search){
  // 21.1.3.15 String.prototype.search(regexp)
  return [function search(regexp){
    'use strict';
    var O  = defined(this)
      , fn = regexp == undefined ? undefined : regexp[SEARCH];
    return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[SEARCH](String(O));
  }, $search];
});

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

// @@split logic
__webpack_require__(74)('split', 2, function(defined, SPLIT, $split){
  'use strict';
  var isRegExp   = __webpack_require__(77)
    , _split     = $split
    , $push      = [].push
    , $SPLIT     = 'split'
    , LENGTH     = 'length'
    , LAST_INDEX = 'lastIndex';
  if(
    'abbc'[$SPLIT](/(b)*/)[1] == 'c' ||
    'test'[$SPLIT](/(?:)/, -1)[LENGTH] != 4 ||
    'ab'[$SPLIT](/(?:ab)*/)[LENGTH] != 2 ||
    '.'[$SPLIT](/(.?)(.?)/)[LENGTH] != 4 ||
    '.'[$SPLIT](/()()/)[LENGTH] > 1 ||
    ''[$SPLIT](/.?/)[LENGTH]
  ){
    var NPCG = /()??/.exec('')[1] === undefined; // nonparticipating capturing group
    // based on es5-shim implementation, need to rework it
    $split = function(separator, limit){
      var string = String(this);
      if(separator === undefined && limit === 0)return [];
      // If `separator` is not a regex, use native split
      if(!isRegExp(separator))return _split.call(string, separator, limit);
      var output = [];
      var flags = (separator.ignoreCase ? 'i' : '') +
                  (separator.multiline ? 'm' : '') +
                  (separator.unicode ? 'u' : '') +
                  (separator.sticky ? 'y' : '');
      var lastLastIndex = 0;
      var splitLimit = limit === undefined ? 4294967295 : limit >>> 0;
      // Make `global` and avoid `lastIndex` issues by working with a copy
      var separatorCopy = new RegExp(separator.source, flags + 'g');
      var separator2, match, lastIndex, lastLength, i;
      // Doesn't need flags gy, but they don't hurt
      if(!NPCG)separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags);
      while(match = separatorCopy.exec(string)){
        // `separatorCopy.lastIndex` is not reliable cross-browser
        lastIndex = match.index + match[0][LENGTH];
        if(lastIndex > lastLastIndex){
          output.push(string.slice(lastLastIndex, match.index));
          // Fix browsers whose `exec` methods don't consistently return `undefined` for NPCG
          if(!NPCG && match[LENGTH] > 1)match[0].replace(separator2, function(){
            for(i = 1; i < arguments[LENGTH] - 2; i++)if(arguments[i] === undefined)match[i] = undefined;
          });
          if(match[LENGTH] > 1 && match.index < string[LENGTH])$push.apply(output, match.slice(1));
          lastLength = match[0][LENGTH];
          lastLastIndex = lastIndex;
          if(output[LENGTH] >= splitLimit)break;
        }
        if(separatorCopy[LAST_INDEX] === match.index)separatorCopy[LAST_INDEX]++; // Avoid an infinite loop
      }
      if(lastLastIndex === string[LENGTH]){
        if(lastLength || !separatorCopy.test(''))output.push('');
      } else output.push(string.slice(lastLastIndex));
      return output[LENGTH] > splitLimit ? output.slice(0, splitLimit) : output;
    };
  // Chakra, V8
  } else if('0'[$SPLIT](undefined, 0)[LENGTH]){
    $split = function(separator, limit){
      return separator === undefined && limit === 0 ? [] : _split.call(this, separator, limit);
    };
  }
  // 21.1.3.17 String.prototype.split(separator, limit)
  return [function split(separator, limit){
    var O  = defined(this)
      , fn = separator == undefined ? undefined : separator[SPLIT];
    return fn !== undefined ? fn.call(separator, O, limit) : $split.call(String(O), separator, limit);
  }, $split];
});

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

"use strict";
'use strict';
__webpack_require__(176);
var anObject    = __webpack_require__(3)
  , $flags      = __webpack_require__(75)
  , DESCRIPTORS = __webpack_require__(8)
  , TO_STRING   = 'toString'
  , $toString   = /./[TO_STRING];

var define = function(fn){
  __webpack_require__(18)(RegExp.prototype, TO_STRING, fn, true);
};

// 21.2.5.14 RegExp.prototype.toString()
if(__webpack_require__(5)(function(){ return $toString.call({source: 'a', flags: 'b'}) != '/a/b'; })){
  define(function toString(){
    var R = anObject(this);
    return '/'.concat(R.source, '/',
      'flags' in R ? R.flags : !DESCRIPTORS && R instanceof RegExp ? $flags.call(R) : undefined);
  });
// FF44- RegExp#toString has a wrong name
} else if($toString.name != TO_STRING){
  define(function toString(){
    return $toString.call(this);
  });
}

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

"use strict";
'use strict';
// B.2.3.2 String.prototype.anchor(name)
__webpack_require__(19)('anchor', function(createHTML){
  return function anchor(name){
    return createHTML(this, 'a', 'name', name);
  }
});

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

"use strict";
'use strict';
// B.2.3.3 String.prototype.big()
__webpack_require__(19)('big', function(createHTML){
  return function big(){
    return createHTML(this, 'big', '', '');
  }
});

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

"use strict";
'use strict';
// B.2.3.4 String.prototype.blink()
__webpack_require__(19)('blink', function(createHTML){
  return function blink(){
    return createHTML(this, 'blink', '', '');
  }
});

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

"use strict";
'use strict';
// B.2.3.5 String.prototype.bold()
__webpack_require__(19)('bold', function(createHTML){
  return function bold(){
    return createHTML(this, 'b', '', '');
  }
});

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

"use strict";
'use strict';
var $export = __webpack_require__(0)
  , $at     = __webpack_require__(106)(false);
$export($export.P, 'String', {
  // 21.1.3.3 String.prototype.codePointAt(pos)
  codePointAt: function codePointAt(pos){
    return $at(this, pos);
  }
});

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

"use strict";
// 21.1.3.6 String.prototype.endsWith(searchString [, endPosition])
'use strict';
var $export   = __webpack_require__(0)
  , toLength  = __webpack_require__(12)
  , context   = __webpack_require__(107)
  , ENDS_WITH = 'endsWith'
  , $endsWith = ''[ENDS_WITH];

$export($export.P + $export.F * __webpack_require__(93)(ENDS_WITH), 'String', {
  endsWith: function endsWith(searchString /*, endPosition = @length */){
    var that = context(this, searchString, ENDS_WITH)
      , endPosition = arguments.length > 1 ? arguments[1] : undefined
      , len    = toLength(that.length)
      , end    = endPosition === undefined ? len : Math.min(toLength(endPosition), len)
      , search = String(searchString);
    return $endsWith
      ? $endsWith.call(that, search, end)
      : that.slice(end - search.length, end) === search;
  }
});

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

"use strict";
'use strict';
// B.2.3.6 String.prototype.fixed()
__webpack_require__(19)('fixed', function(createHTML){
  return function fixed(){
    return createHTML(this, 'tt', '', '');
  }
});

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

"use strict";
'use strict';
// B.2.3.7 String.prototype.fontcolor(color)
__webpack_require__(19)('fontcolor', function(createHTML){
  return function fontcolor(color){
    return createHTML(this, 'font', 'color', color);
  }
});

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

"use strict";
'use strict';
// B.2.3.8 String.prototype.fontsize(size)
__webpack_require__(19)('fontsize', function(createHTML){
  return function fontsize(size){
    return createHTML(this, 'font', 'size', size);
  }
});

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

var $export        = __webpack_require__(0)
  , toIndex        = __webpack_require__(56)
  , fromCharCode   = String.fromCharCode
  , $fromCodePoint = String.fromCodePoint;

// length should be 1, old FF problem
$export($export.S + $export.F * (!!$fromCodePoint && $fromCodePoint.length != 1), 'String', {
  // 21.1.2.2 String.fromCodePoint(...codePoints)
  fromCodePoint: function fromCodePoint(x){ // eslint-disable-line no-unused-vars
    var res  = []
      , aLen = arguments.length
      , i    = 0
      , code;
    while(aLen > i){
      code = +arguments[i++];
      if(toIndex(code, 0x10ffff) !== code)throw RangeError(code + ' is not a valid code point');
      res.push(code < 0x10000
        ? fromCharCode(code)
        : fromCharCode(((code -= 0x10000) >> 10) + 0xd800, code % 0x400 + 0xdc00)
      );
    } return res.join('');
  }
});

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

"use strict";
// 21.1.3.7 String.prototype.includes(searchString, position = 0)
'use strict';
var $export  = __webpack_require__(0)
  , context  = __webpack_require__(107)
  , INCLUDES = 'includes';

$export($export.P + $export.F * __webpack_require__(93)(INCLUDES), 'String', {
  includes: function includes(searchString /*, position = 0 */){
    return !!~context(this, searchString, INCLUDES)
      .indexOf(searchString, arguments.length > 1 ? arguments[1] : undefined);
  }
});

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

"use strict";
'use strict';
// B.2.3.9 String.prototype.italics()
__webpack_require__(19)('italics', function(createHTML){
  return function italics(){
    return createHTML(this, 'i', '', '');
  }
});

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

"use strict";
'use strict';
var $at  = __webpack_require__(106)(true);

// 21.1.3.27 String.prototype[@@iterator]()
__webpack_require__(99)(String, 'String', function(iterated){
  this._t = String(iterated); // target
  this._i = 0;                // next index
// 21.1.5.2.1 %StringIteratorPrototype%.next()
}, function(){
  var O     = this._t
    , index = this._i
    , point;
  if(index >= O.length)return {value: undefined, done: true};
  point = $at(O, index);
  this._i += point.length;
  return {value: point, done: false};
});

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

"use strict";
'use strict';
// B.2.3.10 String.prototype.link(url)
__webpack_require__(19)('link', function(createHTML){
  return function link(url){
    return createHTML(this, 'a', 'href', url);
  }
});

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

var $export   = __webpack_require__(0)
  , toIObject = __webpack_require__(20)
  , toLength  = __webpack_require__(12);

$export($export.S, 'String', {
  // 21.1.2.4 String.raw(callSite, ...substitutions)
  raw: function raw(callSite){
    var tpl  = toIObject(callSite.raw)
      , len  = toLength(tpl.length)
      , aLen = arguments.length
      , res  = []
      , i    = 0;
    while(len > i){
      res.push(String(tpl[i++]));
      if(i < aLen)res.push(String(arguments[i]));
    } return res.join('');
  }
});

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

var $export = __webpack_require__(0);

$export($export.P, 'String', {
  // 21.1.3.13 String.prototype.repeat(count)
  repeat: __webpack_require__(108)
});

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

"use strict";
'use strict';
// B.2.3.11 String.prototype.small()
__webpack_require__(19)('small', function(createHTML){
  return function small(){
    return createHTML(this, 'small', '', '');
  }
});

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

"use strict";
// 21.1.3.18 String.prototype.startsWith(searchString [, position ])
'use strict';
var $export     = __webpack_require__(0)
  , toLength    = __webpack_require__(12)
  , context     = __webpack_require__(107)
  , STARTS_WITH = 'startsWith'
  , $startsWith = ''[STARTS_WITH];

$export($export.P + $export.F * __webpack_require__(93)(STARTS_WITH), 'String', {
  startsWith: function startsWith(searchString /*, position = 0 */){
    var that   = context(this, searchString, STARTS_WITH)
      , index  = toLength(Math.min(arguments.length > 1 ? arguments[1] : undefined, that.length))
      , search = String(searchString);
    return $startsWith
      ? $startsWith.call(that, search, index)
      : that.slice(index, index + search.length) === search;
  }
});

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

"use strict";
'use strict';
// B.2.3.12 String.prototype.strike()
__webpack_require__(19)('strike', function(createHTML){
  return function strike(){
    return createHTML(this, 'strike', '', '');
  }
});

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

"use strict";
'use strict';
// B.2.3.13 String.prototype.sub()
__webpack_require__(19)('sub', function(createHTML){
  return function sub(){
    return createHTML(this, 'sub', '', '');
  }
});

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

"use strict";
'use strict';
// B.2.3.14 String.prototype.sup()
__webpack_require__(19)('sup', function(createHTML){
  return function sup(){
    return createHTML(this, 'sup', '', '');
  }
});

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

"use strict";
'use strict';
// 21.1.3.25 String.prototype.trim()
__webpack_require__(64)('trim', function($trim){
  return function trim(){
    return $trim(this, 3);
  };
});

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

"use strict";
'use strict';
// ECMAScript 6 symbols shim
var global         = __webpack_require__(4)
  , has            = __webpack_require__(15)
  , DESCRIPTORS    = __webpack_require__(8)
  , $export        = __webpack_require__(0)
  , redefine       = __webpack_require__(18)
  , META           = __webpack_require__(41).KEY
  , $fails         = __webpack_require__(5)
  , shared         = __webpack_require__(81)
  , setToStringTag = __webpack_require__(63)
  , uid            = __webpack_require__(57)
  , wks            = __webpack_require__(7)
  , wksExt         = __webpack_require__(174)
  , wksDefine      = __webpack_require__(112)
  , keyOf          = __webpack_require__(233)
  , enumKeys       = __webpack_require__(232)
  , isArray        = __webpack_require__(97)
  , anObject       = __webpack_require__(3)
  , toIObject      = __webpack_require__(20)
  , toPrimitive    = __webpack_require__(33)
  , createDesc     = __webpack_require__(42)
  , _create        = __webpack_require__(51)
  , gOPNExt        = __webpack_require__(166)
  , $GOPD          = __webpack_require__(25)
  , $DP            = __webpack_require__(9)
  , $keys          = __webpack_require__(53)
  , gOPD           = $GOPD.f
  , dP             = $DP.f
  , gOPN           = gOPNExt.f
  , $Symbol        = global.Symbol
  , $JSON          = global.JSON
  , _stringify     = $JSON && $JSON.stringify
  , PROTOTYPE      = 'prototype'
  , HIDDEN         = wks('_hidden')
  , TO_PRIMITIVE   = wks('toPrimitive')
  , isEnum         = {}.propertyIsEnumerable
  , SymbolRegistry = shared('symbol-registry')
  , AllSymbols     = shared('symbols')
  , OPSymbols      = shared('op-symbols')
  , ObjectProto    = Object[PROTOTYPE]
  , USE_NATIVE     = typeof $Symbol == 'function'
  , QObject        = global.QObject;
// Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173
var setter = !QObject || !QObject[PROTOTYPE] || !QObject[PROTOTYPE].findChild;

// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687
var setSymbolDesc = DESCRIPTORS && $fails(function(){
  return _create(dP({}, 'a', {
    get: function(){ return dP(this, 'a', {value: 7}).a; }
  })).a != 7;
}) ? function(it, key, D){
  var protoDesc = gOPD(ObjectProto, key);
  if(protoDesc)delete ObjectProto[key];
  dP(it, key, D);
  if(protoDesc && it !== ObjectProto)dP(ObjectProto, key, protoDesc);
} : dP;

var wrap = function(tag){
  var sym = AllSymbols[tag] = _create($Symbol[PROTOTYPE]);
  sym._k = tag;
  return sym;
};

var isSymbol = USE_NATIVE && typeof $Symbol.iterator == 'symbol' ? function(it){
  return typeof it == 'symbol';
} : function(it){
  return it instanceof $Symbol;
};

var $defineProperty = function defineProperty(it, key, D){
  if(it === ObjectProto)$defineProperty(OPSymbols, key, D);
  anObject(it);
  key = toPrimitive(key, true);
  anObject(D);
  if(has(AllSymbols, key)){
    if(!D.enumerable){
      if(!has(it, HIDDEN))dP(it, HIDDEN, createDesc(1, {}));
      it[HIDDEN][key] = true;
    } else {
      if(has(it, HIDDEN) && it[HIDDEN][key])it[HIDDEN][key] = false;
      D = _create(D, {enumerable: createDesc(0, false)});
    } return setSymbolDesc(it, key, D);
  } return dP(it, key, D);
};
var $defineProperties = function defineProperties(it, P){
  anObject(it);
  var keys = enumKeys(P = toIObject(P))
    , i    = 0
    , l = keys.length
    , key;
  while(l > i)$defineProperty(it, key = keys[i++], P[key]);
  return it;
};
var $create = function create(it, P){
  return P === undefined ? _create(it) : $defineProperties(_create(it), P);
};
var $propertyIsEnumerable = function propertyIsEnumerable(key){
  var E = isEnum.call(this, key = toPrimitive(key, true));
  if(this === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key))return false;
  return E || !has(this, key) || !has(AllSymbols, key) || has(this, HIDDEN) && this[HIDDEN][key] ? E : true;
};
var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(it, key){
  it  = toIObject(it);
  key = toPrimitive(key, true);
  if(it === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key))return;
  var D = gOPD(it, key);
  if(D && has(AllSymbols, key) && !(has(it, HIDDEN) && it[HIDDEN][key]))D.enumerable = true;
  return D;
};
var $getOwnPropertyNames = function getOwnPropertyNames(it){
  var names  = gOPN(toIObject(it))
    , result = []
    , i      = 0
    , key;
  while(names.length > i){
    if(!has(AllSymbols, key = names[i++]) && key != HIDDEN && key != META)result.push(key);
  } return result;
};
var $getOwnPropertySymbols = function getOwnPropertySymbols(it){
  var IS_OP  = it === ObjectProto
    , names  = gOPN(IS_OP ? OPSymbols : toIObject(it))
    , result = []
    , i      = 0
    , key;
  while(names.length > i){
    if(has(AllSymbols, key = names[i++]) && (IS_OP ? has(ObjectProto, key) : true))result.push(AllSymbols[key]);
  } return result;
};

// 19.4.1.1 Symbol([description])
if(!USE_NATIVE){
  $Symbol = function Symbol(){
    if(this instanceof $Symbol)throw TypeError('Symbol is not a constructor!');
    var tag = uid(arguments.length > 0 ? arguments[0] : undefined);
    var $set = function(value){
      if(this === ObjectProto)$set.call(OPSymbols, value);
      if(has(this, HIDDEN) && has(this[HIDDEN], tag))this[HIDDEN][tag] = false;
      setSymbolDesc(this, tag, createDesc(1, value));
    };
    if(DESCRIPTORS && setter)setSymbolDesc(ObjectProto, tag, {configurable: true, set: $set});
    return wrap(tag);
  };
  redefine($Symbol[PROTOTYPE], 'toString', function toString(){
    return this._k;
  });

  $GOPD.f = $getOwnPropertyDescriptor;
  $DP.f   = $defineProperty;
  __webpack_require__(52).f = gOPNExt.f = $getOwnPropertyNames;
  __webpack_require__(69).f  = $propertyIsEnumerable;
  __webpack_require__(80).f = $getOwnPropertySymbols;

  if(DESCRIPTORS && !__webpack_require__(50)){
    redefine(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable, true);
  }

  wksExt.f = function(name){
    return wrap(wks(name));
  }
}

$export($export.G + $export.W + $export.F * !USE_NATIVE, {Symbol: $Symbol});

for(var symbols = (
  // 19.4.2.2, 19.4.2.3, 19.4.2.4, 19.4.2.6, 19.4.2.8, 19.4.2.9, 19.4.2.10, 19.4.2.11, 19.4.2.12, 19.4.2.13, 19.4.2.14
  'hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables'
).split(','), i = 0; symbols.length > i; )wks(symbols[i++]);

for(var symbols = $keys(wks.store), i = 0; symbols.length > i; )wksDefine(symbols[i++]);

$export($export.S + $export.F * !USE_NATIVE, 'Symbol', {
  // 19.4.2.1 Symbol.for(key)
  'for': function(key){
    return has(SymbolRegistry, key += '')
      ? SymbolRegistry[key]
      : SymbolRegistry[key] = $Symbol(key);
  },
  // 19.4.2.5 Symbol.keyFor(sym)
  keyFor: function keyFor(key){
    if(isSymbol(key))return keyOf(SymbolRegistry, key);
    throw TypeError(key + ' is not a symbol!');
  },
  useSetter: function(){ setter = true; },
  useSimple: function(){ setter = false; }
});

$export($export.S + $export.F * !USE_NATIVE, 'Object', {
  // 19.1.2.2 Object.create(O [, Properties])
  create: $create,
  // 19.1.2.4 Object.defineProperty(O, P, Attributes)
  defineProperty: $defineProperty,
  // 19.1.2.3 Object.defineProperties(O, Properties)
  defineProperties: $defineProperties,
  // 19.1.2.6 Object.getOwnPropertyDescriptor(O, P)
  getOwnPropertyDescriptor: $getOwnPropertyDescriptor,
  // 19.1.2.7 Object.getOwnPropertyNames(O)
  getOwnPropertyNames: $getOwnPropertyNames,
  // 19.1.2.8 Object.getOwnPropertySymbols(O)
  getOwnPropertySymbols: $getOwnPropertySymbols
});

// 24.3.2 JSON.stringify(value [, replacer [, space]])
$JSON && $export($export.S + $export.F * (!USE_NATIVE || $fails(function(){
  var S = $Symbol();
  // MS Edge converts symbol values to JSON as {}
  // WebKit converts symbol values to JSON as null
  // V8 throws on boxed symbols
  return _stringify([S]) != '[null]' || _stringify({a: S}) != '{}' || _stringify(Object(S)) != '{}';
})), 'JSON', {
  stringify: function stringify(it){
    if(it === undefined || isSymbol(it))return; // IE8 returns string on undefined
    var args = [it]
      , i    = 1
      , replacer, $replacer;
    while(arguments.length > i)args.push(arguments[i++]);
    replacer = args[1];
    if(typeof replacer == 'function')$replacer = replacer;
    if($replacer || !isArray(replacer))replacer = function(key, value){
      if($replacer)value = $replacer.call(this, key, value);
      if(!isSymbol(value))return value;
    };
    args[1] = replacer;
    return _stringify.apply($JSON, args);
  }
});

// 19.4.3.4 Symbol.prototype[@@toPrimitive](hint)
$Symbol[PROTOTYPE][TO_PRIMITIVE] || __webpack_require__(17)($Symbol[PROTOTYPE], TO_PRIMITIVE, $Symbol[PROTOTYPE].valueOf);
// 19.4.3.5 Symbol.prototype[@@toStringTag]
setToStringTag($Symbol, 'Symbol');
// 20.2.1.9 Math[@@toStringTag]
setToStringTag(Math, 'Math', true);
// 24.3.3 JSON[@@toStringTag]
setToStringTag(global.JSON, 'JSON', true);

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

"use strict";
'use strict';
var $export      = __webpack_require__(0)
  , $typed       = __webpack_require__(82)
  , buffer       = __webpack_require__(111)
  , anObject     = __webpack_require__(3)
  , toIndex      = __webpack_require__(56)
  , toLength     = __webpack_require__(12)
  , isObject     = __webpack_require__(6)
  , ArrayBuffer  = __webpack_require__(4).ArrayBuffer
  , speciesConstructor = __webpack_require__(105)
  , $ArrayBuffer = buffer.ArrayBuffer
  , $DataView    = buffer.DataView
  , $isView      = $typed.ABV && ArrayBuffer.isView
  , $slice       = $ArrayBuffer.prototype.slice
  , VIEW         = $typed.VIEW
  , ARRAY_BUFFER = 'ArrayBuffer';

$export($export.G + $export.W + $export.F * (ArrayBuffer !== $ArrayBuffer), {ArrayBuffer: $ArrayBuffer});

$export($export.S + $export.F * !$typed.CONSTR, ARRAY_BUFFER, {
  // 24.1.3.1 ArrayBuffer.isView(arg)
  isView: function isView(it){
    return $isView && $isView(it) || isObject(it) && VIEW in it;
  }
});

$export($export.P + $export.U + $export.F * __webpack_require__(5)(function(){
  return !new $ArrayBuffer(2).slice(1, undefined).byteLength;
}), ARRAY_BUFFER, {
  // 24.1.4.3 ArrayBuffer.prototype.slice(start, end)
  slice: function slice(start, end){
    if($slice !== undefined && end === undefined)return $slice.call(anObject(this), start); // FF fix
    var len    = anObject(this).byteLength
      , first  = toIndex(start, len)
      , final  = toIndex(end === undefined ? len : end, len)
      , result = new (speciesConstructor(this, $ArrayBuffer))(toLength(final - first))
      , viewS  = new $DataView(this)
      , viewT  = new $DataView(result)
      , index  = 0;
    while(first < final){
      viewT.setUint8(index++, viewS.getUint8(first++));
    } return result;
  }
});

__webpack_require__(55)(ARRAY_BUFFER);

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

var $export = __webpack_require__(0);
$export($export.G + $export.W + $export.F * !__webpack_require__(82).ABV, {
  DataView: __webpack_require__(111).DataView
});

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

__webpack_require__(37)('Float32', 4, function(init){
  return function Float32Array(data, byteOffset, length){
    return init(this, data, byteOffset, length);
  };
});

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

__webpack_require__(37)('Float64', 8, function(init){
  return function Float64Array(data, byteOffset, length){
    return init(this, data, byteOffset, length);
  };
});

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

__webpack_require__(37)('Int16', 2, function(init){
  return function Int16Array(data, byteOffset, length){
    return init(this, data, byteOffset, length);
  };
});

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

__webpack_require__(37)('Int32', 4, function(init){
  return function Int32Array(data, byteOffset, length){
    return init(this, data, byteOffset, length);
  };
});

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

__webpack_require__(37)('Int8', 1, function(init){
  return function Int8Array(data, byteOffset, length){
    return init(this, data, byteOffset, length);
  };
});

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

__webpack_require__(37)('Uint16', 2, function(init){
  return function Uint16Array(data, byteOffset, length){
    return init(this, data, byteOffset, length);
  };
});

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

__webpack_require__(37)('Uint32', 4, function(init){
  return function Uint32Array(data, byteOffset, length){
    return init(this, data, byteOffset, length);
  };
});

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

__webpack_require__(37)('Uint8', 1, function(init){
  return function Uint8Array(data, byteOffset, length){
    return init(this, data, byteOffset, length);
  };
});

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

__webpack_require__(37)('Uint8', 1, function(init){
  return function Uint8ClampedArray(data, byteOffset, length){
    return init(this, data, byteOffset, length);
  };
}, true);

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

"use strict";
'use strict';
var weak = __webpack_require__(158);

// 23.4 WeakSet Objects
__webpack_require__(73)('WeakSet', function(get){
  return function WeakSet(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); };
}, {
  // 23.4.3.1 WeakSet.prototype.add(value)
  add: function add(value){
    return weak.def(this, value, true);
  }
}, weak, false, true);

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

"use strict";
'use strict';
// https://github.com/tc39/Array.prototype.includes
var $export   = __webpack_require__(0)
  , $includes = __webpack_require__(72)(true);

$export($export.P, 'Array', {
  includes: function includes(el /*, fromIndex = 0 */){
    return $includes(this, el, arguments.length > 1 ? arguments[1] : undefined);
  }
});

__webpack_require__(60)('includes');

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

// https://github.com/rwaldron/tc39-notes/blob/master/es6/2014-09/sept-25.md#510-globalasap-for-enqueuing-a-microtask
var $export   = __webpack_require__(0)
  , microtask = __webpack_require__(102)()
  , process   = __webpack_require__(4).process
  , isNode    = __webpack_require__(28)(process) == 'process';

$export($export.G, {
  asap: function asap(fn){
    var domain = isNode && process.domain;
    microtask(domain ? domain.bind(fn) : fn);
  }
});

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

// https://github.com/ljharb/proposal-is-error
var $export = __webpack_require__(0)
  , cof     = __webpack_require__(28);

$export($export.S, 'Error', {
  isError: function isError(it){
    return cof(it) === 'Error';
  }
});

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

// https://github.com/DavidBruant/Map-Set.prototype.toJSON
var $export  = __webpack_require__(0);

$export($export.P + $export.R, 'Map', {toJSON: __webpack_require__(157)('Map')});

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

// https://gist.github.com/BrendanEich/4294d5c212a6d2254703
var $export = __webpack_require__(0);

$export($export.S, 'Math', {
  iaddh: function iaddh(x0, x1, y0, y1){
    var $x0 = x0 >>> 0
      , $x1 = x1 >>> 0
      , $y0 = y0 >>> 0;
    return $x1 + (y1 >>> 0) + (($x0 & $y0 | ($x0 | $y0) & ~($x0 + $y0 >>> 0)) >>> 31) | 0;
  }
});

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

// https://gist.github.com/BrendanEich/4294d5c212a6d2254703
var $export = __webpack_require__(0);

$export($export.S, 'Math', {
  imulh: function imulh(u, v){
    var UINT16 = 0xffff
      , $u = +u
      , $v = +v
      , u0 = $u & UINT16
      , v0 = $v & UINT16
      , u1 = $u >> 16
      , v1 = $v >> 16
      , t  = (u1 * v0 >>> 0) + (u0 * v0 >>> 16);
    return u1 * v1 + (t >> 16) + ((u0 * v1 >>> 0) + (t & UINT16) >> 16);
  }
});

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

// https://gist.github.com/BrendanEich/4294d5c212a6d2254703
var $export = __webpack_require__(0);

$export($export.S, 'Math', {
  isubh: function isubh(x0, x1, y0, y1){
    var $x0 = x0 >>> 0
      , $x1 = x1 >>> 0
      , $y0 = y0 >>> 0;
    return $x1 - (y1 >>> 0) - ((~$x0 & $y0 | ~($x0 ^ $y0) & $x0 - $y0 >>> 0) >>> 31) | 0;
  }
});

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

// https://gist.github.com/BrendanEich/4294d5c212a6d2254703
var $export = __webpack_require__(0);

$export($export.S, 'Math', {
  umulh: function umulh(u, v){
    var UINT16 = 0xffff
      , $u = +u
      , $v = +v
      , u0 = $u & UINT16
      , v0 = $v & UINT16
      , u1 = $u >>> 16
      , v1 = $v >>> 16
      , t  = (u1 * v0 >>> 0) + (u0 * v0 >>> 16);
    return u1 * v1 + (t >>> 16) + ((u0 * v1 >>> 0) + (t & UINT16) >>> 16);
  }
});

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

"use strict";
'use strict';
var $export         = __webpack_require__(0)
  , toObject        = __webpack_require__(13)
  , aFunction       = __webpack_require__(16)
  , $defineProperty = __webpack_require__(9);

// B.2.2.2 Object.prototype.__defineGetter__(P, getter)
__webpack_require__(8) && $export($export.P + __webpack_require__(79), 'Object', {
  __defineGetter__: function __defineGetter__(P, getter){
    $defineProperty.f(toObject(this), P, {get: aFunction(getter), enumerable: true, configurable: true});
  }
});

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

"use strict";
'use strict';
var $export         = __webpack_require__(0)
  , toObject        = __webpack_require__(13)
  , aFunction       = __webpack_require__(16)
  , $defineProperty = __webpack_require__(9);

// B.2.2.3 Object.prototype.__defineSetter__(P, setter)
__webpack_require__(8) && $export($export.P + __webpack_require__(79), 'Object', {
  __defineSetter__: function __defineSetter__(P, setter){
    $defineProperty.f(toObject(this), P, {set: aFunction(setter), enumerable: true, configurable: true});
  }
});

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

// https://github.com/tc39/proposal-object-values-entries
var $export  = __webpack_require__(0)
  , $entries = __webpack_require__(168)(true);

$export($export.S, 'Object', {
  entries: function entries(it){
    return $entries(it);
  }
});

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

// https://github.com/tc39/proposal-object-getownpropertydescriptors
var $export        = __webpack_require__(0)
  , ownKeys        = __webpack_require__(169)
  , toIObject      = __webpack_require__(20)
  , gOPD           = __webpack_require__(25)
  , createProperty = __webpack_require__(90);

$export($export.S, 'Object', {
  getOwnPropertyDescriptors: function getOwnPropertyDescriptors(object){
    var O       = toIObject(object)
      , getDesc = gOPD.f
      , keys    = ownKeys(O)
      , result  = {}
      , i       = 0
      , key;
    while(keys.length > i)createProperty(result, key = keys[i++], getDesc(O, key));
    return result;
  }
});

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

"use strict";
'use strict';
var $export                  = __webpack_require__(0)
  , toObject                 = __webpack_require__(13)
  , toPrimitive              = __webpack_require__(33)
  , getPrototypeOf           = __webpack_require__(26)
  , getOwnPropertyDescriptor = __webpack_require__(25).f;

// B.2.2.4 Object.prototype.__lookupGetter__(P)
__webpack_require__(8) && $export($export.P + __webpack_require__(79), 'Object', {
  __lookupGetter__: function __lookupGetter__(P){
    var O = toObject(this)
      , K = toPrimitive(P, true)
      , D;
    do {
      if(D = getOwnPropertyDescriptor(O, K))return D.get;
    } while(O = getPrototypeOf(O));
  }
});

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

"use strict";
'use strict';
var $export                  = __webpack_require__(0)
  , toObject                 = __webpack_require__(13)
  , toPrimitive              = __webpack_require__(33)
  , getPrototypeOf           = __webpack_require__(26)
  , getOwnPropertyDescriptor = __webpack_require__(25).f;

// B.2.2.5 Object.prototype.__lookupSetter__(P)
__webpack_require__(8) && $export($export.P + __webpack_require__(79), 'Object', {
  __lookupSetter__: function __lookupSetter__(P){
    var O = toObject(this)
      , K = toPrimitive(P, true)
      , D;
    do {
      if(D = getOwnPropertyDescriptor(O, K))return D.set;
    } while(O = getPrototypeOf(O));
  }
});

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

// https://github.com/tc39/proposal-object-values-entries
var $export = __webpack_require__(0)
  , $values = __webpack_require__(168)(false);

$export($export.S, 'Object', {
  values: function values(it){
    return $values(it);
  }
});

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

"use strict";
'use strict';
// https://github.com/zenparsing/es-observable
var $export     = __webpack_require__(0)
  , global      = __webpack_require__(4)
  , core        = __webpack_require__(34)
  , microtask   = __webpack_require__(102)()
  , OBSERVABLE  = __webpack_require__(7)('observable')
  , aFunction   = __webpack_require__(16)
  , anObject    = __webpack_require__(3)
  , anInstance  = __webpack_require__(49)
  , redefineAll = __webpack_require__(54)
  , hide        = __webpack_require__(17)
  , forOf       = __webpack_require__(61)
  , RETURN      = forOf.RETURN;

var getMethod = function(fn){
  return fn == null ? undefined : aFunction(fn);
};

var cleanupSubscription = function(subscription){
  var cleanup = subscription._c;
  if(cleanup){
    subscription._c = undefined;
    cleanup();
  }
};

var subscriptionClosed = function(subscription){
  return subscription._o === undefined;
};

var closeSubscription = function(subscription){
  if(!subscriptionClosed(subscription)){
    subscription._o = undefined;
    cleanupSubscription(subscription);
  }
};

var Subscription = function(observer, subscriber){
  anObject(observer);
  this._c = undefined;
  this._o = observer;
  observer = new SubscriptionObserver(this);
  try {
    var cleanup      = subscriber(observer)
      , subscription = cleanup;
    if(cleanup != null){
      if(typeof cleanup.unsubscribe === 'function')cleanup = function(){ subscription.unsubscribe(); };
      else aFunction(cleanup);
      this._c = cleanup;
    }
  } catch(e){
    observer.error(e);
    return;
  } if(subscriptionClosed(this))cleanupSubscription(this);
};

Subscription.prototype = redefineAll({}, {
  unsubscribe: function unsubscribe(){ closeSubscription(this); }
});

var SubscriptionObserver = function(subscription){
  this._s = subscription;
};

SubscriptionObserver.prototype = redefineAll({}, {
  next: function next(value){
    var subscription = this._s;
    if(!subscriptionClosed(subscription)){
      var observer = subscription._o;
      try {
        var m = getMethod(observer.next);
        if(m)return m.call(observer, value);
      } catch(e){
        try {
          closeSubscription(subscription);
        } finally {
          throw e;
        }
      }
    }
  },
  error: function error(value){
    var subscription = this._s;
    if(subscriptionClosed(subscription))throw value;
    var observer = subscription._o;
    subscription._o = undefined;
    try {
      var m = getMethod(observer.error);
      if(!m)throw value;
      value = m.call(observer, value);
    } catch(e){
      try {
        cleanupSubscription(subscription);
      } finally {
        throw e;
      }
    } cleanupSubscription(subscription);
    return value;
  },
  complete: function complete(value){
    var subscription = this._s;
    if(!subscriptionClosed(subscription)){
      var observer = subscription._o;
      subscription._o = undefined;
      try {
        var m = getMethod(observer.complete);
        value = m ? m.call(observer, value) : undefined;
      } catch(e){
        try {
          cleanupSubscription(subscription);
        } finally {
          throw e;
        }
      } cleanupSubscription(subscription);
      return value;
    }
  }
});

var $Observable = function Observable(subscriber){
  anInstance(this, $Observable, 'Observable', '_f')._f = aFunction(subscriber);
};

redefineAll($Observable.prototype, {
  subscribe: function subscribe(observer){
    return new Subscription(observer, this._f);
  },
  forEach: function forEach(fn){
    var that = this;
    return new (core.Promise || global.Promise)(function(resolve, reject){
      aFunction(fn);
      var subscription = that.subscribe({
        next : function(value){
          try {
            return fn(value);
          } catch(e){
            reject(e);
            subscription.unsubscribe();
          }
        },
        error: reject,
        complete: resolve
      });
    });
  }
});

redefineAll($Observable, {
  from: function from(x){
    var C = typeof this === 'function' ? this : $Observable;
    var method = getMethod(anObject(x)[OBSERVABLE]);
    if(method){
      var observable = anObject(method.call(x));
      return observable.constructor === C ? observable : new C(function(observer){
        return observable.subscribe(observer);
      });
    }
    return new C(function(observer){
      var done = false;
      microtask(function(){
        if(!done){
          try {
            if(forOf(x, false, function(it){
              observer.next(it);
              if(done)return RETURN;
            }) === RETURN)return;
          } catch(e){
            if(done)throw e;
            observer.error(e);
            return;
          } observer.complete();
        }
      });
      return function(){ done = true; };
    });
  },
  of: function of(){
    for(var i = 0, l = arguments.length, items = Array(l); i < l;)items[i] = arguments[i++];
    return new (typeof this === 'function' ? this : $Observable)(function(observer){
      var done = false;
      microtask(function(){
        if(!done){
          for(var i = 0; i < items.length; ++i){
            observer.next(items[i]);
            if(done)return;
          } observer.complete();
        }
      });
      return function(){ done = true; };
    });
  }
});

hide($Observable.prototype, OBSERVABLE, function(){ return this; });

$export($export.G, {Observable: $Observable});

__webpack_require__(55)('Observable');

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

var metadata                  = __webpack_require__(36)
  , anObject                  = __webpack_require__(3)
  , toMetaKey                 = metadata.key
  , ordinaryDefineOwnMetadata = metadata.set;

metadata.exp({defineMetadata: function defineMetadata(metadataKey, metadataValue, target, targetKey){
  ordinaryDefineOwnMetadata(metadataKey, metadataValue, anObject(target), toMetaKey(targetKey));
}});

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

var metadata               = __webpack_require__(36)
  , anObject               = __webpack_require__(3)
  , toMetaKey              = metadata.key
  , getOrCreateMetadataMap = metadata.map
  , store                  = metadata.store;

metadata.exp({deleteMetadata: function deleteMetadata(metadataKey, target /*, targetKey */){
  var targetKey   = arguments.length < 3 ? undefined : toMetaKey(arguments[2])
    , metadataMap = getOrCreateMetadataMap(anObject(target), targetKey, false);
  if(metadataMap === undefined || !metadataMap['delete'](metadataKey))return false;
  if(metadataMap.size)return true;
  var targetMetadata = store.get(target);
  targetMetadata['delete'](targetKey);
  return !!targetMetadata.size || store['delete'](target);
}});

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

var Set                     = __webpack_require__(177)
  , from                    = __webpack_require__(153)
  , metadata                = __webpack_require__(36)
  , anObject                = __webpack_require__(3)
  , getPrototypeOf          = __webpack_require__(26)
  , ordinaryOwnMetadataKeys = metadata.keys
  , toMetaKey               = metadata.key;

var ordinaryMetadataKeys = function(O, P){
  var oKeys  = ordinaryOwnMetadataKeys(O, P)
    , parent = getPrototypeOf(O);
  if(parent === null)return oKeys;
  var pKeys  = ordinaryMetadataKeys(parent, P);
  return pKeys.length ? oKeys.length ? from(new Set(oKeys.concat(pKeys))) : pKeys : oKeys;
};

metadata.exp({getMetadataKeys: function getMetadataKeys(target /*, targetKey */){
  return ordinaryMetadataKeys(anObject(target), arguments.length < 2 ? undefined : toMetaKey(arguments[1]));
}});

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

var metadata               = __webpack_require__(36)
  , anObject               = __webpack_require__(3)
  , getPrototypeOf         = __webpack_require__(26)
  , ordinaryHasOwnMetadata = metadata.has
  , ordinaryGetOwnMetadata = metadata.get
  , toMetaKey              = metadata.key;

var ordinaryGetMetadata = function(MetadataKey, O, P){
  var hasOwn = ordinaryHasOwnMetadata(MetadataKey, O, P);
  if(hasOwn)return ordinaryGetOwnMetadata(MetadataKey, O, P);
  var parent = getPrototypeOf(O);
  return parent !== null ? ordinaryGetMetadata(MetadataKey, parent, P) : undefined;
};

metadata.exp({getMetadata: function getMetadata(metadataKey, target /*, targetKey */){
  return ordinaryGetMetadata(metadataKey, anObject(target), arguments.length < 3 ? undefined : toMetaKey(arguments[2]));
}});

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

var metadata                = __webpack_require__(36)
  , anObject                = __webpack_require__(3)
  , ordinaryOwnMetadataKeys = metadata.keys
  , toMetaKey               = metadata.key;

metadata.exp({getOwnMetadataKeys: function getOwnMetadataKeys(target /*, targetKey */){
  return ordinaryOwnMetadataKeys(anObject(target), arguments.length < 2 ? undefined : toMetaKey(arguments[1]));
}});

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

var metadata               = __webpack_require__(36)
  , anObject               = __webpack_require__(3)
  , ordinaryGetOwnMetadata = metadata.get
  , toMetaKey              = metadata.key;

metadata.exp({getOwnMetadata: function getOwnMetadata(metadataKey, target /*, targetKey */){
  return ordinaryGetOwnMetadata(metadataKey, anObject(target)
    , arguments.length < 3 ? undefined : toMetaKey(arguments[2]));
}});

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

var metadata               = __webpack_require__(36)
  , anObject               = __webpack_require__(3)
  , getPrototypeOf         = __webpack_require__(26)
  , ordinaryHasOwnMetadata = metadata.has
  , toMetaKey              = metadata.key;

var ordinaryHasMetadata = function(MetadataKey, O, P){
  var hasOwn = ordinaryHasOwnMetadata(MetadataKey, O, P);
  if(hasOwn)return true;
  var parent = getPrototypeOf(O);
  return parent !== null ? ordinaryHasMetadata(MetadataKey, parent, P) : false;
};

metadata.exp({hasMetadata: function hasMetadata(metadataKey, target /*, targetKey */){
  return ordinaryHasMetadata(metadataKey, anObject(target), arguments.length < 3 ? undefined : toMetaKey(arguments[2]));
}});

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

var metadata               = __webpack_require__(36)
  , anObject               = __webpack_require__(3)
  , ordinaryHasOwnMetadata = metadata.has
  , toMetaKey              = metadata.key;

metadata.exp({hasOwnMetadata: function hasOwnMetadata(metadataKey, target /*, targetKey */){
  return ordinaryHasOwnMetadata(metadataKey, anObject(target)
    , arguments.length < 3 ? undefined : toMetaKey(arguments[2]));
}});

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

var metadata                  = __webpack_require__(36)
  , anObject                  = __webpack_require__(3)
  , aFunction                 = __webpack_require__(16)
  , toMetaKey                 = metadata.key
  , ordinaryDefineOwnMetadata = metadata.set;

metadata.exp({metadata: function metadata(metadataKey, metadataValue){
  return function decorator(target, targetKey){
    ordinaryDefineOwnMetadata(
      metadataKey, metadataValue,
      (targetKey !== undefined ? anObject : aFunction)(target),
      toMetaKey(targetKey)
    );
  };
}});

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

// https://github.com/DavidBruant/Map-Set.prototype.toJSON
var $export  = __webpack_require__(0);

$export($export.P + $export.R, 'Set', {toJSON: __webpack_require__(157)('Set')});

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

"use strict";
'use strict';
// https://github.com/mathiasbynens/String.prototype.at
var $export = __webpack_require__(0)
  , $at     = __webpack_require__(106)(true);

$export($export.P, 'String', {
  at: function at(pos){
    return $at(this, pos);
  }
});

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

"use strict";
'use strict';
// https://tc39.github.io/String.prototype.matchAll/
var $export     = __webpack_require__(0)
  , defined     = __webpack_require__(29)
  , toLength    = __webpack_require__(12)
  , isRegExp    = __webpack_require__(77)
  , getFlags    = __webpack_require__(75)
  , RegExpProto = RegExp.prototype;

var $RegExpStringIterator = function(regexp, string){
  this._r = regexp;
  this._s = string;
};

__webpack_require__(98)($RegExpStringIterator, 'RegExp String', function next(){
  var match = this._r.exec(this._s);
  return {value: match, done: match === null};
});

$export($export.P, 'String', {
  matchAll: function matchAll(regexp){
    defined(this);
    if(!isRegExp(regexp))throw TypeError(regexp + ' is not a regexp!');
    var S     = String(this)
      , flags = 'flags' in RegExpProto ? String(regexp.flags) : getFlags.call(regexp)
      , rx    = new RegExp(regexp.source, ~flags.indexOf('g') ? flags : 'g' + flags);
    rx.lastIndex = toLength(regexp.lastIndex);
    return new $RegExpStringIterator(rx, S);
  }
});

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

"use strict";
'use strict';
// https://github.com/tc39/proposal-string-pad-start-end
var $export = __webpack_require__(0)
  , $pad    = __webpack_require__(173);

$export($export.P, 'String', {
  padEnd: function padEnd(maxLength /*, fillString = ' ' */){
    return $pad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, false);
  }
});

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

"use strict";
'use strict';
// https://github.com/tc39/proposal-string-pad-start-end
var $export = __webpack_require__(0)
  , $pad    = __webpack_require__(173);

$export($export.P, 'String', {
  padStart: function padStart(maxLength /*, fillString = ' ' */){
    return $pad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, true);
  }
});

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

"use strict";
'use strict';
// https://github.com/sebmarkbage/ecmascript-string-left-right-trim
__webpack_require__(64)('trimLeft', function($trim){
  return function trimLeft(){
    return $trim(this, 1);
  };
}, 'trimStart');

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

"use strict";
'use strict';
// https://github.com/sebmarkbage/ecmascript-string-left-right-trim
__webpack_require__(64)('trimRight', function($trim){
  return function trimRight(){
    return $trim(this, 2);
  };
}, 'trimEnd');

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

__webpack_require__(112)('asyncIterator');

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

__webpack_require__(112)('observable');

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

// https://github.com/ljharb/proposal-global
var $export = __webpack_require__(0);

$export($export.S, 'System', {global: __webpack_require__(4)});

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

var $iterators    = __webpack_require__(114)
  , redefine      = __webpack_require__(18)
  , global        = __webpack_require__(4)
  , hide          = __webpack_require__(17)
  , Iterators     = __webpack_require__(62)
  , wks           = __webpack_require__(7)
  , ITERATOR      = wks('iterator')
  , TO_STRING_TAG = wks('toStringTag')
  , ArrayValues   = Iterators.Array;

for(var collections = ['NodeList', 'DOMTokenList', 'MediaList', 'StyleSheetList', 'CSSRuleList'], i = 0; i < 5; i++){
  var NAME       = collections[i]
    , Collection = global[NAME]
    , proto      = Collection && Collection.prototype
    , key;
  if(proto){
    if(!proto[ITERATOR])hide(proto, ITERATOR, ArrayValues);
    if(!proto[TO_STRING_TAG])hide(proto, TO_STRING_TAG, NAME);
    Iterators[NAME] = ArrayValues;
    for(key in $iterators)if(!proto[key])redefine(proto, key, $iterators[key], true);
  }
}

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

var $export = __webpack_require__(0)
  , $task   = __webpack_require__(110);
$export($export.G + $export.B, {
  setImmediate:   $task.set,
  clearImmediate: $task.clear
});

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

// ie9- setTimeout & setInterval additional parameters fix
var global     = __webpack_require__(4)
  , $export    = __webpack_require__(0)
  , invoke     = __webpack_require__(76)
  , partial    = __webpack_require__(234)
  , navigator  = global.navigator
  , MSIE       = !!navigator && /MSIE .\./.test(navigator.userAgent); // <- dirty ie9- check
var wrap = function(set){
  return MSIE ? function(fn, time /*, ...args */){
    return set(invoke(
      partial,
      [].slice.call(arguments, 2),
      typeof fn == 'function' ? fn : Function(fn)
    ), time);
  } : set;
};
$export($export.G + $export.B + $export.F * MSIE, {
  setTimeout:  wrap(global.setTimeout),
  setInterval: wrap(global.setInterval)
});

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

__webpack_require__(357);
__webpack_require__(296);
__webpack_require__(298);
__webpack_require__(297);
__webpack_require__(300);
__webpack_require__(302);
__webpack_require__(307);
__webpack_require__(301);
__webpack_require__(299);
__webpack_require__(309);
__webpack_require__(308);
__webpack_require__(304);
__webpack_require__(305);
__webpack_require__(303);
__webpack_require__(295);
__webpack_require__(306);
__webpack_require__(310);
__webpack_require__(311);
__webpack_require__(263);
__webpack_require__(265);
__webpack_require__(264);
__webpack_require__(313);
__webpack_require__(312);
__webpack_require__(283);
__webpack_require__(293);
__webpack_require__(294);
__webpack_require__(284);
__webpack_require__(285);
__webpack_require__(286);
__webpack_require__(287);
__webpack_require__(288);
__webpack_require__(289);
__webpack_require__(290);
__webpack_require__(291);
__webpack_require__(292);
__webpack_require__(266);
__webpack_require__(267);
__webpack_require__(268);
__webpack_require__(269);
__webpack_require__(270);
__webpack_require__(271);
__webpack_require__(272);
__webpack_require__(273);
__webpack_require__(274);
__webpack_require__(275);
__webpack_require__(276);
__webpack_require__(277);
__webpack_require__(278);
__webpack_require__(279);
__webpack_require__(280);
__webpack_require__(281);
__webpack_require__(282);
__webpack_require__(344);
__webpack_require__(349);
__webpack_require__(356);
__webpack_require__(347);
__webpack_require__(339);
__webpack_require__(340);
__webpack_require__(345);
__webpack_require__(350);
__webpack_require__(352);
__webpack_require__(335);
__webpack_require__(336);
__webpack_require__(337);
__webpack_require__(338);
__webpack_require__(341);
__webpack_require__(342);
__webpack_require__(343);
__webpack_require__(346);
__webpack_require__(348);
__webpack_require__(351);
__webpack_require__(353);
__webpack_require__(354);
__webpack_require__(355);
__webpack_require__(258);
__webpack_require__(260);
__webpack_require__(259);
__webpack_require__(262);
__webpack_require__(261);
__webpack_require__(247);
__webpack_require__(245);
__webpack_require__(251);
__webpack_require__(248);
__webpack_require__(254);
__webpack_require__(256);
__webpack_require__(244);
__webpack_require__(250);
__webpack_require__(241);
__webpack_require__(255);
__webpack_require__(239);
__webpack_require__(253);
__webpack_require__(252);
__webpack_require__(246);
__webpack_require__(249);
__webpack_require__(238);
__webpack_require__(240);
__webpack_require__(243);
__webpack_require__(242);
__webpack_require__(257);
__webpack_require__(114);
__webpack_require__(329);
__webpack_require__(334);
__webpack_require__(176);
__webpack_require__(330);
__webpack_require__(331);
__webpack_require__(332);
__webpack_require__(333);
__webpack_require__(314);
__webpack_require__(175);
__webpack_require__(177);
__webpack_require__(178);
__webpack_require__(369);
__webpack_require__(358);
__webpack_require__(359);
__webpack_require__(364);
__webpack_require__(367);
__webpack_require__(368);
__webpack_require__(362);
__webpack_require__(365);
__webpack_require__(363);
__webpack_require__(366);
__webpack_require__(360);
__webpack_require__(361);
__webpack_require__(315);
__webpack_require__(316);
__webpack_require__(317);
__webpack_require__(318);
__webpack_require__(319);
__webpack_require__(322);
__webpack_require__(320);
__webpack_require__(321);
__webpack_require__(323);
__webpack_require__(324);
__webpack_require__(325);
__webpack_require__(326);
__webpack_require__(328);
__webpack_require__(327);
__webpack_require__(370);
__webpack_require__(396);
__webpack_require__(399);
__webpack_require__(398);
__webpack_require__(400);
__webpack_require__(401);
__webpack_require__(397);
__webpack_require__(402);
__webpack_require__(403);
__webpack_require__(381);
__webpack_require__(384);
__webpack_require__(380);
__webpack_require__(378);
__webpack_require__(379);
__webpack_require__(382);
__webpack_require__(383);
__webpack_require__(373);
__webpack_require__(395);
__webpack_require__(404);
__webpack_require__(372);
__webpack_require__(374);
__webpack_require__(376);
__webpack_require__(375);
__webpack_require__(377);
__webpack_require__(386);
__webpack_require__(387);
__webpack_require__(389);
__webpack_require__(388);
__webpack_require__(391);
__webpack_require__(390);
__webpack_require__(392);
__webpack_require__(393);
__webpack_require__(394);
__webpack_require__(371);
__webpack_require__(385);
__webpack_require__(407);
__webpack_require__(406);
__webpack_require__(405);
module.exports = __webpack_require__(34);

/***/ },
/* 409 */,
/* 410 */,
/* 411 */,
/* 412 */,
/* 413 */,
/* 414 */,
/* 415 */,
/* 416 */,
/* 417 */,
/* 418 */,
/* 419 */,
/* 420 */,
/* 421 */,
/* 422 */
/***/ function(module, exports) {

module.exports = "<div class=\"vzb-bs-holder\">\n\t<svg class=\"vzb-bs-svg\">\n\t\t<g class=\"vzb-bs-slider-wrap\">\n\t\t\t<g class=\"vzb-bs-slider\">\n\t\t\t</g>\n\t\t</g>\n\t</svg>\n</div>\n";

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

module.exports = "<div class='vzb-dialog-modal'>\n  <div class=\"vzb-dialog-title\"> \n      <%=t (\"buttons/about\") %>\n  </div>\n      \n  <div class=\"vzb-dialog-content\">\n      <p class=\"vzb-about-text0\"></p>\n      <p class=\"vzb-about-text1\"></p>\n      <br/>\n      <p class=\"vzb-about-version\"></p>\n      <p class=\"vzb-about-updated\"></p>\n      <br/>\n      <p class=\"vzb-about-text2\"></p>\n      <br/>\n      <p class=\"vzb-about-report\"></p>\n      <br/>\n      <p class=\"vzb-about-credits\"></p>\n  </div>\n      \n  <div class=\"vzb-dialog-buttons\">\n    <div data-click=\"closeDialog\" class=\"vzb-dialog-button vzb-label-primary\">\n      <%=t (\"buttons/ok\") %>\n    </div>\n  </div>\n      \n\n</div>\n";

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

module.exports = "<div class='vzb-dialog-modal'>\n    <span class=\"thumb-tack-class thumb-tack-class-ico-pin fa\" data-dialogtype=\"axes\" data-click=\"pinDialog\"></span>\n    <span class=\"thumb-tack-class thumb-tack-class-ico-drag fa\" data-dialogtype=\"axes\" data-click=\"dragDialog\"></span>\n    <div class=\"vzb-dialog-title\"><%=t (\"buttons/axes\") %></div>\n    <div class=\"vzb-dialog-content\">\n      <p class=\"vzb-dialog-sublabel\"> <%=t (\"buttons/axis_x\") %> <span class=\"vzb-xaxis-selector\"></span> </p>\n      <div class=\"vzb-xaxis-minmax vzb-dialog-paragraph\"></div>\n      <p class=\"vzb-dialog-sublabel\"> <%=t (\"buttons/axis_y\") %> <span class=\"vzb-yaxis-selector\"></span> </p>\n      <div class=\"vzb-yaxis-minmax vzb-dialog-paragraph\"></div>\n    </div>\n    <div class=\"vzb-dialog-buttons\">\n      <div data-click=\"closeDialog\" class=\"vzb-dialog-button vzb-label-primary\"><%=t ( \"buttons/ok\") %></div>\n    </div>\n</div>";

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

module.exports = "<div class='vzb-dialog-modal'>\n    <span class=\"thumb-tack-class thumb-tack-class-ico-pin fa\" data-dialogtype=\"axesmc\" data-click=\"pinDialog\"></span>\n    <span class=\"thumb-tack-class thumb-tack-class-ico-drag fa\" data-dialogtype=\"axesmc\" data-click=\"dragDialog\"></span>\n    <div class=\"vzb-dialog-title\">\n        <%=t (\"buttons/axes\") %>\n    </div>\n    <div class=\"vzb-dialog-content\">\n        <div class=\"vzb-yaxis-container\">\n            <p class=\"vzb-dialog-sublabel\"><%=t (\"hints/mount/maxYvalue\") %></p>\n            <form class=\"vzb-dialog-paragraph\">\n                <label><input type=\"radio\" name=\"ymax\" value=\"immediate\"><%=t (\"mount/maxYmode/immediate\") %></label>\n                <label><input type=\"radio\" name=\"ymax\" value=\"latest\"><%=t (\"mount/maxYmode/latest\") %></label>\n            </form>\n        </div>\n        <div class=\"vzb-xaxis-container\">\n            <p class=\"vzb-dialog-sublabel\">\n                <%=t (\"hints/mount/logXstops\") %>\n            </p>\n            <form class=\"vzb-dialog-paragraph\">\n                <input type=\"checkbox\" name=\"logstops\" value=\"1\">1\n                <input type=\"checkbox\" name=\"logstops\" value=\"2\">2\n                <input type=\"checkbox\" name=\"logstops\" value=\"5\">5\n            </form>\n        </div>\n        <p class=\"vzb-dialog-sublabel\">\n            <%=t (\"hints/mount/xlimits\") %>\n        </p>\n        <div class=\"vzb-xlimits-container vzb-dialog-paragraph\"></div>\n        <div class=\"vzb-probe-container\">\n            <p class=\"vzb-dialog-sublabel\">\n              <input type=\"checkbox\" name=\"probe\" class=\"vzb-probe-check\"> <%=t (\"hints/mount/probe\") %>\n            </p>\n            <input type=\"text\" class=\"vzb-probe-field\" name=\"probe\">\n        </div>\n    </div>\n    <div class=\"vzb-dialog-buttons\">\n        <div data-click=\"closeDialog\" class=\"vzb-dialog-button vzb-label-primary\">\n            <%=t (\"buttons/ok\") %>\n        </div>\n    </div>\n</div>";

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

module.exports = "<div class='vzb-dialog-modal'>\n  <span class=\"thumb-tack-class thumb-tack-class-ico-pin fa\" data-dialogtype=\"colors\" data-click=\"pinDialog\"></span>\n  <span class=\"thumb-tack-class thumb-tack-class-ico-drag fa\" data-dialogtype=\"colors\" data-click=\"dragDialog\"></span>\n  \n  <div class=\"vzb-dialog-title\">\n      <%=t (\"buttons/colors\") %>\n      <span class=\"vzb-caxis-selector\"></span>\n  </div>\n  \n  \n  \n  <div class=\"vzb-dialog-content vzb-dialog-scrollable\">\n    <div class=\"vzb-clegend-container\"></div>\n  </div>\n\n  <div class=\"vzb-dialog-buttons\">\n    <div data-click=\"closeDialog\" class=\"vzb-dialog-button vzb-label-primary\">\n      <%=t (\"buttons/ok\") %>\n    </div>\n  </div>\n\n</div>\n";

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

module.exports = "<div class='vzb-dialog-modal'>\n  <span class=\"thumb-tack-class thumb-tack-class-ico-pin fa\" data-dialogtype=\"find\" data-click=\"pinDialog\"></span>\n  <span class=\"thumb-tack-class thumb-tack-class-ico-drag fa\" data-dialogtype=\"find\" data-click=\"dragDialog\"></span>\n  <div class=\"vzb-dialog-title\">\n    <%=t (\"dialogs/find\") %>\n    <span class=\"vzb-dialog-content vzb-find-filter\">\n      <input class=\"vzb-find-search\" type=\"search\"/>\n    </span>\n  </div>\n  \n  <div class=\"vzb-dialog-content vzb-dialog-content-fixed vzb-dialog-scrollable\">\n    <div class=\"vzb-find-list\">\n      <!-- list will be placed here -->\n    </div>\n  </div>\n\n  <div class=\"vzb-dialog-buttons\">\n    <div class=\"vzb-dialog-bubbleopacity vzb-dialog-control\"></div>\n    <div class=\"vzb-dialog-button vzb-find-deselect\">\n      <%=t (\"buttons/deselect\") %>\n    </div>\n\n    <div data-click=\"closeDialog\" class=\"vzb-dialog-button vzb-label-primary\">\n      <%=t (\"buttons/ok\") %>\n    </div>\n  </div>\n\n</div>\n";

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

module.exports = "<div class='vzb-dialog-modal'>\n  <span class=\"thumb-tack-class thumb-tack-class-ico-pin fa\" data-dialogtype=\"label\" data-click=\"pinDialog\"></span>\n  <span class=\"thumb-tack-class thumb-tack-class-ico-drag fa\" data-dialogtype=\"label\" data-click=\"dragDialog\"></span>\n  <div class=\"vzb-dialog-title\"> \n      <%=t (\"buttons/label\") %>\n  </div>\n      \n      \n  <div class=\"vzb-dialog-content\">\n    <span class=\"vzb-saxis-selector\"></span>\n    <div class=\"vzb-dialog-sizeslider\"></div>\n    <div class=\"vzb-removelabelbox-switch\"></div>\n  </div>\n\n  <div class=\"vzb-dialog-buttons\">\n    <div data-click=\"closeDialog\" class=\"vzb-dialog-button vzb-label-primary\">\n      <%=t (\"buttons/ok\") %>\n    </div>\n  </div>\n\n</div>\n";

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

module.exports = "<div class='vzb-dialog-modal'>\n  <span class=\"thumb-tack-class thumb-tack-class-ico-pin fa\" data-dialogtype=\"moreoptions\" data-click=\"pinDialog\"></span>\n  <span class=\"thumb-tack-class thumb-tack-class-ico-drag fa\" data-dialogtype=\"moreoptions\" data-click=\"dragDialog\"></span>\n\n\n  <div class=\"vzb-dialog-title\">\n    <%=t (\"buttons/more_options\") %>\n  </div>\n\n  <div class=\"vzb-dialog-content vzb-dialog-scrollable\">\n    <div class='vzb-dialog-options-buttonlist'>\n    </div>\n    <div class=\"vzb-accordion\">\n    </div>\n  </div>\n\n  <div class=\"vzb-dialog-buttons\">\n    <div data-click=\"closeDialog\" class=\"vzb-dialog-button vzb-label-primary\">\n      <%=t (\"buttons/ok\") %>\n    </div>\n  </div>\n\n</div>";

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

module.exports = "<div class='vzb-dialog-modal'>\n  <div class=\"vzb-dialog-title\"> \n      <%=t (\"buttons/opacity\") %>\n  </div>\n      \n  <div class=\"vzb-dialog-content\">\n      <p class=\"vzb-dialog-sublabel\">\n        <%=t (\"buttons/opacityRegular\") %>\n      </p>\n      <div class=\"vzb-dialog-bubbleopacity-regular\"></div>\n\n      <p class=\"vzb-dialog-sublabel\">\n        <%=t (\"buttons/opacityNonselect\") %>\n      </p>\n      <div class=\"vzb-dialog-bubbleopacity-selectdim\"></div>\n    </div>\n  </div>\n\n</div>\n";

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

module.exports = "<div class='vzb-dialog-modal'>\n  <div class=\"vzb-dialog-title\"> \n      <%=t (\"dialogs/presentation\") %>\n  </div>\n      \n  <div class=\"vzb-dialog-content\">\n      <div class=\"vzb-presentationmode-switch\"></div>\n  </div>\n\n</div>\n";

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

module.exports = "<div class='vzb-dialog-modal'>\n  <span class=\"thumb-tack-class thumb-tack-class-ico-pin fa\" data-dialogtype=\"show\" data-click=\"pinDialog\"></span>\n  <span class=\"thumb-tack-class thumb-tack-class-ico-drag fa\" data-dialogtype=\"show\" data-click=\"dragDialog\"></span>\n  <div class=\"vzb-dialog-title\">\n    <%=t (\"buttons/show\") %>\n    <span class=\"vzb-dialog-content vzb-show-filter\">\n      <input class=\"vzb-show-search\" type=\"search\"/>\n    </span>\n  </div>\n  \n  <div class=\"vzb-dialog-content vzb-dialog-content-fixed vzb-dialog-scrollable\">\n    <p class=\"vzb-dialog-sublabel\"> <%=t (\"hints/mount/onlyshowthefollowing\") %> </p>\n    <div class=\"vzb-show-list\">\n      <!-- list will be placed here -->\n    </div>\n  </div>\n\n  <div class=\"vzb-dialog-buttons\">\n    <div class=\"vzb-dialog-button vzb-show-deselect\">\n      <%=t (\"buttons/showall\") %>\n    </div>\n\n    <div data-click=\"closeDialog\" class=\"vzb-dialog-button vzb-label-primary\">\n      <%=t (\"buttons/ok\") %>\n    </div>\n  </div>\n\n</div>\n";

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

module.exports = "<div class='vzb-dialog-modal'>\n  <span class=\"thumb-tack-class thumb-tack-class-ico-pin fa\" data-dialogtype=\"side\" data-click=\"pinDialog\"></span>\n  <span class=\"thumb-tack-class thumb-tack-class-ico-drag fa\" data-dialogtype=\"side\" data-click=\"dragDialog\"></span>\n  <div class=\"vzb-dialog-title\">\n    <%=t (\"buttons/side\") %>\n    <span class=\"vzb-side-selector\"></span>\n    <span class=\"vzb-dialog-content vzb-side-filter\">\n      <input class=\"vzb-side-search\" type=\"search\"/>\n    </span>\n  </div>\n  \n  <div class=\"vzb-dialog-content vzb-dialog-scrollable\">\n    <p class=\"vzb-dialog-sublabel\"> <%=t (\"hints/ap/onlyshowthefollowingsides\") %> </p>\n    <div class=\"vzb-side-list\">\n      <!-- list will be placed here -->\n    </div>\n    <div class=\"vzb-flipsides-switch\"></div>\n  </div>\n\n  <div class=\"vzb-dialog-buttons\">\n    <div class=\"vzb-dialog-button vzb-side-deselect\">\n      <%=t (\"buttons/showall\") %>\n    </div>\n\n    <div data-click=\"closeDialog\" class=\"vzb-dialog-button vzb-label-primary\">\n      <%=t (\"buttons/ok\") %>\n    </div>\n  </div>\n\n</div>\n";

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

module.exports = "<div class='vzb-dialog-modal'>\n  <span class=\"thumb-tack-class thumb-tack-class-ico-pin fa\" data-dialogtype=\"size\" data-click=\"pinDialog\"></span>\n  <span class=\"thumb-tack-class thumb-tack-class-ico-drag fa\" data-dialogtype=\"size\" data-click=\"dragDialog\"></span>\n  <div class=\"vzb-dialog-title\"> \n      <%=t (\"buttons/size\") %>\n      <span class=\"vzb-saxis-selector\"></span>\n  </div>\n      \n      \n  <div class=\"vzb-dialog-content\">\n    <div class=\"vzb-dialog-bubblesize\"></div>\n  </div>\n\n  <div class=\"vzb-dialog-buttons\">\n    <div data-click=\"closeDialog\" class=\"vzb-dialog-button vzb-label-primary\">\n      <%=t (\"buttons/ok\") %>\n    </div>\n  </div>\n\n</div>\n";

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

module.exports = "<div class='vzb-dialog-modal'>\n  <div class=\"vzb-dialog-title\"> \n      <%=t (\"buttons/speed\") %>\n  </div>\n      \n  <div class=\"vzb-dialog-content\">\n    <div class=\"vzb-dialog-placeholder\"></div>\n  </div>\n\n</div>\n";

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

module.exports = "<div class='vzb-dialog-modal'>\n    <span class=\"thumb-tack-class thumb-tack-class-ico-pin fa\" data-dialogtype=\"stack\" data-click=\"pinDialog\"></span>\n    <span class=\"thumb-tack-class thumb-tack-class-ico-drag fa\" data-dialogtype=\"stack\" data-click=\"dragDialog\"></span>\n    <div class=\"vzb-dialog-title\"><%=t (\"buttons/stack\") %></div>\n        \n    <div class=\"vzb-dialog-content vzb-dialog-scrollable\">\n        \n        <!--p class=\"vzb-dialog-sublabel\"> <%=t ( \"hints/mount/howtostack\") %></p-->\n        <form class=\"vzb-howtostack vzb-dialog-paragraph\">\n            <label> <input type=\"radio\" name=\"stack\" value=\"none\"> <%=t (\"mount/stacking/none\") %> </label>\n            <label> <input type=\"radio\" name=\"stack\" value=\"bycolor\"> <%=t (\"mount/stacking/color\") %> </label>\n            <label> <input type=\"radio\" name=\"stack\" value=\"all\"> <%=t (\"mount/stacking/world\") %> </label>\n        </form>\n        \n        <form class=\"vzb-howtomerge vzb-dialog-paragraph\">\n            <p class=\"vzb-dialog-sublabel\"> <%=t (\"hints/mount/howtomerge\") %> </p>\n            <label> <input type=\"radio\" name=\"merge\" value=\"none\"> <%=t (\"mount/merging/none\") %> </label>\n            <label> <input type=\"radio\" name=\"merge\" value=\"grouped\"> <%=t (\"mount/merging/color\") %> </label>\n            <label> <input type=\"radio\" name=\"merge\" value=\"stacked\"> <%=t (\"mount/merging/world\") %> </label>\n        </form>\n        \n        <form class=\"vzb-manual-sorting\">\n            <p class=\"vzb-dialog-sublabel\"> <%=t (\"mount/manualSorting\") %> </p>\n            <div class=\"vzb-dialog-draggablelist vzb-dialog-control\"></div>\n        </form>\n                \n    </div>\n\n    <div class=\"vzb-dialog-buttons\">\n        <div data-click=\"closeDialog\" class=\"vzb-dialog-button vzb-label-primary\"><%=t (\"buttons/ok\") %></div>\n    </div>\n\n</div>";

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

module.exports = "<div class=\"vzb-dialog-modal\">\n  <div class=\"vzb-dialog-content vzb-dialog-content-fixed\">\n    <svg>\n      <g class=\"vzb-timedisplay\"></g>\n    </svg>\n  </div>\n  <div class=\"vzb-dialog-buttons\"></div>\n</div>\n";

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

module.exports = "<div class='vzb-dialog-modal'>\n  <span class=\"thumb-tack-class thumb-tack-class-ico-pin fa\" data-dialogtype=\"label\" data-click=\"pinDialog\"></span>\n  <span class=\"thumb-tack-class thumb-tack-class-ico-drag fa\" data-dialogtype=\"label\" data-click=\"dragDialog\"></span>\n  <div class=\"vzb-dialog-title\"> \n    <%=t (\"buttons/zoom\") %>\n    <div class=\"vzb-dialog-zoom-buttonlist\"></div>\n  </div>\n      \n      \n  <div class=\"vzb-dialog-content\">\n    <div class=\"vzb-zoomonscrolling-switch\"></div>\n    <div class=\"vzb-adaptminmaxzoom-switch\"></div>\n  </div>\n\n  <div class=\"vzb-dialog-buttons\">\n    <div data-click=\"closeDialog\" class=\"vzb-dialog-button vzb-label-primary\">\n      <%=t (\"buttons/ok\") %>\n    </div>\n  </div>\n\n</div>\n";

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

module.exports = "<div class=\"vzb-mmi-holder\">\n\n    <span class=\"vzb-mmi-domainmin-label\"></span>\n    <input type=\"text\" class=\"vzb-mmi-domainmin\" name=\"min\">\n    <span class=\"vzb-mmi-domainmax-label\"></span>\n    <input type=\"text\" class=\"vzb-mmi-domainmax\" name=\"max\">\n\n    <br class=\"vzb-mmi-break\"/>\n\n    <span class=\"vzb-mmi-zoomedmin-label\"></span>\n    <input type=\"text\" class=\"vzb-mmi-zoomedmin\" name=\"min\">\n    <span class=\"vzb-mmi-zoomedmax-label\"></span>\n    <input type=\"text\" class=\"vzb-mmi-zoomedmax\" name=\"max\">\n    \n</div>";

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

module.exports = "<div class=\"vzb-szs-holder\">\n\t<svg class=\"vzb-szs-svg\">\n\t\t<g class=\"vzb-szs-slider-wrap\">\n\t\t\t<g class=\"vzb-szs-slider\">\n\t\t\t</g>\n\t\t</g>\n\t</svg>\n</div>\n";

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

module.exports = "<div class=\"vzb-timeslider vzb-ts-loading\">\n  <div class=\"vzb-ts-slider-wrapper\">\n    <svg class=\"vzb-ts-slider\">\n      <g>\n        <g class=\"vzb-ts-slider-axis\"></g>\n        <g class=\"vzb-ts-slider-progress\"></g>\n        <g class=\"vzb-ts-slider-select\"></g>\n        <g class=\"vzb-ts-slider-slide\">\n          <circle class=\"vzb-ts-slider-handle\"></circle>\n          <text class=\"vzb-ts-slider-value\"></text>\n        </g>\n      </g>\n      </svg>\n  </div>\n\n  <!-- SVG VIZABI ICONS\n       source: https://github.com/encharm/Font-Awesome-SVG-PNG/ -->\n  <div class=\"vzb-ts-btns\">\n    <button class=\"vzb-ts-btn-loading vzb-ts-btn\">\n      <div class='vzb-loader'></div>\n    </button>\n    <button class=\"vzb-ts-btn-play vzb-ts-btn\">\n      <svg class=\"vzb-icon vzb-icon-play\" viewBox=\"3 3 42 42\"\n           xmlns=\"http://www.w3.org/2000/svg\">\n        <path xmlns=\"http://www.w3.org/2000/svg\" d=\"M24 4C12.95 4 4 12.95 4 24s8.95 20 20 20 20-8.95 20-20S35.05 4 24 4zm-4 29V15l12 9-12 9z\"/>\n      </svg>\n    </button>\n    <button class=\"vzb-ts-btn-pause vzb-ts-btn\">\n      <svg class=\"vzb-icon vzb-icon-pause\" viewBox=\"3 3 42 42\"\n           xmlns=\"http://www.w3.org/2000/svg\">\n        <path xmlns=\"http://www.w3.org/2000/svg\" d=\"M24 4C12.95 4 4 12.95 4 24s8.95 20 20 20 20-8.95 20-20S35.05 4 24 4zm-2 28h-4V16h4v16zm8 0h-4V16h4v16z\"/>\n      </svg>\n    </button>\n  </div>\n</div>\n";

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

module.exports = "<!-- Bar Chart Component -->\n<svg class=\"vzb-agepyramid\">\n  <g class=\"vzb-bc-header\">\n    <text class=\"vzb-bc-title\"></text>\n    <text class=\"vzb-bc-title vzb-bc-title-right\"></text>\n    <text class=\"vzb-bc-year\"></text>\n  </g>\n  <g class=\"vzb-bc-graph\">\n\n    <text class=\"vzb-bc-axis-y-title\"></text>\n\n    <g class=\"vzb-bc-axis-y\"></g>\n\n    <svg class=\"vzb-bc-bars-crop\">\n      <g class=\"vzb-bc-bars\"></g>\n    </svg>\n\n    <g class=\"vzb-bc-axis-x\"></g>\n    <g class=\"vzb-bc-axis-x vzb-bc-axis-x-left\"></g>\n\n    <svg class=\"vzb-bc-labels-crop\">\n      <g class=\"vzb-bc-labels\"></g>        \n    </svg>\n\n    <g class=\"vzb-bc-axis-labels\">\n      <!-- <text class=\"vzb-x_label\">Lifespan</text>\n            <text class=\"vzb-y_label\">Lifespan</text> -->\n    </g>\n  </g>\n</svg>\n";

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

module.exports = "<!-- Axis Labeler Component -->\n<svg class=\"vzb-axislabeler\">\n  <g class=\"vzb-al-graph\">\n\n    <g class=\"vzb-al-axis-x\"></g>\n    <g class=\"vzb-al-axis-y\"></g>\n\n  </g>\n</svg>\n";

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

module.exports = "<!-- Bar Chart Component -->\n<svg class=\"vzb-barchart\">\n  <g class=\"vzb-bc-graph\">\n    <g class=\"vzb-bc-bars\"></g>\n    <g class=\"vzb-bc-bar-labels\"></g>\n\n    <g class=\"vzb-bc-axis-y-title\"></g>\n    <text class=\"vzb-bc-year\"></text>\n    <g class=\"vzb-bc-axis-x-title\"></g>\n\n    <g class=\"vzb-bc-axis-x\"></g>\n    <g class=\"vzb-bc-axis-y\"></g>\n\n    <g class=\"vzb-bc-axis-labels\">\n      <!-- <text class=\"vzb-x_label\">Lifespan</text>\n            <text class=\"vzb-y_label\">Lifespan</text> -->\n    </g>\n  </g>\n</svg>\n";

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

module.exports = "<!-- Bar Chart Component -->\n<div class=\"vzb-barrankchart\">\n  <svg class=\"vzb-br-header\">\n    <g class=\"vzb-br-title\">\n      <text></text>\n    </g>\n    <g class=\"vzb-br-total\">\n      <text></text>\n    </g>\n    <g class=\"vzb-br-axis-info vzb-noexport\"></g>\n  </svg>\n\n  <div class=\"vzb-br-barsviewport vzb-dialog-scrollable\">\n    <svg class=\"vzb-br-bars-svg\">\n      <g class=\"vzb-br-bars\"></g>\n    </svg>\n  </div>\n\n  <svg class=\"vzb-data-warning-svg\">\n    <g class=\"vzb-data-warning vzb-noexport\">\n      <svg></svg>\n      <text></text>\n    </g>\n  </svg>\n</div>\n";

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

module.exports = "<!-- Bubble Chart Component -->\n<div class=\"vzb-bubblechart\">\n  <svg class=\"vzb-bubblechart-svg vzb-export\">\n    <g class=\"vzb-bc-graph\">\n      <g class=\"vzb-bc-year\"></g>\n\n      <svg class=\"vzb-bc-axis-x\"><g></g></svg>\n      <svg class=\"vzb-bc-axis-y\"><g></g></svg>\n      <line class=\"vzb-bc-projection-x\"></line>\n      <line class=\"vzb-bc-projection-y\"></line>\n\n      <svg class=\"vzb-bc-bubbles-crop\">\n        <line class=\"vzb-bc-line-equal-xy vzb-invisible\"></line>\n        <rect class=\"vzb-bc-eventarea\"></rect>\n        <g class=\"vzb-bc-trails\"></g>\n        <g class=\"vzb-bc-bubbles\"></g>\n        <g class=\"vzb-bc-lines\"></g>\n        <g class=\"vzb-bc-bubble-crown vzb-hidden\">\n          <circle class=\"vzb-crown-glow\"></circle>\n          <circle class=\"vzb-crown\"></circle>\n        </g>        \n      </svg>        \n\n      <g class=\"vzb-bc-axis-y-title\"></g>\n      <g class=\"vzb-bc-axis-x-title\"></g>\n      <g class=\"vzb-bc-axis-s-title\"></g>\n      <g class=\"vzb-bc-axis-c-title\"></g>\n\n      <g class=\"vzb-bc-axis-y-info vzb-noexport\"></g>\n      <g class=\"vzb-bc-axis-x-info vzb-noexport\"></g>\n      \n      <svg class=\"vzb-bc-labels-crop\">\n        <g class=\"vzb-bc-labels\"></g>        \n      </svg>       \n\n      <g class=\"vzb-data-warning vzb-noexport\">\n        <svg></svg>\n        <text></text>\n      </g>\n\n      <rect class=\"vzb-bc-zoom-rect\"></rect>\n      <g class=\"vzb-bc-tooltip vzb-hidden\">\n        <rect class=\"vzb-tooltip-glow\"></rect>\n        <rect class=\"vzb-tooltip-border\"></rect>\n        <text class=\"vzb-tooltip-text\"></text>\n      </g>\n    </g>\n  </svg>\n  <!-- This could possibly be another component -->\n  <div class=\"vzb-tooltip vzb-hidden vzb-tooltip-mobile\"></div>\n</div>\n";

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

module.exports = "<!-- Bubble Map Chart Component -->\n<div class=\"vzb-bubblemap\">\n  <svg class=\"vzb-bmc-map-background vzb-export\">\n    <g class=\"vzb-bmc-map-graph\"></g>\n  </svg>\n  <svg class=\"vzb-bubblemap-svg vzb-export\">\n    <g class=\"vzb-bmc-graph\">\n      <g class=\"vzb-bmc-year\"></g>\n\n      <g class=\"vzb-bmc-lines\"></g>\n      <g class=\"vzb-bmc-bubbles\"></g>\n      <g class=\"vzb-bmc-bubble-labels\"></g>\n\n\n      <g class=\"vzb-bmc-axis-y-title\">\n          <text></text>\n      </g>\n        \n      <g class=\"vzb-bmc-axis-c-title\">\n          <text></text>\n      </g>\n\n      <g class=\"vzb-bmc-axis-y-info vzb-noexport\">\n      </g>\n\n      <g class=\"vzb-bmc-axis-c-info vzb-noexport\">\n      </g>\n\n      <g class=\"vzb-data-warning vzb-noexport\">\n        <svg></svg>\n        <text></text>\n      </g>\n      <g class=\"vzb-bmc-labels\"></g>\n\n      <g class=\"vzb-bmc-tooltip vzb-hidden\">\n        <rect class=\"vzb-tooltip-border\"></rect>\n        <text class=\"vzb-tooltip-text\"></text>\n      </g>\n    </g>\n  </svg>\n</div>\n";

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

module.exports = "<!-- Cartogram Component -->\n<div class=\"vzb-cartogram\">\n  \n  <svg class=\"vzb-cartogram-svg\">\n    <g class=\"vzb-ct-graph\">\n      <g class=\"vzb-ct-year\"></g>\n      <svg class=\"vzb-ct-map-background vzb-export\">\n        <g class=\"vzb-ct-map-graph\"></g>\n      </svg>\n      <svg class=\"vzb-ct-labels-crop\">\n        <g class=\"vzb-ct-labels\">\n          <line class=\"vzb-ct-vertical-now\"></line>\n        </g>\n      </svg>\n\n      <g class=\"vzb-ct-axis-y-title\"><text></text></g>\n      <g class=\"vzb-ct-axis-c-title\"><text></text></g>\n      <g class=\"vzb-ct-axis-y-info\"></g>\n      <g class=\"vzb-ct-axis-c-info\"></g>\n      <g class=\"vzb-ct-tooltip vzb-hidden\">\n        <rect class=\"vzb-tooltip-border\"></rect>\n        <text class=\"vzb-tooltip-text\"></text>\n\n      </g>\n\n      <g class=\"vzb-data-warning vzb-noexport\">\n        <svg></svg>\n        <text></text>\n      </g>\n    </g>\n  </svg>\n</div>\n";

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

module.exports = "<!-- Line Chart Component -->\n<div class=\"vzb-linechart\">\n  <svg class=\"vzb-linechart-svg\">\n    <g class=\"vzb-lc-graph\">\n\n      <svg class=\"vzb-lc-axis-x\"><g></g></svg>\n      <svg class=\"vzb-lc-axis-y\"><g></g></svg>\n      <text class=\"vzb-lc-axis-x-value\"></text>\n      <text class=\"vzb-lc-axis-y-value\"></text>\n      <svg class=\"vzb-lc-lines-crop\">\n        <svg class=\"vzb-lc-lines\"></svg>\n        <line class=\"vzb-lc-projection-x\"></line>\n        <line class=\"vzb-lc-projection-y\"></line>\n      </svg>\n      <svg class=\"vzb-lc-labels-crop\">\n        <g class=\"vzb-lc-labels\">\n          <line class=\"vzb-lc-vertical-now\"></line>\n        </g>\n      </svg>\n\n      <g class=\"vzb-lc-axis-y-title\"></g>\n      <g class=\"vzb-lc-axis-x-title\"></g>\n      <g class=\"vzb-lc-axis-y-info\"></g>\n\n      <g class=\"vzb-data-warning vzb-noexport\">\n        <svg></svg>\n        <text></text>\n      </g>\n\n      \n      <!--filter id=\"vzb-lc-filter-dropshadow\"> \n        <feOffset result=\"offOut\" in=\"SourceGraphic\" dx=\"0\" dy=\"2\" />\n        <feColorMatrix result = \"matrixOut\" in = \"offOut\" type = \"matrix\"\n                       values = \"0.3 .0 .0 .0 .0\n                                 .0 .3 .0 .0 .0\n                                 .0 .0 .3 .0 .0\n                                 1.0 1.0 1.0 1.0 .0\"/>\n        <feGaussianBlur result=\"blurOut\" in=\"matrixOut\" stdDeviation=\"0.8\" />\n        <feBlend in=\"SourceGraphic\" in2=\"blurOut\" mode=\"normal\" />\n      </filter-->\n\n    </g>\n  </svg>\n  <div class=\"vzb-tooltip vzb-hidden\"></div>\n</div>\n";

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

module.exports = "<!-- Mountain Chart Template -->\n<div class=\"vzb-mountainchart\">\n  <svg class=\"vzb-mountainchart-svg vzb-export\">\n        <g class=\"vzb-mc-graph\">\n            <rect class=\"vzb-mc-eventarea\"></rect>\n            <g class=\"vzb-mc-year\"></g>\n\n            <g class=\"vzb-mc-mountains-mergestacked\"></g>\n            <g class=\"vzb-mc-mountains-mergegrouped\"></g>\n            <g class=\"vzb-mc-mountains\"></g>\n            <g class=\"vzb-mc-mountains-labels\"></g>\n\n\n            <g class=\"vzb-mc-axis-y-title\">\n                <text></text>\n            </g>\n\n            <g class=\"vzb-mc-axis-x-title\">\n                <text></text>\n            </g>\n\n            <g class=\"vzb-mc-axis-info vzb-noexport\">\n            </g>\n\n            <g class=\"vzb-data-warning vzb-noexport\">\n                <svg></svg>\n                <text></text>\n            </g>\n\n            <g class=\"vzb-mc-axis-x\"></g>\n\n            <g class=\"vzb-mc-axis-labels\"></g>\n            <g class=\"vzb-mc-probe\">\n                <text class=\"vzb-shadow vzb-mc-probe-value-ul\"></text>\n                <text class=\"vzb-shadow vzb-mc-probe-value-ur\"></text>\n                <text class=\"vzb-shadow vzb-mc-probe-value-dl\"></text>\n                <text class=\"vzb-shadow vzb-mc-probe-value-dr\"></text>\n                <text class=\"vzb-mc-probe-value-ul\"></text>\n                <text class=\"vzb-mc-probe-value-ur\"></text>\n                <text class=\"vzb-mc-probe-value-dl\"></text>\n                <text class=\"vzb-mc-probe-value-dr\"></text>\n                <text class=\"vzb-mc-probe-extremepoverty\"></text>\n                <line></line>\n            </g>\n\n            <g class=\"vzb-mc-tooltip vzb-hidden\">\n                <rect class=\"vzb-tooltip-border\"></rect>\n                <text class=\"vzb-tooltip-text\"></text>\n            </g>\n        </g>\n  </svg>\n</div>\n";

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

// shim for using process in browser
var process = module.exports = {};

// cached from whatever global is present so that test runners that stub it
// don't break things.  But we need to wrap it in a try catch in case it is
// wrapped in strict mode code which doesn't define any globals.  It's inside a
// function because try/catches deoptimize in certain engines.

var cachedSetTimeout;
var cachedClearTimeout;

function defaultSetTimout() {
    throw new Error('setTimeout has not been defined');
}
function defaultClearTimeout () {
    throw new Error('clearTimeout has not been defined');
}
(function () {
    try {
        if (typeof setTimeout === 'function') {
            cachedSetTimeout = setTimeout;
        } else {
            cachedSetTimeout = defaultSetTimout;
        }
    } catch (e) {
        cachedSetTimeout = defaultSetTimout;
    }
    try {
        if (typeof clearTimeout === 'function') {
            cachedClearTimeout = clearTimeout;
        } else {
            cachedClearTimeout = defaultClearTimeout;
        }
    } catch (e) {
        cachedClearTimeout = defaultClearTimeout;
    }
} ())
function runTimeout(fun) {
    if (cachedSetTimeout === setTimeout) {
        //normal enviroments in sane situations
        return setTimeout(fun, 0);
    }
    // if setTimeout wasn't available but was latter defined
    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
        cachedSetTimeout = setTimeout;
        return setTimeout(fun, 0);
    }
    try {
        // when when somebody has screwed with setTimeout but no I.E. maddness
        return cachedSetTimeout(fun, 0);
    } catch(e){
        try {
            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
            return cachedSetTimeout.call(null, fun, 0);
        } catch(e){
            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
            return cachedSetTimeout.call(this, fun, 0);
        }
    }


}
function runClearTimeout(marker) {
    if (cachedClearTimeout === clearTimeout) {
        //normal enviroments in sane situations
        return clearTimeout(marker);
    }
    // if clearTimeout wasn't available but was latter defined
    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
        cachedClearTimeout = clearTimeout;
        return clearTimeout(marker);
    }
    try {
        // when when somebody has screwed with setTimeout but no I.E. maddness
        return cachedClearTimeout(marker);
    } catch (e){
        try {
            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
            return cachedClearTimeout.call(null, marker);
        } catch (e){
            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
            return cachedClearTimeout.call(this, marker);
        }
    }



}
var queue = [];
var draining = false;
var currentQueue;
var queueIndex = -1;

function cleanUpNextTick() {
    if (!draining || !currentQueue) {
        return;
    }
    draining = false;
    if (currentQueue.length) {
        queue = currentQueue.concat(queue);
    } else {
        queueIndex = -1;
    }
    if (queue.length) {
        drainQueue();
    }
}

function drainQueue() {
    if (draining) {
        return;
    }
    var timeout = runTimeout(cleanUpNextTick);
    draining = true;

    var len = queue.length;
    while(len) {
        currentQueue = queue;
        queue = [];
        while (++queueIndex < len) {
            if (currentQueue) {
                currentQueue[queueIndex].run();
            }
        }
        queueIndex = -1;
        len = queue.length;
    }
    currentQueue = null;
    draining = false;
    runClearTimeout(timeout);
}

process.nextTick = function (fun) {
    var args = new Array(arguments.length - 1);
    if (arguments.length > 1) {
        for (var i = 1; i < arguments.length; i++) {
            args[i - 1] = arguments[i];
        }
    }
    queue.push(new Item(fun, args));
    if (queue.length === 1 && !draining) {
        runTimeout(drainQueue);
    }
};

// v8 likes predictible objects
function Item(fun, array) {
    this.fun = fun;
    this.array = array;
}
Item.prototype.run = function () {
    this.fun.apply(null, this.array);
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};

function noop() {}

process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;

process.binding = function (name) {
    throw new Error('process.binding is not supported');
};

process.cwd = function () { return '/' };
process.chdir = function (dir) {
    throw new Error('process.chdir is not supported');
};
process.umask = function() { return 0; };


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

/* WEBPACK VAR INJECTION */(function(global, process) {/**
 * Copyright (c) 2014, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * https://raw.github.com/facebook/regenerator/master/LICENSE file. An
 * additional grant of patent rights can be found in the PATENTS file in
 * the same directory.
 */

!(function(global) {
  "use strict";

  var Op = Object.prototype;
  var hasOwn = Op.hasOwnProperty;
  var undefined; // More compressible than void 0.
  var $Symbol = typeof Symbol === "function" ? Symbol : {};
  var iteratorSymbol = $Symbol.iterator || "@@iterator";
  var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";

  var inModule = typeof module === "object";
  var runtime = global.regeneratorRuntime;
  if (runtime) {
    if (inModule) {
      // If regeneratorRuntime is defined globally and we're in a module,
      // make the exports object identical to regeneratorRuntime.
      module.exports = runtime;
    }
    // Don't bother evaluating the rest of this file if the runtime was
    // already defined globally.
    return;
  }

  // Define the runtime globally (as expected by generated code) as either
  // module.exports (if we're in a module) or a new, empty object.
  runtime = global.regeneratorRuntime = inModule ? module.exports : {};

  function wrap(innerFn, outerFn, self, tryLocsList) {
    // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.
    var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
    var generator = Object.create(protoGenerator.prototype);
    var context = new Context(tryLocsList || []);

    // The ._invoke method unifies the implementations of the .next,
    // .throw, and .return methods.
    generator._invoke = makeInvokeMethod(innerFn, self, context);

    return generator;
  }
  runtime.wrap = wrap;

  // Try/catch helper to minimize deoptimizations. Returns a completion
  // record like context.tryEntries[i].completion. This interface could
  // have been (and was previously) designed to take a closure to be
  // invoked without arguments, but in all the cases we care about we
  // already have an existing method we want to call, so there's no need
  // to create a new function object. We can even get away with assuming
  // the method takes exactly one argument, since that happens to be true
  // in every case, so we don't have to touch the arguments object. The
  // only additional allocation required is the completion record, which
  // has a stable shape and so hopefully should be cheap to allocate.
  function tryCatch(fn, obj, arg) {
    try {
      return { type: "normal", arg: fn.call(obj, arg) };
    } catch (err) {
      return { type: "throw", arg: err };
    }
  }

  var GenStateSuspendedStart = "suspendedStart";
  var GenStateSuspendedYield = "suspendedYield";
  var GenStateExecuting = "executing";
  var GenStateCompleted = "completed";

  // Returning this object from the innerFn has the same effect as
  // breaking out of the dispatch switch statement.
  var ContinueSentinel = {};

  // Dummy constructor functions that we use as the .constructor and
  // .constructor.prototype properties for functions that return Generator
  // objects. For full spec compliance, you may wish to configure your
  // minifier not to mangle the names of these two functions.
  function Generator() {}
  function GeneratorFunction() {}
  function GeneratorFunctionPrototype() {}

  // This is a polyfill for %IteratorPrototype% for environments that
  // don't natively support it.
  var IteratorPrototype = {};
  IteratorPrototype[iteratorSymbol] = function () {
    return this;
  };

  var getProto = Object.getPrototypeOf;
  var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
  if (NativeIteratorPrototype &&
      NativeIteratorPrototype !== Op &&
      hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
    // This environment has a native %IteratorPrototype%; use it instead
    // of the polyfill.
    IteratorPrototype = NativeIteratorPrototype;
  }

  var Gp = GeneratorFunctionPrototype.prototype =
    Generator.prototype = Object.create(IteratorPrototype);
  GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
  GeneratorFunctionPrototype.constructor = GeneratorFunction;
  GeneratorFunctionPrototype[toStringTagSymbol] =
    GeneratorFunction.displayName = "GeneratorFunction";

  // Helper for defining the .next, .throw, and .return methods of the
  // Iterator interface in terms of a single ._invoke method.
  function defineIteratorMethods(prototype) {
    ["next", "throw", "return"].forEach(function(method) {
      prototype[method] = function(arg) {
        return this._invoke(method, arg);
      };
    });
  }

  runtime.isGeneratorFunction = function(genFun) {
    var ctor = typeof genFun === "function" && genFun.constructor;
    return ctor
      ? ctor === GeneratorFunction ||
        // For the native GeneratorFunction constructor, the best we can
        // do is to check its .name property.
        (ctor.displayName || ctor.name) === "GeneratorFunction"
      : false;
  };

  runtime.mark = function(genFun) {
    if (Object.setPrototypeOf) {
      Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
    } else {
      genFun.__proto__ = GeneratorFunctionPrototype;
      if (!(toStringTagSymbol in genFun)) {
        genFun[toStringTagSymbol] = "GeneratorFunction";
      }
    }
    genFun.prototype = Object.create(Gp);
    return genFun;
  };

  // Within the body of any async function, `await x` is transformed to
  // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test
  // `hasOwn.call(value, "__await")` to determine if the yielded value is
  // meant to be awaited.
  runtime.awrap = function(arg) {
    return { __await: arg };
  };

  function AsyncIterator(generator) {
    function invoke(method, arg, resolve, reject) {
      var record = tryCatch(generator[method], generator, arg);
      if (record.type === "throw") {
        reject(record.arg);
      } else {
        var result = record.arg;
        var value = result.value;
        if (value &&
            typeof value === "object" &&
            hasOwn.call(value, "__await")) {
          return Promise.resolve(value.__await).then(function(value) {
            invoke("next", value, resolve, reject);
          }, function(err) {
            invoke("throw", err, resolve, reject);
          });
        }

        return Promise.resolve(value).then(function(unwrapped) {
          // When a yielded Promise is resolved, its final value becomes
          // the .value of the Promise<{value,done}> result for the
          // current iteration. If the Promise is rejected, however, the
          // result for this iteration will be rejected with the same
          // reason. Note that rejections of yielded Promises are not
          // thrown back into the generator function, as is the case
          // when an awaited Promise is rejected. This difference in
          // behavior between yield and await is important, because it
          // allows the consumer to decide what to do with the yielded
          // rejection (swallow it and continue, manually .throw it back
          // into the generator, abandon iteration, whatever). With
          // await, by contrast, there is no opportunity to examine the
          // rejection reason outside the generator function, so the
          // only option is to throw it from the await expression, and
          // let the generator function handle the exception.
          result.value = unwrapped;
          resolve(result);
        }, reject);
      }
    }

    if (typeof process === "object" && process.domain) {
      invoke = process.domain.bind(invoke);
    }

    var previousPromise;

    function enqueue(method, arg) {
      function callInvokeWithMethodAndArg() {
        return new Promise(function(resolve, reject) {
          invoke(method, arg, resolve, reject);
        });
      }

      return previousPromise =
        // If enqueue has been called before, then we want to wait until
        // all previous Promises have been resolved before calling invoke,
        // so that results are always delivered in the correct order. If
        // enqueue has not been called before, then it is important to
        // call invoke immediately, without waiting on a callback to fire,
        // so that the async generator function has the opportunity to do
        // any necessary setup in a predictable way. This predictability
        // is why the Promise constructor synchronously invokes its
        // executor callback, and why async functions synchronously
        // execute code before the first await. Since we implement simple
        // async functions in terms of async generators, it is especially
        // important to get this right, even though it requires care.
        previousPromise ? previousPromise.then(
          callInvokeWithMethodAndArg,
          // Avoid propagating failures to Promises returned by later
          // invocations of the iterator.
          callInvokeWithMethodAndArg
        ) : callInvokeWithMethodAndArg();
    }

    // Define the unified helper method that is used to implement .next,
    // .throw, and .return (see defineIteratorMethods).
    this._invoke = enqueue;
  }

  defineIteratorMethods(AsyncIterator.prototype);
  runtime.AsyncIterator = AsyncIterator;

  // Note that simple async functions are implemented on top of
  // AsyncIterator objects; they just return a Promise for the value of
  // the final result produced by the iterator.
  runtime.async = function(innerFn, outerFn, self, tryLocsList) {
    var iter = new AsyncIterator(
      wrap(innerFn, outerFn, self, tryLocsList)
    );

    return runtime.isGeneratorFunction(outerFn)
      ? iter // If outerFn is a generator, return the full iterator.
      : iter.next().then(function(result) {
          return result.done ? result.value : iter.next();
        });
  };

  function makeInvokeMethod(innerFn, self, context) {
    var state = GenStateSuspendedStart;

    return function invoke(method, arg) {
      if (state === GenStateExecuting) {
        throw new Error("Generator is already running");
      }

      if (state === GenStateCompleted) {
        if (method === "throw") {
          throw arg;
        }

        // Be forgiving, per 25.3.3.3.3 of the spec:
        // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume
        return doneResult();
      }

      while (true) {
        var delegate = context.delegate;
        if (delegate) {
          if (method === "return" ||
              (method === "throw" && delegate.iterator[method] === undefined)) {
            // A return or throw (when the delegate iterator has no throw
            // method) always terminates the yield* loop.
            context.delegate = null;

            // If the delegate iterator has a return method, give it a
            // chance to clean up.
            var returnMethod = delegate.iterator["return"];
            if (returnMethod) {
              var record = tryCatch(returnMethod, delegate.iterator, arg);
              if (record.type === "throw") {
                // If the return method threw an exception, let that
                // exception prevail over the original return or throw.
                method = "throw";
                arg = record.arg;
                continue;
              }
            }

            if (method === "return") {
              // Continue with the outer return, now that the delegate
              // iterator has been terminated.
              continue;
            }
          }

          var record = tryCatch(
            delegate.iterator[method],
            delegate.iterator,
            arg
          );

          if (record.type === "throw") {
            context.delegate = null;

            // Like returning generator.throw(uncaught), but without the
            // overhead of an extra function call.
            method = "throw";
            arg = record.arg;
            continue;
          }

          // Delegate generator ran and handled its own exceptions so
          // regardless of what the method was, we continue as if it is
          // "next" with an undefined arg.
          method = "next";
          arg = undefined;

          var info = record.arg;
          if (info.done) {
            context[delegate.resultName] = info.value;
            context.next = delegate.nextLoc;
          } else {
            state = GenStateSuspendedYield;
            return info;
          }

          context.delegate = null;
        }

        if (method === "next") {
          // Setting context._sent for legacy support of Babel's
          // function.sent implementation.
          context.sent = context._sent = arg;

        } else if (method === "throw") {
          if (state === GenStateSuspendedStart) {
            state = GenStateCompleted;
            throw arg;
          }

          if (context.dispatchException(arg)) {
            // If the dispatched exception was caught by a catch block,
            // then let that catch block handle the exception normally.
            method = "next";
            arg = undefined;
          }

        } else if (method === "return") {
          context.abrupt("return", arg);
        }

        state = GenStateExecuting;

        var record = tryCatch(innerFn, self, context);
        if (record.type === "normal") {
          // If an exception is thrown from innerFn, we leave state ===
          // GenStateExecuting and loop back for another invocation.
          state = context.done
            ? GenStateCompleted
            : GenStateSuspendedYield;

          var info = {
            value: record.arg,
            done: context.done
          };

          if (record.arg === ContinueSentinel) {
            if (context.delegate && method === "next") {
              // Deliberately forget the last sent value so that we don't
              // accidentally pass it on to the delegate.
              arg = undefined;
            }
          } else {
            return info;
          }

        } else if (record.type === "throw") {
          state = GenStateCompleted;
          // Dispatch the exception by looping back around to the
          // context.dispatchException(arg) call above.
          method = "throw";
          arg = record.arg;
        }
      }
    };
  }

  // Define Generator.prototype.{next,throw,return} in terms of the
  // unified ._invoke helper method.
  defineIteratorMethods(Gp);

  Gp[toStringTagSymbol] = "Generator";

  Gp.toString = function() {
    return "[object Generator]";
  };

  function pushTryEntry(locs) {
    var entry = { tryLoc: locs[0] };

    if (1 in locs) {
      entry.catchLoc = locs[1];
    }

    if (2 in locs) {
      entry.finallyLoc = locs[2];
      entry.afterLoc = locs[3];
    }

    this.tryEntries.push(entry);
  }

  function resetTryEntry(entry) {
    var record = entry.completion || {};
    record.type = "normal";
    delete record.arg;
    entry.completion = record;
  }

  function Context(tryLocsList) {
    // The root entry object (effectively a try statement without a catch
    // or a finally block) gives us a place to store values thrown from
    // locations where there is no enclosing try statement.
    this.tryEntries = [{ tryLoc: "root" }];
    tryLocsList.forEach(pushTryEntry, this);
    this.reset(true);
  }

  runtime.keys = function(object) {
    var keys = [];
    for (var key in object) {
      keys.push(key);
    }
    keys.reverse();

    // Rather than returning an object with a next method, we keep
    // things simple and return the next function itself.
    return function next() {
      while (keys.length) {
        var key = keys.pop();
        if (key in object) {
          next.value = key;
          next.done = false;
          return next;
        }
      }

      // To avoid creating an additional object, we just hang the .value
      // and .done properties off the next function object itself. This
      // also ensures that the minifier will not anonymize the function.
      next.done = true;
      return next;
    };
  };

  function values(iterable) {
    if (iterable) {
      var iteratorMethod = iterable[iteratorSymbol];
      if (iteratorMethod) {
        return iteratorMethod.call(iterable);
      }

      if (typeof iterable.next === "function") {
        return iterable;
      }

      if (!isNaN(iterable.length)) {
        var i = -1, next = function next() {
          while (++i < iterable.length) {
            if (hasOwn.call(iterable, i)) {
              next.value = iterable[i];
              next.done = false;
              return next;
            }
          }

          next.value = undefined;
          next.done = true;

          return next;
        };

        return next.next = next;
      }
    }

    // Return an iterator with no values.
    return { next: doneResult };
  }
  runtime.values = values;

  function doneResult() {
    return { value: undefined, done: true };
  }

  Context.prototype = {
    constructor: Context,

    reset: function(skipTempReset) {
      this.prev = 0;
      this.next = 0;
      // Resetting context._sent for legacy support of Babel's
      // function.sent implementation.
      this.sent = this._sent = undefined;
      this.done = false;
      this.delegate = null;

      this.tryEntries.forEach(resetTryEntry);

      if (!skipTempReset) {
        for (var name in this) {
          // Not sure about the optimal order of these conditions:
          if (name.charAt(0) === "t" &&
              hasOwn.call(this, name) &&
              !isNaN(+name.slice(1))) {
            this[name] = undefined;
          }
        }
      }
    },

    stop: function() {
      this.done = true;

      var rootEntry = this.tryEntries[0];
      var rootRecord = rootEntry.completion;
      if (rootRecord.type === "throw") {
        throw rootRecord.arg;
      }

      return this.rval;
    },

    dispatchException: function(exception) {
      if (this.done) {
        throw exception;
      }

      var context = this;
      function handle(loc, caught) {
        record.type = "throw";
        record.arg = exception;
        context.next = loc;
        return !!caught;
      }

      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        var record = entry.completion;

        if (entry.tryLoc === "root") {
          // Exception thrown outside of any try block that could handle
          // it, so set the completion value of the entire function to
          // throw the exception.
          return handle("end");
        }

        if (entry.tryLoc <= this.prev) {
          var hasCatch = hasOwn.call(entry, "catchLoc");
          var hasFinally = hasOwn.call(entry, "finallyLoc");

          if (hasCatch && hasFinally) {
            if (this.prev < entry.catchLoc) {
              return handle(entry.catchLoc, true);
            } else if (this.prev < entry.finallyLoc) {
              return handle(entry.finallyLoc);
            }

          } else if (hasCatch) {
            if (this.prev < entry.catchLoc) {
              return handle(entry.catchLoc, true);
            }

          } else if (hasFinally) {
            if (this.prev < entry.finallyLoc) {
              return handle(entry.finallyLoc);
            }

          } else {
            throw new Error("try statement without catch or finally");
          }
        }
      }
    },

    abrupt: function(type, arg) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        if (entry.tryLoc <= this.prev &&
            hasOwn.call(entry, "finallyLoc") &&
            this.prev < entry.finallyLoc) {
          var finallyEntry = entry;
          break;
        }
      }

      if (finallyEntry &&
          (type === "break" ||
           type === "continue") &&
          finallyEntry.tryLoc <= arg &&
          arg <= finallyEntry.finallyLoc) {
        // Ignore the finally entry if control is not jumping to a
        // location outside the try/catch block.
        finallyEntry = null;
      }

      var record = finallyEntry ? finallyEntry.completion : {};
      record.type = type;
      record.arg = arg;

      if (finallyEntry) {
        this.next = finallyEntry.finallyLoc;
      } else {
        this.complete(record);
      }

      return ContinueSentinel;
    },

    complete: function(record, afterLoc) {
      if (record.type === "throw") {
        throw record.arg;
      }

      if (record.type === "break" ||
          record.type === "continue") {
        this.next = record.arg;
      } else if (record.type === "return") {
        this.rval = record.arg;
        this.next = "end";
      } else if (record.type === "normal" && afterLoc) {
        this.next = afterLoc;
      }
    },

    finish: function(finallyLoc) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        if (entry.finallyLoc === finallyLoc) {
          this.complete(entry.completion, entry.afterLoc);
          resetTryEntry(entry);
          return ContinueSentinel;
        }
      }
    },

    "catch": function(tryLoc) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        if (entry.tryLoc === tryLoc) {
          var record = entry.completion;
          if (record.type === "throw") {
            var thrown = record.arg;
            resetTryEntry(entry);
          }
          return thrown;
        }
      }

      // The context.catch method must only be called with a location
      // argument that corresponds to a known catch block.
      throw new Error("illegal catch attempt");
    },

    delegateYield: function(iterable, resultName, nextLoc) {
      this.delegate = {
        iterator: values(iterable),
        resultName: resultName,
        nextLoc: nextLoc
      };

      return ContinueSentinel;
    }
  };
})(
  // Among the various tricks for obtaining a reference to the global
  // object, this seems to be the most reliable technique that does not
  // use indirect eval (which violates Content Security Policy).
  typeof global === "object" ? global :
  typeof window === "object" ? window :
  typeof self === "object" ? self : this
);

/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(179), __webpack_require__(451)))

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

/*
 * A collection of interpolators
 * @param {Number} x1, x2, y1, y2 - boundary points
 * @param {Number} x - point of interpolation
 * @return {Number} y - interpolated value
 */
//
module.exports = {
    linear: function(x1, x2, y1, y2, x) {
      return +y1 + (x - x1) / (x2 - x1) * (y2 - y1);
    },
    exp: function(x1, x2, y1, y2, x) {
      return Math.exp((Math.log(y1) * (x2 - x) - Math.log(y2) * (x1 - x)) / (x2 - x1));
    },
    stepBefore: function(x1, x2, y1, y2, x) {
        return y2;
    },
    stepAfter: function(x1, x2, y1, y2, x) {
        return y1;
    },
    stepMiddle: function(x1, x2, y1, y2, x) {
        return (x < (x1 + x2)/2) ? y1 : y2;
    }
};


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

var map = {
	"./bubblesize/bubblesize.js": 83,
	"./buttonlist/buttonlist.js": 22,
	"./buttonlist/optionsbuttonlist/optionsbuttonlist.js": 115,
	"./colorlegend/colorlegend.js": 84,
	"./datanotes/datanotes.js": 38,
	"./datawarning/datawarning.js": 39,
	"./dialogs/_dialog.js": 11,
	"./dialogs/about/about.js": 116,
	"./dialogs/axes/axes.js": 117,
	"./dialogs/axesmc/axesmc.js": 118,
	"./dialogs/colors/colors.js": 119,
	"./dialogs/dialogs.js": 23,
	"./dialogs/find/find.js": 120,
	"./dialogs/label/label.js": 121,
	"./dialogs/moreoptions/moreoptions.js": 122,
	"./dialogs/opacity/opacity.js": 123,
	"./dialogs/presentation/presentation.js": 124,
	"./dialogs/show/show.js": 125,
	"./dialogs/side/side.js": 126,
	"./dialogs/size/size.js": 127,
	"./dialogs/speed/speed.js": 128,
	"./dialogs/stack/stack.js": 129,
	"./dialogs/timedisplay/timedisplay.js": 130,
	"./dialogs/zoom/zoom.js": 131,
	"./draggablelist/draggablelist.js": 132,
	"./indicatorpicker/indicatorpicker.js": 47,
	"./minmaxinputs/minmaxinputs.js": 85,
	"./simplecheckbox/simplecheckbox.js": 58,
	"./simpleslider/simpleslider.js": 65,
	"./sizeslider/sizeslider.js": 133,
	"./timeslider/timeslider.js": 24,
	"./treemenu/treemenu.js": 27,
	"./zoombuttonlist/zoombuttonlist.js": 134
};
function webpackContext(req) {
	return __webpack_require__(webpackContextResolve(req));
};
function webpackContextResolve(req) {
	var id = map[req];
	if(!(id + 1)) // check for number
		throw new Error("Cannot find module '" + req + "'.");
	return id;
};
webpackContext.keys = function webpackContextKeys() {
	return Object.keys(map);
};
webpackContext.resolve = webpackContextResolve;
module.exports = webpackContext;
webpackContext.id = 454;


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

var map = {
	"./about/about.html": 423,
	"./axes/axes.html": 424,
	"./axesmc/axesmc.html": 425,
	"./colors/colors.html": 426,
	"./find/find.html": 427,
	"./label/label.html": 428,
	"./moreoptions/moreoptions.html": 429,
	"./opacity/opacity.html": 430,
	"./presentation/presentation.html": 431,
	"./show/show.html": 432,
	"./side/side.html": 433,
	"./size/size.html": 434,
	"./speed/speed.html": 435,
	"./stack/stack.html": 436,
	"./timedisplay/timedisplay.html": 437,
	"./zoom/zoom.html": 438
};
function webpackContext(req) {
	return __webpack_require__(webpackContextResolve(req));
};
function webpackContextResolve(req) {
	var id = map[req];
	if(!(id + 1)) // check for number
		throw new Error("Cannot find module '" + req + "'.");
	return id;
};
webpackContext.keys = function webpackContextKeys() {
	return Object.keys(map);
};
webpackContext.resolve = webpackContextResolve;
module.exports = webpackContext;
webpackContext.id = 455;


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

var map = {
	"./_dialog.js": 11,
	"./about/about.js": 116,
	"./axes/axes.js": 117,
	"./axesmc/axesmc.js": 118,
	"./colors/colors.js": 119,
	"./dialogs.js": 23,
	"./find/find.js": 120,
	"./label/label.js": 121,
	"./moreoptions/moreoptions.js": 122,
	"./opacity/opacity.js": 123,
	"./presentation/presentation.js": 124,
	"./show/show.js": 125,
	"./side/side.js": 126,
	"./size/size.js": 127,
	"./speed/speed.js": 128,
	"./stack/stack.js": 129,
	"./timedisplay/timedisplay.js": 130,
	"./zoom/zoom.js": 131
};
function webpackContext(req) {
	return __webpack_require__(webpackContextResolve(req));
};
function webpackContextResolve(req) {
	var id = map[req];
	if(!(id + 1)) // check for number
		throw new Error("Cannot find module '" + req + "'.");
	return id;
};
webpackContext.keys = function webpackContextKeys() {
	return Object.keys(map);
};
webpackContext.resolve = webpackContextResolve;
module.exports = webpackContext;
webpackContext.id = 456;


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

var map = {
	"./axis": 87,
	"./axis.js": 87,
	"./color": 137,
	"./color.js": 137,
	"./data": 138,
	"./data.js": 138,
	"./dataconnected": 59,
	"./dataconnected.js": 59,
	"./entities": 139,
	"./entities.js": 139,
	"./group": 140,
	"./group.js": 140,
	"./hook": 48,
	"./hook.js": 48,
	"./label": 141,
	"./label.js": 141,
	"./locale": 142,
	"./locale.js": 142,
	"./marker": 143,
	"./marker.js": 143,
	"./size": 144,
	"./size.js": 144,
	"./stack": 145,
	"./stack.js": 145,
	"./time": 146,
	"./time.js": 146,
	"./ui": 147,
	"./ui.js": 147
};
function webpackContext(req) {
	return __webpack_require__(webpackContextResolve(req));
};
function webpackContextResolve(req) {
	var id = map[req];
	if(!(id + 1)) // check for number
		throw new Error("Cannot find module '" + req + "'.");
	return id;
};
webpackContext.keys = function webpackContextKeys() {
	return Object.keys(map);
};
webpackContext.resolve = webpackContextResolve;
module.exports = webpackContext;
webpackContext.id = 457;


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

var map = {
	"./csv-time_in_columns/csv-time_in_columns.js": 214,
	"./csv/csv.js": 148,
	"./inline/inline.js": 215
};
function webpackContext(req) {
	return __webpack_require__(webpackContextResolve(req));
};
function webpackContextResolve(req) {
	var id = map[req];
	if(!(id + 1)) // check for number
		throw new Error("Cannot find module '" + req + "'.");
	return id;
};
webpackContext.keys = function webpackContextKeys() {
	return Object.keys(map);
};
webpackContext.resolve = webpackContextResolve;
module.exports = webpackContext;
webpackContext.id = 458;


/***/ },
/* 459 */,
/* 460 */
/***/ function(module, exports, __webpack_require__) {

"use strict";
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

__webpack_require__(193);

var _globals = __webpack_require__(44);

var _globals2 = _interopRequireDefault(_globals);

var _utils = __webpack_require__(1);

var utils = _interopRequireWildcard(_utils);

var _tool = __webpack_require__(14);

var _tool2 = _interopRequireDefault(_tool);

var _vizabi = __webpack_require__(192);

var _vizabi2 = _interopRequireDefault(_vizabi);

__webpack_require__(194);

var _requireAll = __webpack_require__(70);

var _requireAll2 = _interopRequireDefault(_requireAll);

var _bubblechart = __webpack_require__(184);

var _bubblechart2 = _interopRequireDefault(_bubblechart);

var _barrankchart = __webpack_require__(183);

var _barrankchart2 = _interopRequireDefault(_barrankchart);

var _mountainchart = __webpack_require__(191);

var _mountainchart2 = _interopRequireDefault(_mountainchart);

var _barchart = __webpack_require__(182);

var _barchart2 = _interopRequireDefault(_barchart);

var _bubblemap = __webpack_require__(185);

var _bubblemap2 = _interopRequireDefault(_bubblemap);

var _linechart = __webpack_require__(190);

var _linechart2 = _interopRequireDefault(_linechart);

var _donutchart = __webpack_require__(187);

var _donutchart2 = _interopRequireDefault(_donutchart);

var _cartogram = __webpack_require__(186);

var _cartogram2 = _interopRequireDefault(_cartogram);

var _axislabeler = __webpack_require__(181);

var _axislabeler2 = _interopRequireDefault(_axislabeler);

var _agepyramid = __webpack_require__(180);

var _agepyramid2 = _interopRequireDefault(_agepyramid);

var _joint_pyramidline = __webpack_require__(189);

var _joint_pyramidline2 = _interopRequireDefault(_joint_pyramidline);

var _joint_cartogramline = __webpack_require__(188);

var _joint_cartogramline2 = _interopRequireDefault(_joint_cartogramline);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

// Fallback in case if WS is not available - requesting data from local files


//import tools
var locationArray = window.location.href.split("/"); /*!
                                                      * VIZABI GAPMINDER PREFERENCES (included only in Gapminder build)
                                                      */

var localUrl = locationArray.splice(0, locationArray.indexOf("preview")).join("/") + "/preview/";

_globals2.default.ext_resources = utils.deepExtend({
  host: localUrl,
  preloadPath: 'data/',
  dataPath: 'data/waffles/'
}, _globals2.default.ext_resources);

exports.default = _vizabi2.default;

module.exports = _vizabi2.default;

/***/ }
/******/ ])
});
;