From 6cde052a46e35d73bb65092e1e86bff80155a9c3 Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 27 Mar 2020 13:54:43 +0100 Subject: [PATCH] Update mermaid --- .jshintignore | 2 +- www/code/mermaid-new.css | 4 + www/code/mermaid.js | 59134 ---------------------------------- www/code/mermaid.min.js | 56 + www/common/diffMarked.js | 3 +- www/common/requireconfig.js | 1 + 6 files changed, 64 insertions(+), 59136 deletions(-) create mode 100644 www/code/mermaid-new.css delete mode 100644 www/code/mermaid.js create mode 100644 www/code/mermaid.min.js diff --git a/.jshintignore b/.jshintignore index a403739b4..3d249cde2 100644 --- a/.jshintignore +++ b/.jshintignore @@ -34,4 +34,4 @@ customize/ www/debug/chainpad.dist.js www/pad/mathjax/ -www/code/mermaid.js +www/code/mermaid*.js diff --git a/www/code/mermaid-new.css b/www/code/mermaid-new.css new file mode 100644 index 000000000..a6384cfba --- /dev/null +++ b/www/code/mermaid-new.css @@ -0,0 +1,4 @@ +.sectionTitle, .titleText { + font-weight: bold; +} + diff --git a/www/code/mermaid.js b/www/code/mermaid.js deleted file mode 100644 index 104bb7f82..000000000 --- a/www/code/mermaid.js +++ /dev/null @@ -1,59134 +0,0 @@ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.mermaid=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o b ? 1 : a >= b ? 0 : NaN; - } - d3.descending = function(a, b) { - return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN; - }; - d3.min = function(array, f) { - var i = -1, n = array.length, a, b; - if (arguments.length === 1) { - while (++i < n) if ((b = array[i]) != null && b >= b) { - a = b; - break; - } - while (++i < n) if ((b = array[i]) != null && a > b) a = b; - } else { - while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) { - a = b; - break; - } - while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b; - } - return a; - }; - d3.max = function(array, f) { - var i = -1, n = array.length, a, b; - if (arguments.length === 1) { - while (++i < n) if ((b = array[i]) != null && b >= b) { - a = b; - break; - } - while (++i < n) if ((b = array[i]) != null && b > a) a = b; - } else { - while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) { - a = b; - break; - } - while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b; - } - return a; - }; - d3.extent = function(array, f) { - var i = -1, n = array.length, a, b, c; - if (arguments.length === 1) { - while (++i < n) if ((b = array[i]) != null && b >= b) { - a = c = b; - break; - } - while (++i < n) if ((b = array[i]) != null) { - if (a > b) a = b; - if (c < b) c = b; - } - } else { - while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) { - a = c = b; - break; - } - while (++i < n) if ((b = f.call(array, array[i], i)) != null) { - if (a > b) a = b; - if (c < b) c = b; - } - } - return [ a, c ]; - }; - function d3_number(x) { - return x === null ? NaN : +x; - } - function d3_numeric(x) { - return !isNaN(x); - } - d3.sum = function(array, f) { - var s = 0, n = array.length, a, i = -1; - if (arguments.length === 1) { - while (++i < n) if (d3_numeric(a = +array[i])) s += a; - } else { - while (++i < n) if (d3_numeric(a = +f.call(array, array[i], i))) s += a; - } - return s; - }; - d3.mean = function(array, f) { - var s = 0, n = array.length, a, i = -1, j = n; - if (arguments.length === 1) { - while (++i < n) if (d3_numeric(a = d3_number(array[i]))) s += a; else --j; - } else { - while (++i < n) if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) s += a; else --j; - } - if (j) return s / j; - }; - d3.quantile = function(values, p) { - var H = (values.length - 1) * p + 1, h = Math.floor(H), v = +values[h - 1], e = H - h; - return e ? v + e * (values[h] - v) : v; - }; - d3.median = function(array, f) { - var numbers = [], n = array.length, a, i = -1; - if (arguments.length === 1) { - while (++i < n) if (d3_numeric(a = d3_number(array[i]))) numbers.push(a); - } else { - while (++i < n) if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) numbers.push(a); - } - if (numbers.length) return d3.quantile(numbers.sort(d3_ascending), .5); - }; - d3.variance = function(array, f) { - var n = array.length, m = 0, a, d, s = 0, i = -1, j = 0; - if (arguments.length === 1) { - while (++i < n) { - if (d3_numeric(a = d3_number(array[i]))) { - d = a - m; - m += d / ++j; - s += d * (a - m); - } - } - } else { - while (++i < n) { - if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) { - d = a - m; - m += d / ++j; - s += d * (a - m); - } - } - } - if (j > 1) return s / (j - 1); - }; - d3.deviation = function() { - var v = d3.variance.apply(this, arguments); - return v ? Math.sqrt(v) : v; - }; - function d3_bisector(compare) { - return { - left: function(a, x, lo, hi) { - if (arguments.length < 3) lo = 0; - if (arguments.length < 4) hi = a.length; - while (lo < hi) { - var mid = lo + hi >>> 1; - if (compare(a[mid], x) < 0) lo = mid + 1; else hi = mid; - } - return lo; - }, - right: function(a, x, lo, hi) { - if (arguments.length < 3) lo = 0; - if (arguments.length < 4) hi = a.length; - while (lo < hi) { - var mid = lo + hi >>> 1; - if (compare(a[mid], x) > 0) hi = mid; else lo = mid + 1; - } - return lo; - } - }; - } - var d3_bisect = d3_bisector(d3_ascending); - d3.bisectLeft = d3_bisect.left; - d3.bisect = d3.bisectRight = d3_bisect.right; - d3.bisector = function(f) { - return d3_bisector(f.length === 1 ? function(d, x) { - return d3_ascending(f(d), x); - } : f); - }; - d3.shuffle = function(array, i0, i1) { - if ((m = arguments.length) < 3) { - i1 = array.length; - if (m < 2) i0 = 0; - } - var m = i1 - i0, t, i; - while (m) { - i = Math.random() * m-- | 0; - t = array[m + i0], array[m + i0] = array[i + i0], array[i + i0] = t; - } - return array; - }; - d3.permute = function(array, indexes) { - var i = indexes.length, permutes = new Array(i); - while (i--) permutes[i] = array[indexes[i]]; - return permutes; - }; - d3.pairs = function(array) { - var i = 0, n = array.length - 1, p0, p1 = array[0], pairs = new Array(n < 0 ? 0 : n); - while (i < n) pairs[i] = [ p0 = p1, p1 = array[++i] ]; - return pairs; - }; - d3.zip = function() { - if (!(n = arguments.length)) return []; - for (var i = -1, m = d3.min(arguments, d3_zipLength), zips = new Array(m); ++i < m; ) { - for (var j = -1, n, zip = zips[i] = new Array(n); ++j < n; ) { - zip[j] = arguments[j][i]; - } - } - return zips; - }; - function d3_zipLength(d) { - return d.length; - } - d3.transpose = function(matrix) { - return d3.zip.apply(d3, matrix); - }; - d3.keys = function(map) { - var keys = []; - for (var key in map) keys.push(key); - return keys; - }; - d3.values = function(map) { - var values = []; - for (var key in map) values.push(map[key]); - return values; - }; - d3.entries = function(map) { - var entries = []; - for (var key in map) entries.push({ - key: key, - value: map[key] - }); - return entries; - }; - d3.merge = function(arrays) { - var n = arrays.length, m, i = -1, j = 0, merged, array; - while (++i < n) j += arrays[i].length; - merged = new Array(j); - while (--n >= 0) { - array = arrays[n]; - m = array.length; - while (--m >= 0) { - merged[--j] = array[m]; - } - } - return merged; - }; - var abs = Math.abs; - d3.range = function(start, stop, step) { - if (arguments.length < 3) { - step = 1; - if (arguments.length < 2) { - stop = start; - start = 0; - } - } - if ((stop - start) / step === Infinity) throw new Error("infinite range"); - var range = [], k = d3_range_integerScale(abs(step)), i = -1, j; - start *= k, stop *= k, step *= k; - if (step < 0) while ((j = start + step * ++i) > stop) range.push(j / k); else while ((j = start + step * ++i) < stop) range.push(j / k); - return range; - }; - function d3_range_integerScale(x) { - var k = 1; - while (x * k % 1) k *= 10; - return k; - } - function d3_class(ctor, properties) { - for (var key in properties) { - Object.defineProperty(ctor.prototype, key, { - value: properties[key], - enumerable: false - }); - } - } - d3.map = function(object, f) { - var map = new d3_Map(); - if (object instanceof d3_Map) { - object.forEach(function(key, value) { - map.set(key, value); - }); - } else if (Array.isArray(object)) { - var i = -1, n = object.length, o; - if (arguments.length === 1) while (++i < n) map.set(i, object[i]); else while (++i < n) map.set(f.call(object, o = object[i], i), o); - } else { - for (var key in object) map.set(key, object[key]); - } - return map; - }; - function d3_Map() { - this._ = Object.create(null); - } - var d3_map_proto = "__proto__", d3_map_zero = "\x00"; - d3_class(d3_Map, { - has: d3_map_has, - get: function(key) { - return this._[d3_map_escape(key)]; - }, - set: function(key, value) { - return this._[d3_map_escape(key)] = value; - }, - remove: d3_map_remove, - keys: d3_map_keys, - values: function() { - var values = []; - for (var key in this._) values.push(this._[key]); - return values; - }, - entries: function() { - var entries = []; - for (var key in this._) entries.push({ - key: d3_map_unescape(key), - value: this._[key] - }); - return entries; - }, - size: d3_map_size, - empty: d3_map_empty, - forEach: function(f) { - for (var key in this._) f.call(this, d3_map_unescape(key), this._[key]); - } - }); - function d3_map_escape(key) { - return (key += "") === d3_map_proto || key[0] === d3_map_zero ? d3_map_zero + key : key; - } - function d3_map_unescape(key) { - return (key += "")[0] === d3_map_zero ? key.slice(1) : key; - } - function d3_map_has(key) { - return d3_map_escape(key) in this._; - } - function d3_map_remove(key) { - return (key = d3_map_escape(key)) in this._ && delete this._[key]; - } - function d3_map_keys() { - var keys = []; - for (var key in this._) keys.push(d3_map_unescape(key)); - return keys; - } - function d3_map_size() { - var size = 0; - for (var key in this._) ++size; - return size; - } - function d3_map_empty() { - for (var key in this._) return false; - return true; - } - d3.nest = function() { - var nest = {}, keys = [], sortKeys = [], sortValues, rollup; - function map(mapType, array, depth) { - if (depth >= keys.length) return rollup ? rollup.call(nest, array) : sortValues ? array.sort(sortValues) : array; - var i = -1, n = array.length, key = keys[depth++], keyValue, object, setter, valuesByKey = new d3_Map(), values; - while (++i < n) { - if (values = valuesByKey.get(keyValue = key(object = array[i]))) { - values.push(object); - } else { - valuesByKey.set(keyValue, [ object ]); - } - } - if (mapType) { - object = mapType(); - setter = function(keyValue, values) { - object.set(keyValue, map(mapType, values, depth)); - }; - } else { - object = {}; - setter = function(keyValue, values) { - object[keyValue] = map(mapType, values, depth); - }; - } - valuesByKey.forEach(setter); - return object; - } - function entries(map, depth) { - if (depth >= keys.length) return map; - var array = [], sortKey = sortKeys[depth++]; - map.forEach(function(key, keyMap) { - array.push({ - key: key, - values: entries(keyMap, depth) - }); - }); - return sortKey ? array.sort(function(a, b) { - return sortKey(a.key, b.key); - }) : array; - } - nest.map = function(array, mapType) { - return map(mapType, array, 0); - }; - nest.entries = function(array) { - return entries(map(d3.map, array, 0), 0); - }; - nest.key = function(d) { - keys.push(d); - return nest; - }; - nest.sortKeys = function(order) { - sortKeys[keys.length - 1] = order; - return nest; - }; - nest.sortValues = function(order) { - sortValues = order; - return nest; - }; - nest.rollup = function(f) { - rollup = f; - return nest; - }; - return nest; - }; - d3.set = function(array) { - var set = new d3_Set(); - if (array) for (var i = 0, n = array.length; i < n; ++i) set.add(array[i]); - return set; - }; - function d3_Set() { - this._ = Object.create(null); - } - d3_class(d3_Set, { - has: d3_map_has, - add: function(key) { - this._[d3_map_escape(key += "")] = true; - return key; - }, - remove: d3_map_remove, - values: d3_map_keys, - size: d3_map_size, - empty: d3_map_empty, - forEach: function(f) { - for (var key in this._) f.call(this, d3_map_unescape(key)); - } - }); - d3.behavior = {}; - function d3_identity(d) { - return d; - } - d3.rebind = function(target, source) { - var i = 1, n = arguments.length, method; - while (++i < n) target[method = arguments[i]] = d3_rebind(target, source, source[method]); - return target; - }; - function d3_rebind(target, source, method) { - return function() { - var value = method.apply(source, arguments); - return value === source ? target : value; - }; - } - function d3_vendorSymbol(object, name) { - if (name in object) return name; - name = name.charAt(0).toUpperCase() + name.slice(1); - for (var i = 0, n = d3_vendorPrefixes.length; i < n; ++i) { - var prefixName = d3_vendorPrefixes[i] + name; - if (prefixName in object) return prefixName; - } - } - var d3_vendorPrefixes = [ "webkit", "ms", "moz", "Moz", "o", "O" ]; - function d3_noop() {} - d3.dispatch = function() { - var dispatch = new d3_dispatch(), i = -1, n = arguments.length; - while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); - return dispatch; - }; - function d3_dispatch() {} - d3_dispatch.prototype.on = function(type, listener) { - var i = type.indexOf("."), name = ""; - if (i >= 0) { - name = type.slice(i + 1); - type = type.slice(0, i); - } - if (type) return arguments.length < 2 ? this[type].on(name) : this[type].on(name, listener); - if (arguments.length === 2) { - if (listener == null) for (type in this) { - if (this.hasOwnProperty(type)) this[type].on(name, null); - } - return this; - } - }; - function d3_dispatch_event(dispatch) { - var listeners = [], listenerByName = new d3_Map(); - function event() { - var z = listeners, i = -1, n = z.length, l; - while (++i < n) if (l = z[i].on) l.apply(this, arguments); - return dispatch; - } - event.on = function(name, listener) { - var l = listenerByName.get(name), i; - if (arguments.length < 2) return l && l.on; - if (l) { - l.on = null; - listeners = listeners.slice(0, i = listeners.indexOf(l)).concat(listeners.slice(i + 1)); - listenerByName.remove(name); - } - if (listener) listeners.push(listenerByName.set(name, { - on: listener - })); - return dispatch; - }; - return event; - } - d3.event = null; - function d3_eventPreventDefault() { - d3.event.preventDefault(); - } - function d3_eventSource() { - var e = d3.event, s; - while (s = e.sourceEvent) e = s; - return e; - } - function d3_eventDispatch(target) { - var dispatch = new d3_dispatch(), i = 0, n = arguments.length; - while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); - dispatch.of = function(thiz, argumentz) { - return function(e1) { - try { - var e0 = e1.sourceEvent = d3.event; - e1.target = target; - d3.event = e1; - dispatch[e1.type].apply(thiz, argumentz); - } finally { - d3.event = e0; - } - }; - }; - return dispatch; - } - d3.requote = function(s) { - return s.replace(d3_requote_re, "\\$&"); - }; - var d3_requote_re = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g; - var d3_subclass = {}.__proto__ ? function(object, prototype) { - object.__proto__ = prototype; - } : function(object, prototype) { - for (var property in prototype) object[property] = prototype[property]; - }; - function d3_selection(groups) { - d3_subclass(groups, d3_selectionPrototype); - return groups; - } - var d3_select = function(s, n) { - return n.querySelector(s); - }, d3_selectAll = function(s, n) { - return n.querySelectorAll(s); - }, d3_selectMatches = function(n, s) { - var d3_selectMatcher = n.matches || n[d3_vendorSymbol(n, "matchesSelector")]; - d3_selectMatches = function(n, s) { - return d3_selectMatcher.call(n, s); - }; - return d3_selectMatches(n, s); - }; - if (typeof Sizzle === "function") { - d3_select = function(s, n) { - return Sizzle(s, n)[0] || null; - }; - d3_selectAll = Sizzle; - d3_selectMatches = Sizzle.matchesSelector; - } - d3.selection = function() { - return d3.select(d3_document.documentElement); - }; - var d3_selectionPrototype = d3.selection.prototype = []; - d3_selectionPrototype.select = function(selector) { - var subgroups = [], subgroup, subnode, group, node; - selector = d3_selection_selector(selector); - for (var j = -1, m = this.length; ++j < m; ) { - subgroups.push(subgroup = []); - subgroup.parentNode = (group = this[j]).parentNode; - for (var i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) { - subgroup.push(subnode = selector.call(node, node.__data__, i, j)); - if (subnode && "__data__" in node) subnode.__data__ = node.__data__; - } else { - subgroup.push(null); - } - } - } - return d3_selection(subgroups); - }; - function d3_selection_selector(selector) { - return typeof selector === "function" ? selector : function() { - return d3_select(selector, this); - }; - } - d3_selectionPrototype.selectAll = function(selector) { - var subgroups = [], subgroup, node; - selector = d3_selection_selectorAll(selector); - for (var j = -1, m = this.length; ++j < m; ) { - for (var group = this[j], i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) { - subgroups.push(subgroup = d3_array(selector.call(node, node.__data__, i, j))); - subgroup.parentNode = node; - } - } - } - return d3_selection(subgroups); - }; - function d3_selection_selectorAll(selector) { - return typeof selector === "function" ? selector : function() { - return d3_selectAll(selector, this); - }; - } - var d3_nsPrefix = { - svg: "http://www.w3.org/2000/svg", - xhtml: "http://www.w3.org/1999/xhtml", - xlink: "http://www.w3.org/1999/xlink", - xml: "http://www.w3.org/XML/1998/namespace", - xmlns: "http://www.w3.org/2000/xmlns/" - }; - d3.ns = { - prefix: d3_nsPrefix, - qualify: function(name) { - var i = name.indexOf(":"), prefix = name; - if (i >= 0) { - prefix = name.slice(0, i); - name = name.slice(i + 1); - } - return d3_nsPrefix.hasOwnProperty(prefix) ? { - space: d3_nsPrefix[prefix], - local: name - } : name; - } - }; - d3_selectionPrototype.attr = function(name, value) { - if (arguments.length < 2) { - if (typeof name === "string") { - var node = this.node(); - name = d3.ns.qualify(name); - return name.local ? node.getAttributeNS(name.space, name.local) : node.getAttribute(name); - } - for (value in name) this.each(d3_selection_attr(value, name[value])); - return this; - } - return this.each(d3_selection_attr(name, value)); - }; - function d3_selection_attr(name, value) { - name = d3.ns.qualify(name); - function attrNull() { - this.removeAttribute(name); - } - function attrNullNS() { - this.removeAttributeNS(name.space, name.local); - } - function attrConstant() { - this.setAttribute(name, value); - } - function attrConstantNS() { - this.setAttributeNS(name.space, name.local, value); - } - function attrFunction() { - var x = value.apply(this, arguments); - if (x == null) this.removeAttribute(name); else this.setAttribute(name, x); - } - function attrFunctionNS() { - var x = value.apply(this, arguments); - if (x == null) this.removeAttributeNS(name.space, name.local); else this.setAttributeNS(name.space, name.local, x); - } - return value == null ? name.local ? attrNullNS : attrNull : typeof value === "function" ? name.local ? attrFunctionNS : attrFunction : name.local ? attrConstantNS : attrConstant; - } - function d3_collapse(s) { - return s.trim().replace(/\s+/g, " "); - } - d3_selectionPrototype.classed = function(name, value) { - if (arguments.length < 2) { - if (typeof name === "string") { - var node = this.node(), n = (name = d3_selection_classes(name)).length, i = -1; - if (value = node.classList) { - while (++i < n) if (!value.contains(name[i])) return false; - } else { - value = node.getAttribute("class"); - while (++i < n) if (!d3_selection_classedRe(name[i]).test(value)) return false; - } - return true; - } - for (value in name) this.each(d3_selection_classed(value, name[value])); - return this; - } - return this.each(d3_selection_classed(name, value)); - }; - function d3_selection_classedRe(name) { - return new RegExp("(?:^|\\s+)" + d3.requote(name) + "(?:\\s+|$)", "g"); - } - function d3_selection_classes(name) { - return (name + "").trim().split(/^|\s+/); - } - function d3_selection_classed(name, value) { - name = d3_selection_classes(name).map(d3_selection_classedName); - var n = name.length; - function classedConstant() { - var i = -1; - while (++i < n) name[i](this, value); - } - function classedFunction() { - var i = -1, x = value.apply(this, arguments); - while (++i < n) name[i](this, x); - } - return typeof value === "function" ? classedFunction : classedConstant; - } - function d3_selection_classedName(name) { - var re = d3_selection_classedRe(name); - return function(node, value) { - if (c = node.classList) return value ? c.add(name) : c.remove(name); - var c = node.getAttribute("class") || ""; - if (value) { - re.lastIndex = 0; - if (!re.test(c)) node.setAttribute("class", d3_collapse(c + " " + name)); - } else { - node.setAttribute("class", d3_collapse(c.replace(re, " "))); - } - }; - } - d3_selectionPrototype.style = function(name, value, priority) { - var n = arguments.length; - if (n < 3) { - if (typeof name !== "string") { - if (n < 2) value = ""; - for (priority in name) this.each(d3_selection_style(priority, name[priority], value)); - return this; - } - if (n < 2) { - var node = this.node(); - return d3_window(node).getComputedStyle(node, null).getPropertyValue(name); - } - priority = ""; - } - return this.each(d3_selection_style(name, value, priority)); - }; - function d3_selection_style(name, value, priority) { - function styleNull() { - this.style.removeProperty(name); - } - function styleConstant() { - this.style.setProperty(name, value, priority); - } - function styleFunction() { - var x = value.apply(this, arguments); - if (x == null) this.style.removeProperty(name); else this.style.setProperty(name, x, priority); - } - return value == null ? styleNull : typeof value === "function" ? styleFunction : styleConstant; - } - d3_selectionPrototype.property = function(name, value) { - if (arguments.length < 2) { - if (typeof name === "string") return this.node()[name]; - for (value in name) this.each(d3_selection_property(value, name[value])); - return this; - } - return this.each(d3_selection_property(name, value)); - }; - function d3_selection_property(name, value) { - function propertyNull() { - delete this[name]; - } - function propertyConstant() { - this[name] = value; - } - function propertyFunction() { - var x = value.apply(this, arguments); - if (x == null) delete this[name]; else this[name] = x; - } - return value == null ? propertyNull : typeof value === "function" ? propertyFunction : propertyConstant; - } - d3_selectionPrototype.text = function(value) { - return arguments.length ? this.each(typeof value === "function" ? function() { - var v = value.apply(this, arguments); - this.textContent = v == null ? "" : v; - } : value == null ? function() { - this.textContent = ""; - } : function() { - this.textContent = value; - }) : this.node().textContent; - }; - d3_selectionPrototype.html = function(value) { - return arguments.length ? this.each(typeof value === "function" ? function() { - var v = value.apply(this, arguments); - this.innerHTML = v == null ? "" : v; - } : value == null ? function() { - this.innerHTML = ""; - } : function() { - this.innerHTML = value; - }) : this.node().innerHTML; - }; - d3_selectionPrototype.append = function(name) { - name = d3_selection_creator(name); - return this.select(function() { - return this.appendChild(name.apply(this, arguments)); - }); - }; - function d3_selection_creator(name) { - function create() { - var document = this.ownerDocument, namespace = this.namespaceURI; - return namespace ? document.createElementNS(namespace, name) : document.createElement(name); - } - function createNS() { - return this.ownerDocument.createElementNS(name.space, name.local); - } - return typeof name === "function" ? name : (name = d3.ns.qualify(name)).local ? createNS : create; - } - d3_selectionPrototype.insert = function(name, before) { - name = d3_selection_creator(name); - before = d3_selection_selector(before); - return this.select(function() { - return this.insertBefore(name.apply(this, arguments), before.apply(this, arguments) || null); - }); - }; - d3_selectionPrototype.remove = function() { - return this.each(d3_selectionRemove); - }; - function d3_selectionRemove() { - var parent = this.parentNode; - if (parent) parent.removeChild(this); - } - d3_selectionPrototype.data = function(value, key) { - var i = -1, n = this.length, group, node; - if (!arguments.length) { - value = new Array(n = (group = this[0]).length); - while (++i < n) { - if (node = group[i]) { - value[i] = node.__data__; - } - } - return value; - } - function bind(group, groupData) { - var i, n = group.length, m = groupData.length, n0 = Math.min(n, m), updateNodes = new Array(m), enterNodes = new Array(m), exitNodes = new Array(n), node, nodeData; - if (key) { - var nodeByKeyValue = new d3_Map(), keyValues = new Array(n), keyValue; - for (i = -1; ++i < n; ) { - if (nodeByKeyValue.has(keyValue = key.call(node = group[i], node.__data__, i))) { - exitNodes[i] = node; - } else { - nodeByKeyValue.set(keyValue, node); - } - keyValues[i] = keyValue; - } - for (i = -1; ++i < m; ) { - if (!(node = nodeByKeyValue.get(keyValue = key.call(groupData, nodeData = groupData[i], i)))) { - enterNodes[i] = d3_selection_dataNode(nodeData); - } else if (node !== true) { - updateNodes[i] = node; - node.__data__ = nodeData; - } - nodeByKeyValue.set(keyValue, true); - } - for (i = -1; ++i < n; ) { - if (nodeByKeyValue.get(keyValues[i]) !== true) { - exitNodes[i] = group[i]; - } - } - } else { - for (i = -1; ++i < n0; ) { - node = group[i]; - nodeData = groupData[i]; - if (node) { - node.__data__ = nodeData; - updateNodes[i] = node; - } else { - enterNodes[i] = d3_selection_dataNode(nodeData); - } - } - for (;i < m; ++i) { - enterNodes[i] = d3_selection_dataNode(groupData[i]); - } - for (;i < n; ++i) { - exitNodes[i] = group[i]; - } - } - enterNodes.update = updateNodes; - enterNodes.parentNode = updateNodes.parentNode = exitNodes.parentNode = group.parentNode; - enter.push(enterNodes); - update.push(updateNodes); - exit.push(exitNodes); - } - var enter = d3_selection_enter([]), update = d3_selection([]), exit = d3_selection([]); - if (typeof value === "function") { - while (++i < n) { - bind(group = this[i], value.call(group, group.parentNode.__data__, i)); - } - } else { - while (++i < n) { - bind(group = this[i], value); - } - } - update.enter = function() { - return enter; - }; - update.exit = function() { - return exit; - }; - return update; - }; - function d3_selection_dataNode(data) { - return { - __data__: data - }; - } - d3_selectionPrototype.datum = function(value) { - return arguments.length ? this.property("__data__", value) : this.property("__data__"); - }; - d3_selectionPrototype.filter = function(filter) { - var subgroups = [], subgroup, group, node; - if (typeof filter !== "function") filter = d3_selection_filter(filter); - for (var j = 0, m = this.length; j < m; j++) { - subgroups.push(subgroup = []); - subgroup.parentNode = (group = this[j]).parentNode; - for (var i = 0, n = group.length; i < n; i++) { - if ((node = group[i]) && filter.call(node, node.__data__, i, j)) { - subgroup.push(node); - } - } - } - return d3_selection(subgroups); - }; - function d3_selection_filter(selector) { - return function() { - return d3_selectMatches(this, selector); - }; - } - d3_selectionPrototype.order = function() { - for (var j = -1, m = this.length; ++j < m; ) { - for (var group = this[j], i = group.length - 1, next = group[i], node; --i >= 0; ) { - if (node = group[i]) { - if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next); - next = node; - } - } - } - return this; - }; - d3_selectionPrototype.sort = function(comparator) { - comparator = d3_selection_sortComparator.apply(this, arguments); - for (var j = -1, m = this.length; ++j < m; ) this[j].sort(comparator); - return this.order(); - }; - function d3_selection_sortComparator(comparator) { - if (!arguments.length) comparator = d3_ascending; - return function(a, b) { - return a && b ? comparator(a.__data__, b.__data__) : !a - !b; - }; - } - d3_selectionPrototype.each = function(callback) { - return d3_selection_each(this, function(node, i, j) { - callback.call(node, node.__data__, i, j); - }); - }; - function d3_selection_each(groups, callback) { - for (var j = 0, m = groups.length; j < m; j++) { - for (var group = groups[j], i = 0, n = group.length, node; i < n; i++) { - if (node = group[i]) callback(node, i, j); - } - } - return groups; - } - d3_selectionPrototype.call = function(callback) { - var args = d3_array(arguments); - callback.apply(args[0] = this, args); - return this; - }; - d3_selectionPrototype.empty = function() { - return !this.node(); - }; - d3_selectionPrototype.node = function() { - for (var j = 0, m = this.length; j < m; j++) { - for (var group = this[j], i = 0, n = group.length; i < n; i++) { - var node = group[i]; - if (node) return node; - } - } - return null; - }; - d3_selectionPrototype.size = function() { - var n = 0; - d3_selection_each(this, function() { - ++n; - }); - return n; - }; - function d3_selection_enter(selection) { - d3_subclass(selection, d3_selection_enterPrototype); - return selection; - } - var d3_selection_enterPrototype = []; - d3.selection.enter = d3_selection_enter; - d3.selection.enter.prototype = d3_selection_enterPrototype; - d3_selection_enterPrototype.append = d3_selectionPrototype.append; - d3_selection_enterPrototype.empty = d3_selectionPrototype.empty; - d3_selection_enterPrototype.node = d3_selectionPrototype.node; - d3_selection_enterPrototype.call = d3_selectionPrototype.call; - d3_selection_enterPrototype.size = d3_selectionPrototype.size; - d3_selection_enterPrototype.select = function(selector) { - var subgroups = [], subgroup, subnode, upgroup, group, node; - for (var j = -1, m = this.length; ++j < m; ) { - upgroup = (group = this[j]).update; - subgroups.push(subgroup = []); - subgroup.parentNode = group.parentNode; - for (var i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) { - subgroup.push(upgroup[i] = subnode = selector.call(group.parentNode, node.__data__, i, j)); - subnode.__data__ = node.__data__; - } else { - subgroup.push(null); - } - } - } - return d3_selection(subgroups); - }; - d3_selection_enterPrototype.insert = function(name, before) { - if (arguments.length < 2) before = d3_selection_enterInsertBefore(this); - return d3_selectionPrototype.insert.call(this, name, before); - }; - function d3_selection_enterInsertBefore(enter) { - var i0, j0; - return function(d, i, j) { - var group = enter[j].update, n = group.length, node; - if (j != j0) j0 = j, i0 = 0; - if (i >= i0) i0 = i + 1; - while (!(node = group[i0]) && ++i0 < n) ; - return node; - }; - } - d3.select = function(node) { - var group; - if (typeof node === "string") { - group = [ d3_select(node, d3_document) ]; - group.parentNode = d3_document.documentElement; - } else { - group = [ node ]; - group.parentNode = d3_documentElement(node); - } - return d3_selection([ group ]); - }; - d3.selectAll = function(nodes) { - var group; - if (typeof nodes === "string") { - group = d3_array(d3_selectAll(nodes, d3_document)); - group.parentNode = d3_document.documentElement; - } else { - group = nodes; - group.parentNode = null; - } - return d3_selection([ group ]); - }; - d3_selectionPrototype.on = function(type, listener, capture) { - var n = arguments.length; - if (n < 3) { - if (typeof type !== "string") { - if (n < 2) listener = false; - for (capture in type) this.each(d3_selection_on(capture, type[capture], listener)); - return this; - } - if (n < 2) return (n = this.node()["__on" + type]) && n._; - capture = false; - } - return this.each(d3_selection_on(type, listener, capture)); - }; - function d3_selection_on(type, listener, capture) { - var name = "__on" + type, i = type.indexOf("."), wrap = d3_selection_onListener; - if (i > 0) type = type.slice(0, i); - var filter = d3_selection_onFilters.get(type); - if (filter) type = filter, wrap = d3_selection_onFilter; - function onRemove() { - var l = this[name]; - if (l) { - this.removeEventListener(type, l, l.$); - delete this[name]; - } - } - function onAdd() { - var l = wrap(listener, d3_array(arguments)); - onRemove.call(this); - this.addEventListener(type, this[name] = l, l.$ = capture); - l._ = listener; - } - function removeAll() { - var re = new RegExp("^__on([^.]+)" + d3.requote(type) + "$"), match; - for (var name in this) { - if (match = name.match(re)) { - var l = this[name]; - this.removeEventListener(match[1], l, l.$); - delete this[name]; - } - } - } - return i ? listener ? onAdd : onRemove : listener ? d3_noop : removeAll; - } - var d3_selection_onFilters = d3.map({ - mouseenter: "mouseover", - mouseleave: "mouseout" - }); - if (d3_document) { - d3_selection_onFilters.forEach(function(k) { - if ("on" + k in d3_document) d3_selection_onFilters.remove(k); - }); - } - function d3_selection_onListener(listener, argumentz) { - return function(e) { - var o = d3.event; - d3.event = e; - argumentz[0] = this.__data__; - try { - listener.apply(this, argumentz); - } finally { - d3.event = o; - } - }; - } - function d3_selection_onFilter(listener, argumentz) { - var l = d3_selection_onListener(listener, argumentz); - return function(e) { - var target = this, related = e.relatedTarget; - if (!related || related !== target && !(related.compareDocumentPosition(target) & 8)) { - l.call(target, e); - } - }; - } - var d3_event_dragSelect, d3_event_dragId = 0; - function d3_event_dragSuppress(node) { - var name = ".dragsuppress-" + ++d3_event_dragId, click = "click" + name, w = d3.select(d3_window(node)).on("touchmove" + name, d3_eventPreventDefault).on("dragstart" + name, d3_eventPreventDefault).on("selectstart" + name, d3_eventPreventDefault); - if (d3_event_dragSelect == null) { - d3_event_dragSelect = "onselectstart" in node ? false : d3_vendorSymbol(node.style, "userSelect"); - } - if (d3_event_dragSelect) { - var style = d3_documentElement(node).style, select = style[d3_event_dragSelect]; - style[d3_event_dragSelect] = "none"; - } - return function(suppressClick) { - w.on(name, null); - if (d3_event_dragSelect) style[d3_event_dragSelect] = select; - if (suppressClick) { - var off = function() { - w.on(click, null); - }; - w.on(click, function() { - d3_eventPreventDefault(); - off(); - }, true); - setTimeout(off, 0); - } - }; - } - d3.mouse = function(container) { - return d3_mousePoint(container, d3_eventSource()); - }; - var d3_mouse_bug44083 = this.navigator && /WebKit/.test(this.navigator.userAgent) ? -1 : 0; - function d3_mousePoint(container, e) { - if (e.changedTouches) e = e.changedTouches[0]; - var svg = container.ownerSVGElement || container; - if (svg.createSVGPoint) { - var point = svg.createSVGPoint(); - if (d3_mouse_bug44083 < 0) { - var window = d3_window(container); - if (window.scrollX || window.scrollY) { - svg = d3.select("body").append("svg").style({ - position: "absolute", - top: 0, - left: 0, - margin: 0, - padding: 0, - border: "none" - }, "important"); - var ctm = svg[0][0].getScreenCTM(); - d3_mouse_bug44083 = !(ctm.f || ctm.e); - svg.remove(); - } - } - if (d3_mouse_bug44083) point.x = e.pageX, point.y = e.pageY; else point.x = e.clientX, - point.y = e.clientY; - point = point.matrixTransform(container.getScreenCTM().inverse()); - return [ point.x, point.y ]; - } - var rect = container.getBoundingClientRect(); - return [ e.clientX - rect.left - container.clientLeft, e.clientY - rect.top - container.clientTop ]; - } - d3.touch = function(container, touches, identifier) { - if (arguments.length < 3) identifier = touches, touches = d3_eventSource().changedTouches; - if (touches) for (var i = 0, n = touches.length, touch; i < n; ++i) { - if ((touch = touches[i]).identifier === identifier) { - return d3_mousePoint(container, touch); - } - } - }; - d3.behavior.drag = function() { - var event = d3_eventDispatch(drag, "drag", "dragstart", "dragend"), origin = null, mousedown = dragstart(d3_noop, d3.mouse, d3_window, "mousemove", "mouseup"), touchstart = dragstart(d3_behavior_dragTouchId, d3.touch, d3_identity, "touchmove", "touchend"); - function drag() { - this.on("mousedown.drag", mousedown).on("touchstart.drag", touchstart); - } - function dragstart(id, position, subject, move, end) { - return function() { - var that = this, target = d3.event.target, parent = that.parentNode, dispatch = event.of(that, arguments), dragged = 0, dragId = id(), dragName = ".drag" + (dragId == null ? "" : "-" + dragId), dragOffset, dragSubject = d3.select(subject(target)).on(move + dragName, moved).on(end + dragName, ended), dragRestore = d3_event_dragSuppress(target), position0 = position(parent, dragId); - if (origin) { - dragOffset = origin.apply(that, arguments); - dragOffset = [ dragOffset.x - position0[0], dragOffset.y - position0[1] ]; - } else { - dragOffset = [ 0, 0 ]; - } - dispatch({ - type: "dragstart" - }); - function moved() { - var position1 = position(parent, dragId), dx, dy; - if (!position1) return; - dx = position1[0] - position0[0]; - dy = position1[1] - position0[1]; - dragged |= dx | dy; - position0 = position1; - dispatch({ - type: "drag", - x: position1[0] + dragOffset[0], - y: position1[1] + dragOffset[1], - dx: dx, - dy: dy - }); - } - function ended() { - if (!position(parent, dragId)) return; - dragSubject.on(move + dragName, null).on(end + dragName, null); - dragRestore(dragged && d3.event.target === target); - dispatch({ - type: "dragend" - }); - } - }; - } - drag.origin = function(x) { - if (!arguments.length) return origin; - origin = x; - return drag; - }; - return d3.rebind(drag, event, "on"); - }; - function d3_behavior_dragTouchId() { - return d3.event.changedTouches[0].identifier; - } - d3.touches = function(container, touches) { - if (arguments.length < 2) touches = d3_eventSource().touches; - return touches ? d3_array(touches).map(function(touch) { - var point = d3_mousePoint(container, touch); - point.identifier = touch.identifier; - return point; - }) : []; - }; - var ε = 1e-6, ε2 = ε * ε, π = Math.PI, τ = 2 * π, τε = τ - ε, halfπ = π / 2, d3_radians = π / 180, d3_degrees = 180 / π; - function d3_sgn(x) { - return x > 0 ? 1 : x < 0 ? -1 : 0; - } - function d3_cross2d(a, b, c) { - return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]); - } - function d3_acos(x) { - return x > 1 ? 0 : x < -1 ? π : Math.acos(x); - } - function d3_asin(x) { - return x > 1 ? halfπ : x < -1 ? -halfπ : Math.asin(x); - } - function d3_sinh(x) { - return ((x = Math.exp(x)) - 1 / x) / 2; - } - function d3_cosh(x) { - return ((x = Math.exp(x)) + 1 / x) / 2; - } - function d3_tanh(x) { - return ((x = Math.exp(2 * x)) - 1) / (x + 1); - } - function d3_haversin(x) { - return (x = Math.sin(x / 2)) * x; - } - var ρ = Math.SQRT2, ρ2 = 2, ρ4 = 4; - d3.interpolateZoom = function(p0, p1) { - var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], ux1 = p1[0], uy1 = p1[1], w1 = p1[2]; - var dx = ux1 - ux0, dy = uy1 - uy0, d2 = dx * dx + dy * dy, d1 = Math.sqrt(d2), b0 = (w1 * w1 - w0 * w0 + ρ4 * d2) / (2 * w0 * ρ2 * d1), b1 = (w1 * w1 - w0 * w0 - ρ4 * d2) / (2 * w1 * ρ2 * d1), r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1), dr = r1 - r0, S = (dr || Math.log(w1 / w0)) / ρ; - function interpolate(t) { - var s = t * S; - if (dr) { - var coshr0 = d3_cosh(r0), u = w0 / (ρ2 * d1) * (coshr0 * d3_tanh(ρ * s + r0) - d3_sinh(r0)); - return [ ux0 + u * dx, uy0 + u * dy, w0 * coshr0 / d3_cosh(ρ * s + r0) ]; - } - return [ ux0 + t * dx, uy0 + t * dy, w0 * Math.exp(ρ * s) ]; - } - interpolate.duration = S * 1e3; - return interpolate; - }; - d3.behavior.zoom = function() { - var view = { - x: 0, - y: 0, - k: 1 - }, translate0, center0, center, size = [ 960, 500 ], scaleExtent = d3_behavior_zoomInfinity, duration = 250, zooming = 0, mousedown = "mousedown.zoom", mousemove = "mousemove.zoom", mouseup = "mouseup.zoom", mousewheelTimer, touchstart = "touchstart.zoom", touchtime, event = d3_eventDispatch(zoom, "zoomstart", "zoom", "zoomend"), x0, x1, y0, y1; - if (!d3_behavior_zoomWheel) { - d3_behavior_zoomWheel = "onwheel" in d3_document ? (d3_behavior_zoomDelta = function() { - return -d3.event.deltaY * (d3.event.deltaMode ? 120 : 1); - }, "wheel") : "onmousewheel" in d3_document ? (d3_behavior_zoomDelta = function() { - return d3.event.wheelDelta; - }, "mousewheel") : (d3_behavior_zoomDelta = function() { - return -d3.event.detail; - }, "MozMousePixelScroll"); - } - function zoom(g) { - g.on(mousedown, mousedowned).on(d3_behavior_zoomWheel + ".zoom", mousewheeled).on("dblclick.zoom", dblclicked).on(touchstart, touchstarted); - } - zoom.event = function(g) { - g.each(function() { - var dispatch = event.of(this, arguments), view1 = view; - if (d3_transitionInheritId) { - d3.select(this).transition().each("start.zoom", function() { - view = this.__chart__ || { - x: 0, - y: 0, - k: 1 - }; - zoomstarted(dispatch); - }).tween("zoom:zoom", function() { - var dx = size[0], dy = size[1], cx = center0 ? center0[0] : dx / 2, cy = center0 ? center0[1] : dy / 2, i = d3.interpolateZoom([ (cx - view.x) / view.k, (cy - view.y) / view.k, dx / view.k ], [ (cx - view1.x) / view1.k, (cy - view1.y) / view1.k, dx / view1.k ]); - return function(t) { - var l = i(t), k = dx / l[2]; - this.__chart__ = view = { - x: cx - l[0] * k, - y: cy - l[1] * k, - k: k - }; - zoomed(dispatch); - }; - }).each("interrupt.zoom", function() { - zoomended(dispatch); - }).each("end.zoom", function() { - zoomended(dispatch); - }); - } else { - this.__chart__ = view; - zoomstarted(dispatch); - zoomed(dispatch); - zoomended(dispatch); - } - }); - }; - zoom.translate = function(_) { - if (!arguments.length) return [ view.x, view.y ]; - view = { - x: +_[0], - y: +_[1], - k: view.k - }; - rescale(); - return zoom; - }; - zoom.scale = function(_) { - if (!arguments.length) return view.k; - view = { - x: view.x, - y: view.y, - k: +_ - }; - rescale(); - return zoom; - }; - zoom.scaleExtent = function(_) { - if (!arguments.length) return scaleExtent; - scaleExtent = _ == null ? d3_behavior_zoomInfinity : [ +_[0], +_[1] ]; - return zoom; - }; - zoom.center = function(_) { - if (!arguments.length) return center; - center = _ && [ +_[0], +_[1] ]; - return zoom; - }; - zoom.size = function(_) { - if (!arguments.length) return size; - size = _ && [ +_[0], +_[1] ]; - return zoom; - }; - zoom.duration = function(_) { - if (!arguments.length) return duration; - duration = +_; - return zoom; - }; - zoom.x = function(z) { - if (!arguments.length) return x1; - x1 = z; - x0 = z.copy(); - view = { - x: 0, - y: 0, - k: 1 - }; - return zoom; - }; - zoom.y = function(z) { - if (!arguments.length) return y1; - y1 = z; - y0 = z.copy(); - view = { - x: 0, - y: 0, - k: 1 - }; - return zoom; - }; - function location(p) { - return [ (p[0] - view.x) / view.k, (p[1] - view.y) / view.k ]; - } - function point(l) { - return [ l[0] * view.k + view.x, l[1] * view.k + view.y ]; - } - function scaleTo(s) { - view.k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], s)); - } - function translateTo(p, l) { - l = point(l); - view.x += p[0] - l[0]; - view.y += p[1] - l[1]; - } - function zoomTo(that, p, l, k) { - that.__chart__ = { - x: view.x, - y: view.y, - k: view.k - }; - scaleTo(Math.pow(2, k)); - translateTo(center0 = p, l); - that = d3.select(that); - if (duration > 0) that = that.transition().duration(duration); - that.call(zoom.event); - } - function rescale() { - if (x1) x1.domain(x0.range().map(function(x) { - return (x - view.x) / view.k; - }).map(x0.invert)); - if (y1) y1.domain(y0.range().map(function(y) { - return (y - view.y) / view.k; - }).map(y0.invert)); - } - function zoomstarted(dispatch) { - if (!zooming++) dispatch({ - type: "zoomstart" - }); - } - function zoomed(dispatch) { - rescale(); - dispatch({ - type: "zoom", - scale: view.k, - translate: [ view.x, view.y ] - }); - } - function zoomended(dispatch) { - if (!--zooming) dispatch({ - type: "zoomend" - }), center0 = null; - } - function mousedowned() { - var that = this, target = d3.event.target, dispatch = event.of(that, arguments), dragged = 0, subject = d3.select(d3_window(that)).on(mousemove, moved).on(mouseup, ended), location0 = location(d3.mouse(that)), dragRestore = d3_event_dragSuppress(that); - d3_selection_interrupt.call(that); - zoomstarted(dispatch); - function moved() { - dragged = 1; - translateTo(d3.mouse(that), location0); - zoomed(dispatch); - } - function ended() { - subject.on(mousemove, null).on(mouseup, null); - dragRestore(dragged && d3.event.target === target); - zoomended(dispatch); - } - } - function touchstarted() { - var that = this, dispatch = event.of(that, arguments), locations0 = {}, distance0 = 0, scale0, zoomName = ".zoom-" + d3.event.changedTouches[0].identifier, touchmove = "touchmove" + zoomName, touchend = "touchend" + zoomName, targets = [], subject = d3.select(that), dragRestore = d3_event_dragSuppress(that); - started(); - zoomstarted(dispatch); - subject.on(mousedown, null).on(touchstart, started); - function relocate() { - var touches = d3.touches(that); - scale0 = view.k; - touches.forEach(function(t) { - if (t.identifier in locations0) locations0[t.identifier] = location(t); - }); - return touches; - } - function started() { - var target = d3.event.target; - d3.select(target).on(touchmove, moved).on(touchend, ended); - targets.push(target); - var changed = d3.event.changedTouches; - for (var i = 0, n = changed.length; i < n; ++i) { - locations0[changed[i].identifier] = null; - } - var touches = relocate(), now = Date.now(); - if (touches.length === 1) { - if (now - touchtime < 500) { - var p = touches[0]; - zoomTo(that, p, locations0[p.identifier], Math.floor(Math.log(view.k) / Math.LN2) + 1); - d3_eventPreventDefault(); - } - touchtime = now; - } else if (touches.length > 1) { - var p = touches[0], q = touches[1], dx = p[0] - q[0], dy = p[1] - q[1]; - distance0 = dx * dx + dy * dy; - } - } - function moved() { - var touches = d3.touches(that), p0, l0, p1, l1; - d3_selection_interrupt.call(that); - for (var i = 0, n = touches.length; i < n; ++i, l1 = null) { - p1 = touches[i]; - if (l1 = locations0[p1.identifier]) { - if (l0) break; - p0 = p1, l0 = l1; - } - } - if (l1) { - var distance1 = (distance1 = p1[0] - p0[0]) * distance1 + (distance1 = p1[1] - p0[1]) * distance1, scale1 = distance0 && Math.sqrt(distance1 / distance0); - p0 = [ (p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2 ]; - l0 = [ (l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2 ]; - scaleTo(scale1 * scale0); - } - touchtime = null; - translateTo(p0, l0); - zoomed(dispatch); - } - function ended() { - if (d3.event.touches.length) { - var changed = d3.event.changedTouches; - for (var i = 0, n = changed.length; i < n; ++i) { - delete locations0[changed[i].identifier]; - } - for (var identifier in locations0) { - return void relocate(); - } - } - d3.selectAll(targets).on(zoomName, null); - subject.on(mousedown, mousedowned).on(touchstart, touchstarted); - dragRestore(); - zoomended(dispatch); - } - } - function mousewheeled() { - var dispatch = event.of(this, arguments); - if (mousewheelTimer) clearTimeout(mousewheelTimer); else d3_selection_interrupt.call(this), - translate0 = location(center0 = center || d3.mouse(this)), zoomstarted(dispatch); - mousewheelTimer = setTimeout(function() { - mousewheelTimer = null; - zoomended(dispatch); - }, 50); - d3_eventPreventDefault(); - scaleTo(Math.pow(2, d3_behavior_zoomDelta() * .002) * view.k); - translateTo(center0, translate0); - zoomed(dispatch); - } - function dblclicked() { - var p = d3.mouse(this), k = Math.log(view.k) / Math.LN2; - zoomTo(this, p, location(p), d3.event.shiftKey ? Math.ceil(k) - 1 : Math.floor(k) + 1); - } - return d3.rebind(zoom, event, "on"); - }; - var d3_behavior_zoomInfinity = [ 0, Infinity ], d3_behavior_zoomDelta, d3_behavior_zoomWheel; - d3.color = d3_color; - function d3_color() {} - d3_color.prototype.toString = function() { - return this.rgb() + ""; - }; - d3.hsl = d3_hsl; - function d3_hsl(h, s, l) { - return this instanceof d3_hsl ? void (this.h = +h, this.s = +s, this.l = +l) : arguments.length < 2 ? h instanceof d3_hsl ? new d3_hsl(h.h, h.s, h.l) : d3_rgb_parse("" + h, d3_rgb_hsl, d3_hsl) : new d3_hsl(h, s, l); - } - var d3_hslPrototype = d3_hsl.prototype = new d3_color(); - d3_hslPrototype.brighter = function(k) { - k = Math.pow(.7, arguments.length ? k : 1); - return new d3_hsl(this.h, this.s, this.l / k); - }; - d3_hslPrototype.darker = function(k) { - k = Math.pow(.7, arguments.length ? k : 1); - return new d3_hsl(this.h, this.s, k * this.l); - }; - d3_hslPrototype.rgb = function() { - return d3_hsl_rgb(this.h, this.s, this.l); - }; - function d3_hsl_rgb(h, s, l) { - var m1, m2; - h = isNaN(h) ? 0 : (h %= 360) < 0 ? h + 360 : h; - s = isNaN(s) ? 0 : s < 0 ? 0 : s > 1 ? 1 : s; - l = l < 0 ? 0 : l > 1 ? 1 : l; - m2 = l <= .5 ? l * (1 + s) : l + s - l * s; - m1 = 2 * l - m2; - function v(h) { - if (h > 360) h -= 360; else if (h < 0) h += 360; - if (h < 60) return m1 + (m2 - m1) * h / 60; - if (h < 180) return m2; - if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60; - return m1; - } - function vv(h) { - return Math.round(v(h) * 255); - } - return new d3_rgb(vv(h + 120), vv(h), vv(h - 120)); - } - d3.hcl = d3_hcl; - function d3_hcl(h, c, l) { - return this instanceof d3_hcl ? void (this.h = +h, this.c = +c, this.l = +l) : arguments.length < 2 ? h instanceof d3_hcl ? new d3_hcl(h.h, h.c, h.l) : h instanceof d3_lab ? d3_lab_hcl(h.l, h.a, h.b) : d3_lab_hcl((h = d3_rgb_lab((h = d3.rgb(h)).r, h.g, h.b)).l, h.a, h.b) : new d3_hcl(h, c, l); - } - var d3_hclPrototype = d3_hcl.prototype = new d3_color(); - d3_hclPrototype.brighter = function(k) { - return new d3_hcl(this.h, this.c, Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1))); - }; - d3_hclPrototype.darker = function(k) { - return new d3_hcl(this.h, this.c, Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1))); - }; - d3_hclPrototype.rgb = function() { - return d3_hcl_lab(this.h, this.c, this.l).rgb(); - }; - function d3_hcl_lab(h, c, l) { - if (isNaN(h)) h = 0; - if (isNaN(c)) c = 0; - return new d3_lab(l, Math.cos(h *= d3_radians) * c, Math.sin(h) * c); - } - d3.lab = d3_lab; - function d3_lab(l, a, b) { - return this instanceof d3_lab ? void (this.l = +l, this.a = +a, this.b = +b) : arguments.length < 2 ? l instanceof d3_lab ? new d3_lab(l.l, l.a, l.b) : l instanceof d3_hcl ? d3_hcl_lab(l.h, l.c, l.l) : d3_rgb_lab((l = d3_rgb(l)).r, l.g, l.b) : new d3_lab(l, a, b); - } - var d3_lab_K = 18; - var d3_lab_X = .95047, d3_lab_Y = 1, d3_lab_Z = 1.08883; - var d3_labPrototype = d3_lab.prototype = new d3_color(); - d3_labPrototype.brighter = function(k) { - return new d3_lab(Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)), this.a, this.b); - }; - d3_labPrototype.darker = function(k) { - return new d3_lab(Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)), this.a, this.b); - }; - d3_labPrototype.rgb = function() { - return d3_lab_rgb(this.l, this.a, this.b); - }; - function d3_lab_rgb(l, a, b) { - var y = (l + 16) / 116, x = y + a / 500, z = y - b / 200; - x = d3_lab_xyz(x) * d3_lab_X; - y = d3_lab_xyz(y) * d3_lab_Y; - z = d3_lab_xyz(z) * d3_lab_Z; - return new d3_rgb(d3_xyz_rgb(3.2404542 * x - 1.5371385 * y - .4985314 * z), d3_xyz_rgb(-.969266 * x + 1.8760108 * y + .041556 * z), d3_xyz_rgb(.0556434 * x - .2040259 * y + 1.0572252 * z)); - } - function d3_lab_hcl(l, a, b) { - return l > 0 ? new d3_hcl(Math.atan2(b, a) * d3_degrees, Math.sqrt(a * a + b * b), l) : new d3_hcl(NaN, NaN, l); - } - function d3_lab_xyz(x) { - return x > .206893034 ? x * x * x : (x - 4 / 29) / 7.787037; - } - function d3_xyz_lab(x) { - return x > .008856 ? Math.pow(x, 1 / 3) : 7.787037 * x + 4 / 29; - } - function d3_xyz_rgb(r) { - return Math.round(255 * (r <= .00304 ? 12.92 * r : 1.055 * Math.pow(r, 1 / 2.4) - .055)); - } - d3.rgb = d3_rgb; - function d3_rgb(r, g, b) { - return this instanceof d3_rgb ? void (this.r = ~~r, this.g = ~~g, this.b = ~~b) : arguments.length < 2 ? r instanceof d3_rgb ? new d3_rgb(r.r, r.g, r.b) : d3_rgb_parse("" + r, d3_rgb, d3_hsl_rgb) : new d3_rgb(r, g, b); - } - function d3_rgbNumber(value) { - return new d3_rgb(value >> 16, value >> 8 & 255, value & 255); - } - function d3_rgbString(value) { - return d3_rgbNumber(value) + ""; - } - var d3_rgbPrototype = d3_rgb.prototype = new d3_color(); - d3_rgbPrototype.brighter = function(k) { - k = Math.pow(.7, arguments.length ? k : 1); - var r = this.r, g = this.g, b = this.b, i = 30; - if (!r && !g && !b) return new d3_rgb(i, i, i); - if (r && r < i) r = i; - if (g && g < i) g = i; - if (b && b < i) b = i; - return new d3_rgb(Math.min(255, r / k), Math.min(255, g / k), Math.min(255, b / k)); - }; - d3_rgbPrototype.darker = function(k) { - k = Math.pow(.7, arguments.length ? k : 1); - return new d3_rgb(k * this.r, k * this.g, k * this.b); - }; - d3_rgbPrototype.hsl = function() { - return d3_rgb_hsl(this.r, this.g, this.b); - }; - d3_rgbPrototype.toString = function() { - return "#" + d3_rgb_hex(this.r) + d3_rgb_hex(this.g) + d3_rgb_hex(this.b); - }; - function d3_rgb_hex(v) { - return v < 16 ? "0" + Math.max(0, v).toString(16) : Math.min(255, v).toString(16); - } - function d3_rgb_parse(format, rgb, hsl) { - format = format.toLowerCase(); - var r = 0, g = 0, b = 0, m1, m2, color; - m1 = /([a-z]+)\((.*)\)/.exec(format); - if (m1) { - m2 = m1[2].split(","); - switch (m1[1]) { - case "hsl": - { - return hsl(parseFloat(m2[0]), parseFloat(m2[1]) / 100, parseFloat(m2[2]) / 100); - } - - case "rgb": - { - return rgb(d3_rgb_parseNumber(m2[0]), d3_rgb_parseNumber(m2[1]), d3_rgb_parseNumber(m2[2])); - } - } - } - if (color = d3_rgb_names.get(format)) { - return rgb(color.r, color.g, color.b); - } - if (format != null && format.charAt(0) === "#" && !isNaN(color = parseInt(format.slice(1), 16))) { - if (format.length === 4) { - r = (color & 3840) >> 4; - r = r >> 4 | r; - g = color & 240; - g = g >> 4 | g; - b = color & 15; - b = b << 4 | b; - } else if (format.length === 7) { - r = (color & 16711680) >> 16; - g = (color & 65280) >> 8; - b = color & 255; - } - } - return rgb(r, g, b); - } - function d3_rgb_hsl(r, g, b) { - var min = Math.min(r /= 255, g /= 255, b /= 255), max = Math.max(r, g, b), d = max - min, h, s, l = (max + min) / 2; - if (d) { - s = l < .5 ? d / (max + min) : d / (2 - max - min); - if (r == max) h = (g - b) / d + (g < b ? 6 : 0); else if (g == max) h = (b - r) / d + 2; else h = (r - g) / d + 4; - h *= 60; - } else { - h = NaN; - s = l > 0 && l < 1 ? 0 : h; - } - return new d3_hsl(h, s, l); - } - function d3_rgb_lab(r, g, b) { - r = d3_rgb_xyz(r); - g = d3_rgb_xyz(g); - b = d3_rgb_xyz(b); - var x = d3_xyz_lab((.4124564 * r + .3575761 * g + .1804375 * b) / d3_lab_X), y = d3_xyz_lab((.2126729 * r + .7151522 * g + .072175 * b) / d3_lab_Y), z = d3_xyz_lab((.0193339 * r + .119192 * g + .9503041 * b) / d3_lab_Z); - return d3_lab(116 * y - 16, 500 * (x - y), 200 * (y - z)); - } - function d3_rgb_xyz(r) { - return (r /= 255) <= .04045 ? r / 12.92 : Math.pow((r + .055) / 1.055, 2.4); - } - function d3_rgb_parseNumber(c) { - var f = parseFloat(c); - return c.charAt(c.length - 1) === "%" ? Math.round(f * 2.55) : f; - } - var d3_rgb_names = d3.map({ - aliceblue: 15792383, - antiquewhite: 16444375, - aqua: 65535, - aquamarine: 8388564, - azure: 15794175, - beige: 16119260, - bisque: 16770244, - black: 0, - blanchedalmond: 16772045, - blue: 255, - blueviolet: 9055202, - brown: 10824234, - burlywood: 14596231, - cadetblue: 6266528, - chartreuse: 8388352, - chocolate: 13789470, - coral: 16744272, - cornflowerblue: 6591981, - cornsilk: 16775388, - crimson: 14423100, - cyan: 65535, - darkblue: 139, - darkcyan: 35723, - darkgoldenrod: 12092939, - darkgray: 11119017, - darkgreen: 25600, - darkgrey: 11119017, - darkkhaki: 12433259, - darkmagenta: 9109643, - darkolivegreen: 5597999, - darkorange: 16747520, - darkorchid: 10040012, - darkred: 9109504, - darksalmon: 15308410, - darkseagreen: 9419919, - darkslateblue: 4734347, - darkslategray: 3100495, - darkslategrey: 3100495, - darkturquoise: 52945, - darkviolet: 9699539, - deeppink: 16716947, - deepskyblue: 49151, - dimgray: 6908265, - dimgrey: 6908265, - dodgerblue: 2003199, - firebrick: 11674146, - floralwhite: 16775920, - forestgreen: 2263842, - fuchsia: 16711935, - gainsboro: 14474460, - ghostwhite: 16316671, - gold: 16766720, - goldenrod: 14329120, - gray: 8421504, - green: 32768, - greenyellow: 11403055, - grey: 8421504, - honeydew: 15794160, - hotpink: 16738740, - indianred: 13458524, - indigo: 4915330, - ivory: 16777200, - khaki: 15787660, - lavender: 15132410, - lavenderblush: 16773365, - lawngreen: 8190976, - lemonchiffon: 16775885, - lightblue: 11393254, - lightcoral: 15761536, - lightcyan: 14745599, - lightgoldenrodyellow: 16448210, - lightgray: 13882323, - lightgreen: 9498256, - lightgrey: 13882323, - lightpink: 16758465, - lightsalmon: 16752762, - lightseagreen: 2142890, - lightskyblue: 8900346, - lightslategray: 7833753, - lightslategrey: 7833753, - lightsteelblue: 11584734, - lightyellow: 16777184, - lime: 65280, - limegreen: 3329330, - linen: 16445670, - magenta: 16711935, - maroon: 8388608, - mediumaquamarine: 6737322, - mediumblue: 205, - mediumorchid: 12211667, - mediumpurple: 9662683, - mediumseagreen: 3978097, - mediumslateblue: 8087790, - mediumspringgreen: 64154, - mediumturquoise: 4772300, - mediumvioletred: 13047173, - midnightblue: 1644912, - mintcream: 16121850, - mistyrose: 16770273, - moccasin: 16770229, - navajowhite: 16768685, - navy: 128, - oldlace: 16643558, - olive: 8421376, - olivedrab: 7048739, - orange: 16753920, - orangered: 16729344, - orchid: 14315734, - palegoldenrod: 15657130, - palegreen: 10025880, - paleturquoise: 11529966, - palevioletred: 14381203, - papayawhip: 16773077, - peachpuff: 16767673, - peru: 13468991, - pink: 16761035, - plum: 14524637, - powderblue: 11591910, - purple: 8388736, - rebeccapurple: 6697881, - red: 16711680, - rosybrown: 12357519, - royalblue: 4286945, - saddlebrown: 9127187, - salmon: 16416882, - sandybrown: 16032864, - seagreen: 3050327, - seashell: 16774638, - sienna: 10506797, - silver: 12632256, - skyblue: 8900331, - slateblue: 6970061, - slategray: 7372944, - slategrey: 7372944, - snow: 16775930, - springgreen: 65407, - steelblue: 4620980, - tan: 13808780, - teal: 32896, - thistle: 14204888, - tomato: 16737095, - turquoise: 4251856, - violet: 15631086, - wheat: 16113331, - white: 16777215, - whitesmoke: 16119285, - yellow: 16776960, - yellowgreen: 10145074 - }); - d3_rgb_names.forEach(function(key, value) { - d3_rgb_names.set(key, d3_rgbNumber(value)); - }); - function d3_functor(v) { - return typeof v === "function" ? v : function() { - return v; - }; - } - d3.functor = d3_functor; - d3.xhr = d3_xhrType(d3_identity); - function d3_xhrType(response) { - return function(url, mimeType, callback) { - if (arguments.length === 2 && typeof mimeType === "function") callback = mimeType, - mimeType = null; - return d3_xhr(url, mimeType, response, callback); - }; - } - function d3_xhr(url, mimeType, response, callback) { - var xhr = {}, dispatch = d3.dispatch("beforesend", "progress", "load", "error"), headers = {}, request = new XMLHttpRequest(), responseType = null; - if (this.XDomainRequest && !("withCredentials" in request) && /^(http(s)?:)?\/\//.test(url)) request = new XDomainRequest(); - "onload" in request ? request.onload = request.onerror = respond : request.onreadystatechange = function() { - request.readyState > 3 && respond(); - }; - function respond() { - var status = request.status, result; - if (!status && d3_xhrHasResponse(request) || status >= 200 && status < 300 || status === 304) { - try { - result = response.call(xhr, request); - } catch (e) { - dispatch.error.call(xhr, e); - return; - } - dispatch.load.call(xhr, result); - } else { - dispatch.error.call(xhr, request); - } - } - request.onprogress = function(event) { - var o = d3.event; - d3.event = event; - try { - dispatch.progress.call(xhr, request); - } finally { - d3.event = o; - } - }; - xhr.header = function(name, value) { - name = (name + "").toLowerCase(); - if (arguments.length < 2) return headers[name]; - if (value == null) delete headers[name]; else headers[name] = value + ""; - return xhr; - }; - xhr.mimeType = function(value) { - if (!arguments.length) return mimeType; - mimeType = value == null ? null : value + ""; - return xhr; - }; - xhr.responseType = function(value) { - if (!arguments.length) return responseType; - responseType = value; - return xhr; - }; - xhr.response = function(value) { - response = value; - return xhr; - }; - [ "get", "post" ].forEach(function(method) { - xhr[method] = function() { - return xhr.send.apply(xhr, [ method ].concat(d3_array(arguments))); - }; - }); - xhr.send = function(method, data, callback) { - if (arguments.length === 2 && typeof data === "function") callback = data, data = null; - request.open(method, url, true); - if (mimeType != null && !("accept" in headers)) headers["accept"] = mimeType + ",*/*"; - if (request.setRequestHeader) for (var name in headers) request.setRequestHeader(name, headers[name]); - if (mimeType != null && request.overrideMimeType) request.overrideMimeType(mimeType); - if (responseType != null) request.responseType = responseType; - if (callback != null) xhr.on("error", callback).on("load", function(request) { - callback(null, request); - }); - dispatch.beforesend.call(xhr, request); - request.send(data == null ? null : data); - return xhr; - }; - xhr.abort = function() { - request.abort(); - return xhr; - }; - d3.rebind(xhr, dispatch, "on"); - return callback == null ? xhr : xhr.get(d3_xhr_fixCallback(callback)); - } - function d3_xhr_fixCallback(callback) { - return callback.length === 1 ? function(error, request) { - callback(error == null ? request : null); - } : callback; - } - function d3_xhrHasResponse(request) { - var type = request.responseType; - return type && type !== "text" ? request.response : request.responseText; - } - d3.dsv = function(delimiter, mimeType) { - var reFormat = new RegExp('["' + delimiter + "\n]"), delimiterCode = delimiter.charCodeAt(0); - function dsv(url, row, callback) { - if (arguments.length < 3) callback = row, row = null; - var xhr = d3_xhr(url, mimeType, row == null ? response : typedResponse(row), callback); - xhr.row = function(_) { - return arguments.length ? xhr.response((row = _) == null ? response : typedResponse(_)) : row; - }; - return xhr; - } - function response(request) { - return dsv.parse(request.responseText); - } - function typedResponse(f) { - return function(request) { - return dsv.parse(request.responseText, f); - }; - } - dsv.parse = function(text, f) { - var o; - return dsv.parseRows(text, function(row, i) { - if (o) return o(row, i - 1); - var a = new Function("d", "return {" + row.map(function(name, i) { - return JSON.stringify(name) + ": d[" + i + "]"; - }).join(",") + "}"); - o = f ? function(row, i) { - return f(a(row), i); - } : a; - }); - }; - dsv.parseRows = function(text, f) { - var EOL = {}, EOF = {}, rows = [], N = text.length, I = 0, n = 0, t, eol; - function token() { - if (I >= N) return EOF; - if (eol) return eol = false, EOL; - var j = I; - if (text.charCodeAt(j) === 34) { - var i = j; - while (i++ < N) { - if (text.charCodeAt(i) === 34) { - if (text.charCodeAt(i + 1) !== 34) break; - ++i; - } - } - I = i + 2; - var c = text.charCodeAt(i + 1); - if (c === 13) { - eol = true; - if (text.charCodeAt(i + 2) === 10) ++I; - } else if (c === 10) { - eol = true; - } - return text.slice(j + 1, i).replace(/""/g, '"'); - } - while (I < N) { - var c = text.charCodeAt(I++), k = 1; - if (c === 10) eol = true; else if (c === 13) { - eol = true; - if (text.charCodeAt(I) === 10) ++I, ++k; - } else if (c !== delimiterCode) continue; - return text.slice(j, I - k); - } - return text.slice(j); - } - while ((t = token()) !== EOF) { - var a = []; - while (t !== EOL && t !== EOF) { - a.push(t); - t = token(); - } - if (f && (a = f(a, n++)) == null) continue; - rows.push(a); - } - return rows; - }; - dsv.format = function(rows) { - if (Array.isArray(rows[0])) return dsv.formatRows(rows); - var fieldSet = new d3_Set(), fields = []; - rows.forEach(function(row) { - for (var field in row) { - if (!fieldSet.has(field)) { - fields.push(fieldSet.add(field)); - } - } - }); - return [ fields.map(formatValue).join(delimiter) ].concat(rows.map(function(row) { - return fields.map(function(field) { - return formatValue(row[field]); - }).join(delimiter); - })).join("\n"); - }; - dsv.formatRows = function(rows) { - return rows.map(formatRow).join("\n"); - }; - function formatRow(row) { - return row.map(formatValue).join(delimiter); - } - function formatValue(text) { - return reFormat.test(text) ? '"' + text.replace(/\"/g, '""') + '"' : text; - } - return dsv; - }; - d3.csv = d3.dsv(",", "text/csv"); - d3.tsv = d3.dsv(" ", "text/tab-separated-values"); - var d3_timer_queueHead, d3_timer_queueTail, d3_timer_interval, d3_timer_timeout, d3_timer_active, d3_timer_frame = this[d3_vendorSymbol(this, "requestAnimationFrame")] || function(callback) { - setTimeout(callback, 17); - }; - d3.timer = function(callback, delay, then) { - var n = arguments.length; - if (n < 2) delay = 0; - if (n < 3) then = Date.now(); - var time = then + delay, timer = { - c: callback, - t: time, - f: false, - n: null - }; - if (d3_timer_queueTail) d3_timer_queueTail.n = timer; else d3_timer_queueHead = timer; - d3_timer_queueTail = timer; - if (!d3_timer_interval) { - d3_timer_timeout = clearTimeout(d3_timer_timeout); - d3_timer_interval = 1; - d3_timer_frame(d3_timer_step); - } - }; - function d3_timer_step() { - var now = d3_timer_mark(), delay = d3_timer_sweep() - now; - if (delay > 24) { - if (isFinite(delay)) { - clearTimeout(d3_timer_timeout); - d3_timer_timeout = setTimeout(d3_timer_step, delay); - } - d3_timer_interval = 0; - } else { - d3_timer_interval = 1; - d3_timer_frame(d3_timer_step); - } - } - d3.timer.flush = function() { - d3_timer_mark(); - d3_timer_sweep(); - }; - function d3_timer_mark() { - var now = Date.now(); - d3_timer_active = d3_timer_queueHead; - while (d3_timer_active) { - if (now >= d3_timer_active.t) d3_timer_active.f = d3_timer_active.c(now - d3_timer_active.t); - d3_timer_active = d3_timer_active.n; - } - return now; - } - function d3_timer_sweep() { - var t0, t1 = d3_timer_queueHead, time = Infinity; - while (t1) { - if (t1.f) { - t1 = t0 ? t0.n = t1.n : d3_timer_queueHead = t1.n; - } else { - if (t1.t < time) time = t1.t; - t1 = (t0 = t1).n; - } - } - d3_timer_queueTail = t0; - return time; - } - function d3_format_precision(x, p) { - return p - (x ? Math.ceil(Math.log(x) / Math.LN10) : 1); - } - d3.round = function(x, n) { - return n ? Math.round(x * (n = Math.pow(10, n))) / n : Math.round(x); - }; - var d3_formatPrefixes = [ "y", "z", "a", "f", "p", "n", "µ", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y" ].map(d3_formatPrefix); - d3.formatPrefix = function(value, precision) { - var i = 0; - if (value) { - if (value < 0) value *= -1; - if (precision) value = d3.round(value, d3_format_precision(value, precision)); - i = 1 + Math.floor(1e-12 + Math.log(value) / Math.LN10); - i = Math.max(-24, Math.min(24, Math.floor((i - 1) / 3) * 3)); - } - return d3_formatPrefixes[8 + i / 3]; - }; - function d3_formatPrefix(d, i) { - var k = Math.pow(10, abs(8 - i) * 3); - return { - scale: i > 8 ? function(d) { - return d / k; - } : function(d) { - return d * k; - }, - symbol: d - }; - } - function d3_locale_numberFormat(locale) { - var locale_decimal = locale.decimal, locale_thousands = locale.thousands, locale_grouping = locale.grouping, locale_currency = locale.currency, formatGroup = locale_grouping && locale_thousands ? function(value, width) { - var i = value.length, t = [], j = 0, g = locale_grouping[0], length = 0; - while (i > 0 && g > 0) { - if (length + g + 1 > width) g = Math.max(1, width - length); - t.push(value.substring(i -= g, i + g)); - if ((length += g + 1) > width) break; - g = locale_grouping[j = (j + 1) % locale_grouping.length]; - } - return t.reverse().join(locale_thousands); - } : d3_identity; - return function(specifier) { - var match = d3_format_re.exec(specifier), fill = match[1] || " ", align = match[2] || ">", sign = match[3] || "-", symbol = match[4] || "", zfill = match[5], width = +match[6], comma = match[7], precision = match[8], type = match[9], scale = 1, prefix = "", suffix = "", integer = false, exponent = true; - if (precision) precision = +precision.substring(1); - if (zfill || fill === "0" && align === "=") { - zfill = fill = "0"; - align = "="; - } - switch (type) { - case "n": - comma = true; - type = "g"; - break; - - case "%": - scale = 100; - suffix = "%"; - type = "f"; - break; - - case "p": - scale = 100; - suffix = "%"; - type = "r"; - break; - - case "b": - case "o": - case "x": - case "X": - if (symbol === "#") prefix = "0" + type.toLowerCase(); - - case "c": - exponent = false; - - case "d": - integer = true; - precision = 0; - break; - - case "s": - scale = -1; - type = "r"; - break; - } - if (symbol === "$") prefix = locale_currency[0], suffix = locale_currency[1]; - if (type == "r" && !precision) type = "g"; - if (precision != null) { - if (type == "g") precision = Math.max(1, Math.min(21, precision)); else if (type == "e" || type == "f") precision = Math.max(0, Math.min(20, precision)); - } - type = d3_format_types.get(type) || d3_format_typeDefault; - var zcomma = zfill && comma; - return function(value) { - var fullSuffix = suffix; - if (integer && value % 1) return ""; - var negative = value < 0 || value === 0 && 1 / value < 0 ? (value = -value, "-") : sign === "-" ? "" : sign; - if (scale < 0) { - var unit = d3.formatPrefix(value, precision); - value = unit.scale(value); - fullSuffix = unit.symbol + suffix; - } else { - value *= scale; - } - value = type(value, precision); - var i = value.lastIndexOf("."), before, after; - if (i < 0) { - var j = exponent ? value.lastIndexOf("e") : -1; - if (j < 0) before = value, after = ""; else before = value.substring(0, j), after = value.substring(j); - } else { - before = value.substring(0, i); - after = locale_decimal + value.substring(i + 1); - } - if (!zfill && comma) before = formatGroup(before, Infinity); - var length = prefix.length + before.length + after.length + (zcomma ? 0 : negative.length), padding = length < width ? new Array(length = width - length + 1).join(fill) : ""; - if (zcomma) before = formatGroup(padding + before, padding.length ? width - after.length : Infinity); - negative += prefix; - value = before + after; - return (align === "<" ? negative + value + padding : align === ">" ? padding + negative + value : align === "^" ? padding.substring(0, length >>= 1) + negative + value + padding.substring(length) : negative + (zcomma ? value : padding + value)) + fullSuffix; - }; - }; - } - var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i; - var d3_format_types = d3.map({ - b: function(x) { - return x.toString(2); - }, - c: function(x) { - return String.fromCharCode(x); - }, - o: function(x) { - return x.toString(8); - }, - x: function(x) { - return x.toString(16); - }, - X: function(x) { - return x.toString(16).toUpperCase(); - }, - g: function(x, p) { - return x.toPrecision(p); - }, - e: function(x, p) { - return x.toExponential(p); - }, - f: function(x, p) { - return x.toFixed(p); - }, - r: function(x, p) { - return (x = d3.round(x, d3_format_precision(x, p))).toFixed(Math.max(0, Math.min(20, d3_format_precision(x * (1 + 1e-15), p)))); - } - }); - function d3_format_typeDefault(x) { - return x + ""; - } - var d3_time = d3.time = {}, d3_date = Date; - function d3_date_utc() { - this._ = new Date(arguments.length > 1 ? Date.UTC.apply(this, arguments) : arguments[0]); - } - d3_date_utc.prototype = { - getDate: function() { - return this._.getUTCDate(); - }, - getDay: function() { - return this._.getUTCDay(); - }, - getFullYear: function() { - return this._.getUTCFullYear(); - }, - getHours: function() { - return this._.getUTCHours(); - }, - getMilliseconds: function() { - return this._.getUTCMilliseconds(); - }, - getMinutes: function() { - return this._.getUTCMinutes(); - }, - getMonth: function() { - return this._.getUTCMonth(); - }, - getSeconds: function() { - return this._.getUTCSeconds(); - }, - getTime: function() { - return this._.getTime(); - }, - getTimezoneOffset: function() { - return 0; - }, - valueOf: function() { - return this._.valueOf(); - }, - setDate: function() { - d3_time_prototype.setUTCDate.apply(this._, arguments); - }, - setDay: function() { - d3_time_prototype.setUTCDay.apply(this._, arguments); - }, - setFullYear: function() { - d3_time_prototype.setUTCFullYear.apply(this._, arguments); - }, - setHours: function() { - d3_time_prototype.setUTCHours.apply(this._, arguments); - }, - setMilliseconds: function() { - d3_time_prototype.setUTCMilliseconds.apply(this._, arguments); - }, - setMinutes: function() { - d3_time_prototype.setUTCMinutes.apply(this._, arguments); - }, - setMonth: function() { - d3_time_prototype.setUTCMonth.apply(this._, arguments); - }, - setSeconds: function() { - d3_time_prototype.setUTCSeconds.apply(this._, arguments); - }, - setTime: function() { - d3_time_prototype.setTime.apply(this._, arguments); - } - }; - var d3_time_prototype = Date.prototype; - function d3_time_interval(local, step, number) { - function round(date) { - var d0 = local(date), d1 = offset(d0, 1); - return date - d0 < d1 - date ? d0 : d1; - } - function ceil(date) { - step(date = local(new d3_date(date - 1)), 1); - return date; - } - function offset(date, k) { - step(date = new d3_date(+date), k); - return date; - } - function range(t0, t1, dt) { - var time = ceil(t0), times = []; - if (dt > 1) { - while (time < t1) { - if (!(number(time) % dt)) times.push(new Date(+time)); - step(time, 1); - } - } else { - while (time < t1) times.push(new Date(+time)), step(time, 1); - } - return times; - } - function range_utc(t0, t1, dt) { - try { - d3_date = d3_date_utc; - var utc = new d3_date_utc(); - utc._ = t0; - return range(utc, t1, dt); - } finally { - d3_date = Date; - } - } - local.floor = local; - local.round = round; - local.ceil = ceil; - local.offset = offset; - local.range = range; - var utc = local.utc = d3_time_interval_utc(local); - utc.floor = utc; - utc.round = d3_time_interval_utc(round); - utc.ceil = d3_time_interval_utc(ceil); - utc.offset = d3_time_interval_utc(offset); - utc.range = range_utc; - return local; - } - function d3_time_interval_utc(method) { - return function(date, k) { - try { - d3_date = d3_date_utc; - var utc = new d3_date_utc(); - utc._ = date; - return method(utc, k)._; - } finally { - d3_date = Date; - } - }; - } - d3_time.year = d3_time_interval(function(date) { - date = d3_time.day(date); - date.setMonth(0, 1); - return date; - }, function(date, offset) { - date.setFullYear(date.getFullYear() + offset); - }, function(date) { - return date.getFullYear(); - }); - d3_time.years = d3_time.year.range; - d3_time.years.utc = d3_time.year.utc.range; - d3_time.day = d3_time_interval(function(date) { - var day = new d3_date(2e3, 0); - day.setFullYear(date.getFullYear(), date.getMonth(), date.getDate()); - return day; - }, function(date, offset) { - date.setDate(date.getDate() + offset); - }, function(date) { - return date.getDate() - 1; - }); - d3_time.days = d3_time.day.range; - d3_time.days.utc = d3_time.day.utc.range; - d3_time.dayOfYear = function(date) { - var year = d3_time.year(date); - return Math.floor((date - year - (date.getTimezoneOffset() - year.getTimezoneOffset()) * 6e4) / 864e5); - }; - [ "sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday" ].forEach(function(day, i) { - i = 7 - i; - var interval = d3_time[day] = d3_time_interval(function(date) { - (date = d3_time.day(date)).setDate(date.getDate() - (date.getDay() + i) % 7); - return date; - }, function(date, offset) { - date.setDate(date.getDate() + Math.floor(offset) * 7); - }, function(date) { - var day = d3_time.year(date).getDay(); - return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7) - (day !== i); - }); - d3_time[day + "s"] = interval.range; - d3_time[day + "s"].utc = interval.utc.range; - d3_time[day + "OfYear"] = function(date) { - var day = d3_time.year(date).getDay(); - return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7); - }; - }); - d3_time.week = d3_time.sunday; - d3_time.weeks = d3_time.sunday.range; - d3_time.weeks.utc = d3_time.sunday.utc.range; - d3_time.weekOfYear = d3_time.sundayOfYear; - function d3_locale_timeFormat(locale) { - var locale_dateTime = locale.dateTime, locale_date = locale.date, locale_time = locale.time, locale_periods = locale.periods, locale_days = locale.days, locale_shortDays = locale.shortDays, locale_months = locale.months, locale_shortMonths = locale.shortMonths; - function d3_time_format(template) { - var n = template.length; - function format(date) { - var string = [], i = -1, j = 0, c, p, f; - while (++i < n) { - if (template.charCodeAt(i) === 37) { - string.push(template.slice(j, i)); - if ((p = d3_time_formatPads[c = template.charAt(++i)]) != null) c = template.charAt(++i); - if (f = d3_time_formats[c]) c = f(date, p == null ? c === "e" ? " " : "0" : p); - string.push(c); - j = i + 1; - } - } - string.push(template.slice(j, i)); - return string.join(""); - } - format.parse = function(string) { - var d = { - y: 1900, - m: 0, - d: 1, - H: 0, - M: 0, - S: 0, - L: 0, - Z: null - }, i = d3_time_parse(d, template, string, 0); - if (i != string.length) return null; - if ("p" in d) d.H = d.H % 12 + d.p * 12; - var localZ = d.Z != null && d3_date !== d3_date_utc, date = new (localZ ? d3_date_utc : d3_date)(); - if ("j" in d) date.setFullYear(d.y, 0, d.j); else if ("w" in d && ("W" in d || "U" in d)) { - date.setFullYear(d.y, 0, 1); - date.setFullYear(d.y, 0, "W" in d ? (d.w + 6) % 7 + d.W * 7 - (date.getDay() + 5) % 7 : d.w + d.U * 7 - (date.getDay() + 6) % 7); - } else date.setFullYear(d.y, d.m, d.d); - date.setHours(d.H + (d.Z / 100 | 0), d.M + d.Z % 100, d.S, d.L); - return localZ ? date._ : date; - }; - format.toString = function() { - return template; - }; - return format; - } - function d3_time_parse(date, template, string, j) { - var c, p, t, i = 0, n = template.length, m = string.length; - while (i < n) { - if (j >= m) return -1; - c = template.charCodeAt(i++); - if (c === 37) { - t = template.charAt(i++); - p = d3_time_parsers[t in d3_time_formatPads ? template.charAt(i++) : t]; - if (!p || (j = p(date, string, j)) < 0) return -1; - } else if (c != string.charCodeAt(j++)) { - return -1; - } - } - return j; - } - d3_time_format.utc = function(template) { - var local = d3_time_format(template); - function format(date) { - try { - d3_date = d3_date_utc; - var utc = new d3_date(); - utc._ = date; - return local(utc); - } finally { - d3_date = Date; - } - } - format.parse = function(string) { - try { - d3_date = d3_date_utc; - var date = local.parse(string); - return date && date._; - } finally { - d3_date = Date; - } - }; - format.toString = local.toString; - return format; - }; - d3_time_format.multi = d3_time_format.utc.multi = d3_time_formatMulti; - var d3_time_periodLookup = d3.map(), d3_time_dayRe = d3_time_formatRe(locale_days), d3_time_dayLookup = d3_time_formatLookup(locale_days), d3_time_dayAbbrevRe = d3_time_formatRe(locale_shortDays), d3_time_dayAbbrevLookup = d3_time_formatLookup(locale_shortDays), d3_time_monthRe = d3_time_formatRe(locale_months), d3_time_monthLookup = d3_time_formatLookup(locale_months), d3_time_monthAbbrevRe = d3_time_formatRe(locale_shortMonths), d3_time_monthAbbrevLookup = d3_time_formatLookup(locale_shortMonths); - locale_periods.forEach(function(p, i) { - d3_time_periodLookup.set(p.toLowerCase(), i); - }); - var d3_time_formats = { - a: function(d) { - return locale_shortDays[d.getDay()]; - }, - A: function(d) { - return locale_days[d.getDay()]; - }, - b: function(d) { - return locale_shortMonths[d.getMonth()]; - }, - B: function(d) { - return locale_months[d.getMonth()]; - }, - c: d3_time_format(locale_dateTime), - d: function(d, p) { - return d3_time_formatPad(d.getDate(), p, 2); - }, - e: function(d, p) { - return d3_time_formatPad(d.getDate(), p, 2); - }, - H: function(d, p) { - return d3_time_formatPad(d.getHours(), p, 2); - }, - I: function(d, p) { - return d3_time_formatPad(d.getHours() % 12 || 12, p, 2); - }, - j: function(d, p) { - return d3_time_formatPad(1 + d3_time.dayOfYear(d), p, 3); - }, - L: function(d, p) { - return d3_time_formatPad(d.getMilliseconds(), p, 3); - }, - m: function(d, p) { - return d3_time_formatPad(d.getMonth() + 1, p, 2); - }, - M: function(d, p) { - return d3_time_formatPad(d.getMinutes(), p, 2); - }, - p: function(d) { - return locale_periods[+(d.getHours() >= 12)]; - }, - S: function(d, p) { - return d3_time_formatPad(d.getSeconds(), p, 2); - }, - U: function(d, p) { - return d3_time_formatPad(d3_time.sundayOfYear(d), p, 2); - }, - w: function(d) { - return d.getDay(); - }, - W: function(d, p) { - return d3_time_formatPad(d3_time.mondayOfYear(d), p, 2); - }, - x: d3_time_format(locale_date), - X: d3_time_format(locale_time), - y: function(d, p) { - return d3_time_formatPad(d.getFullYear() % 100, p, 2); - }, - Y: function(d, p) { - return d3_time_formatPad(d.getFullYear() % 1e4, p, 4); - }, - Z: d3_time_zone, - "%": function() { - return "%"; - } - }; - var d3_time_parsers = { - a: d3_time_parseWeekdayAbbrev, - A: d3_time_parseWeekday, - b: d3_time_parseMonthAbbrev, - B: d3_time_parseMonth, - c: d3_time_parseLocaleFull, - d: d3_time_parseDay, - e: d3_time_parseDay, - H: d3_time_parseHour24, - I: d3_time_parseHour24, - j: d3_time_parseDayOfYear, - L: d3_time_parseMilliseconds, - m: d3_time_parseMonthNumber, - M: d3_time_parseMinutes, - p: d3_time_parseAmPm, - S: d3_time_parseSeconds, - U: d3_time_parseWeekNumberSunday, - w: d3_time_parseWeekdayNumber, - W: d3_time_parseWeekNumberMonday, - x: d3_time_parseLocaleDate, - X: d3_time_parseLocaleTime, - y: d3_time_parseYear, - Y: d3_time_parseFullYear, - Z: d3_time_parseZone, - "%": d3_time_parseLiteralPercent - }; - function d3_time_parseWeekdayAbbrev(date, string, i) { - d3_time_dayAbbrevRe.lastIndex = 0; - var n = d3_time_dayAbbrevRe.exec(string.slice(i)); - return n ? (date.w = d3_time_dayAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; - } - function d3_time_parseWeekday(date, string, i) { - d3_time_dayRe.lastIndex = 0; - var n = d3_time_dayRe.exec(string.slice(i)); - return n ? (date.w = d3_time_dayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; - } - function d3_time_parseMonthAbbrev(date, string, i) { - d3_time_monthAbbrevRe.lastIndex = 0; - var n = d3_time_monthAbbrevRe.exec(string.slice(i)); - return n ? (date.m = d3_time_monthAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; - } - function d3_time_parseMonth(date, string, i) { - d3_time_monthRe.lastIndex = 0; - var n = d3_time_monthRe.exec(string.slice(i)); - return n ? (date.m = d3_time_monthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; - } - function d3_time_parseLocaleFull(date, string, i) { - return d3_time_parse(date, d3_time_formats.c.toString(), string, i); - } - function d3_time_parseLocaleDate(date, string, i) { - return d3_time_parse(date, d3_time_formats.x.toString(), string, i); - } - function d3_time_parseLocaleTime(date, string, i) { - return d3_time_parse(date, d3_time_formats.X.toString(), string, i); - } - function d3_time_parseAmPm(date, string, i) { - var n = d3_time_periodLookup.get(string.slice(i, i += 2).toLowerCase()); - return n == null ? -1 : (date.p = n, i); - } - return d3_time_format; - } - var d3_time_formatPads = { - "-": "", - _: " ", - "0": "0" - }, d3_time_numberRe = /^\s*\d+/, d3_time_percentRe = /^%/; - function d3_time_formatPad(value, fill, width) { - var sign = value < 0 ? "-" : "", string = (sign ? -value : value) + "", length = string.length; - return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string); - } - function d3_time_formatRe(names) { - return new RegExp("^(?:" + names.map(d3.requote).join("|") + ")", "i"); - } - function d3_time_formatLookup(names) { - var map = new d3_Map(), i = -1, n = names.length; - while (++i < n) map.set(names[i].toLowerCase(), i); - return map; - } - function d3_time_parseWeekdayNumber(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 1)); - return n ? (date.w = +n[0], i + n[0].length) : -1; - } - function d3_time_parseWeekNumberSunday(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i)); - return n ? (date.U = +n[0], i + n[0].length) : -1; - } - function d3_time_parseWeekNumberMonday(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i)); - return n ? (date.W = +n[0], i + n[0].length) : -1; - } - function d3_time_parseFullYear(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 4)); - return n ? (date.y = +n[0], i + n[0].length) : -1; - } - function d3_time_parseYear(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 2)); - return n ? (date.y = d3_time_expandYear(+n[0]), i + n[0].length) : -1; - } - function d3_time_parseZone(date, string, i) { - return /^[+-]\d{4}$/.test(string = string.slice(i, i + 5)) ? (date.Z = -string, - i + 5) : -1; - } - function d3_time_expandYear(d) { - return d + (d > 68 ? 1900 : 2e3); - } - function d3_time_parseMonthNumber(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 2)); - return n ? (date.m = n[0] - 1, i + n[0].length) : -1; - } - function d3_time_parseDay(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 2)); - return n ? (date.d = +n[0], i + n[0].length) : -1; - } - function d3_time_parseDayOfYear(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 3)); - return n ? (date.j = +n[0], i + n[0].length) : -1; - } - function d3_time_parseHour24(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 2)); - return n ? (date.H = +n[0], i + n[0].length) : -1; - } - function d3_time_parseMinutes(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 2)); - return n ? (date.M = +n[0], i + n[0].length) : -1; - } - function d3_time_parseSeconds(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 2)); - return n ? (date.S = +n[0], i + n[0].length) : -1; - } - function d3_time_parseMilliseconds(date, string, i) { - d3_time_numberRe.lastIndex = 0; - var n = d3_time_numberRe.exec(string.slice(i, i + 3)); - return n ? (date.L = +n[0], i + n[0].length) : -1; - } - function d3_time_zone(d) { - var z = d.getTimezoneOffset(), zs = z > 0 ? "-" : "+", zh = abs(z) / 60 | 0, zm = abs(z) % 60; - return zs + d3_time_formatPad(zh, "0", 2) + d3_time_formatPad(zm, "0", 2); - } - function d3_time_parseLiteralPercent(date, string, i) { - d3_time_percentRe.lastIndex = 0; - var n = d3_time_percentRe.exec(string.slice(i, i + 1)); - return n ? i + n[0].length : -1; - } - function d3_time_formatMulti(formats) { - var n = formats.length, i = -1; - while (++i < n) formats[i][0] = this(formats[i][0]); - return function(date) { - var i = 0, f = formats[i]; - while (!f[1](date)) f = formats[++i]; - return f[0](date); - }; - } - d3.locale = function(locale) { - return { - numberFormat: d3_locale_numberFormat(locale), - timeFormat: d3_locale_timeFormat(locale) - }; - }; - var d3_locale_enUS = d3.locale({ - decimal: ".", - thousands: ",", - grouping: [ 3 ], - currency: [ "$", "" ], - dateTime: "%a %b %e %X %Y", - date: "%m/%d/%Y", - time: "%H:%M:%S", - periods: [ "AM", "PM" ], - days: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], - shortDays: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], - months: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ], - shortMonths: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ] - }); - d3.format = d3_locale_enUS.numberFormat; - d3.geo = {}; - function d3_adder() {} - d3_adder.prototype = { - s: 0, - t: 0, - add: function(y) { - d3_adderSum(y, this.t, d3_adderTemp); - d3_adderSum(d3_adderTemp.s, this.s, this); - if (this.s) this.t += d3_adderTemp.t; else this.s = d3_adderTemp.t; - }, - reset: function() { - this.s = this.t = 0; - }, - valueOf: function() { - return this.s; - } - }; - var d3_adderTemp = new d3_adder(); - function d3_adderSum(a, b, o) { - var x = o.s = a + b, bv = x - a, av = x - bv; - o.t = a - av + (b - bv); - } - d3.geo.stream = function(object, listener) { - if (object && d3_geo_streamObjectType.hasOwnProperty(object.type)) { - d3_geo_streamObjectType[object.type](object, listener); - } else { - d3_geo_streamGeometry(object, listener); - } - }; - function d3_geo_streamGeometry(geometry, listener) { - if (geometry && d3_geo_streamGeometryType.hasOwnProperty(geometry.type)) { - d3_geo_streamGeometryType[geometry.type](geometry, listener); - } - } - var d3_geo_streamObjectType = { - Feature: function(feature, listener) { - d3_geo_streamGeometry(feature.geometry, listener); - }, - FeatureCollection: function(object, listener) { - var features = object.features, i = -1, n = features.length; - while (++i < n) d3_geo_streamGeometry(features[i].geometry, listener); - } - }; - var d3_geo_streamGeometryType = { - Sphere: function(object, listener) { - listener.sphere(); - }, - Point: function(object, listener) { - object = object.coordinates; - listener.point(object[0], object[1], object[2]); - }, - MultiPoint: function(object, listener) { - var coordinates = object.coordinates, i = -1, n = coordinates.length; - while (++i < n) object = coordinates[i], listener.point(object[0], object[1], object[2]); - }, - LineString: function(object, listener) { - d3_geo_streamLine(object.coordinates, listener, 0); - }, - MultiLineString: function(object, listener) { - var coordinates = object.coordinates, i = -1, n = coordinates.length; - while (++i < n) d3_geo_streamLine(coordinates[i], listener, 0); - }, - Polygon: function(object, listener) { - d3_geo_streamPolygon(object.coordinates, listener); - }, - MultiPolygon: function(object, listener) { - var coordinates = object.coordinates, i = -1, n = coordinates.length; - while (++i < n) d3_geo_streamPolygon(coordinates[i], listener); - }, - GeometryCollection: function(object, listener) { - var geometries = object.geometries, i = -1, n = geometries.length; - while (++i < n) d3_geo_streamGeometry(geometries[i], listener); - } - }; - function d3_geo_streamLine(coordinates, listener, closed) { - var i = -1, n = coordinates.length - closed, coordinate; - listener.lineStart(); - while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1], coordinate[2]); - listener.lineEnd(); - } - function d3_geo_streamPolygon(coordinates, listener) { - var i = -1, n = coordinates.length; - listener.polygonStart(); - while (++i < n) d3_geo_streamLine(coordinates[i], listener, 1); - listener.polygonEnd(); - } - d3.geo.area = function(object) { - d3_geo_areaSum = 0; - d3.geo.stream(object, d3_geo_area); - return d3_geo_areaSum; - }; - var d3_geo_areaSum, d3_geo_areaRingSum = new d3_adder(); - var d3_geo_area = { - sphere: function() { - d3_geo_areaSum += 4 * π; - }, - point: d3_noop, - lineStart: d3_noop, - lineEnd: d3_noop, - polygonStart: function() { - d3_geo_areaRingSum.reset(); - d3_geo_area.lineStart = d3_geo_areaRingStart; - }, - polygonEnd: function() { - var area = 2 * d3_geo_areaRingSum; - d3_geo_areaSum += area < 0 ? 4 * π + area : area; - d3_geo_area.lineStart = d3_geo_area.lineEnd = d3_geo_area.point = d3_noop; - } - }; - function d3_geo_areaRingStart() { - var λ00, φ00, λ0, cosφ0, sinφ0; - d3_geo_area.point = function(λ, φ) { - d3_geo_area.point = nextPoint; - λ0 = (λ00 = λ) * d3_radians, cosφ0 = Math.cos(φ = (φ00 = φ) * d3_radians / 2 + π / 4), - sinφ0 = Math.sin(φ); - }; - function nextPoint(λ, φ) { - λ *= d3_radians; - φ = φ * d3_radians / 2 + π / 4; - var dλ = λ - λ0, sdλ = dλ >= 0 ? 1 : -1, adλ = sdλ * dλ, cosφ = Math.cos(φ), sinφ = Math.sin(φ), k = sinφ0 * sinφ, u = cosφ0 * cosφ + k * Math.cos(adλ), v = k * sdλ * Math.sin(adλ); - d3_geo_areaRingSum.add(Math.atan2(v, u)); - λ0 = λ, cosφ0 = cosφ, sinφ0 = sinφ; - } - d3_geo_area.lineEnd = function() { - nextPoint(λ00, φ00); - }; - } - function d3_geo_cartesian(spherical) { - var λ = spherical[0], φ = spherical[1], cosφ = Math.cos(φ); - return [ cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ) ]; - } - function d3_geo_cartesianDot(a, b) { - return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; - } - function d3_geo_cartesianCross(a, b) { - return [ a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0] ]; - } - function d3_geo_cartesianAdd(a, b) { - a[0] += b[0]; - a[1] += b[1]; - a[2] += b[2]; - } - function d3_geo_cartesianScale(vector, k) { - return [ vector[0] * k, vector[1] * k, vector[2] * k ]; - } - function d3_geo_cartesianNormalize(d) { - var l = Math.sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]); - d[0] /= l; - d[1] /= l; - d[2] /= l; - } - function d3_geo_spherical(cartesian) { - return [ Math.atan2(cartesian[1], cartesian[0]), d3_asin(cartesian[2]) ]; - } - function d3_geo_sphericalEqual(a, b) { - return abs(a[0] - b[0]) < ε && abs(a[1] - b[1]) < ε; - } - d3.geo.bounds = function() { - var λ0, φ0, λ1, φ1, λ_, λ__, φ__, p0, dλSum, ranges, range; - var bound = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { - bound.point = ringPoint; - bound.lineStart = ringStart; - bound.lineEnd = ringEnd; - dλSum = 0; - d3_geo_area.polygonStart(); - }, - polygonEnd: function() { - d3_geo_area.polygonEnd(); - bound.point = point; - bound.lineStart = lineStart; - bound.lineEnd = lineEnd; - if (d3_geo_areaRingSum < 0) λ0 = -(λ1 = 180), φ0 = -(φ1 = 90); else if (dλSum > ε) φ1 = 90; else if (dλSum < -ε) φ0 = -90; - range[0] = λ0, range[1] = λ1; - } - }; - function point(λ, φ) { - ranges.push(range = [ λ0 = λ, λ1 = λ ]); - if (φ < φ0) φ0 = φ; - if (φ > φ1) φ1 = φ; - } - function linePoint(λ, φ) { - var p = d3_geo_cartesian([ λ * d3_radians, φ * d3_radians ]); - if (p0) { - var normal = d3_geo_cartesianCross(p0, p), equatorial = [ normal[1], -normal[0], 0 ], inflection = d3_geo_cartesianCross(equatorial, normal); - d3_geo_cartesianNormalize(inflection); - inflection = d3_geo_spherical(inflection); - var dλ = λ - λ_, s = dλ > 0 ? 1 : -1, λi = inflection[0] * d3_degrees * s, antimeridian = abs(dλ) > 180; - if (antimeridian ^ (s * λ_ < λi && λi < s * λ)) { - var φi = inflection[1] * d3_degrees; - if (φi > φ1) φ1 = φi; - } else if (λi = (λi + 360) % 360 - 180, antimeridian ^ (s * λ_ < λi && λi < s * λ)) { - var φi = -inflection[1] * d3_degrees; - if (φi < φ0) φ0 = φi; - } else { - if (φ < φ0) φ0 = φ; - if (φ > φ1) φ1 = φ; - } - if (antimeridian) { - if (λ < λ_) { - if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ; - } else { - if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ; - } - } else { - if (λ1 >= λ0) { - if (λ < λ0) λ0 = λ; - if (λ > λ1) λ1 = λ; - } else { - if (λ > λ_) { - if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ; - } else { - if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ; - } - } - } - } else { - point(λ, φ); - } - p0 = p, λ_ = λ; - } - function lineStart() { - bound.point = linePoint; - } - function lineEnd() { - range[0] = λ0, range[1] = λ1; - bound.point = point; - p0 = null; - } - function ringPoint(λ, φ) { - if (p0) { - var dλ = λ - λ_; - dλSum += abs(dλ) > 180 ? dλ + (dλ > 0 ? 360 : -360) : dλ; - } else λ__ = λ, φ__ = φ; - d3_geo_area.point(λ, φ); - linePoint(λ, φ); - } - function ringStart() { - d3_geo_area.lineStart(); - } - function ringEnd() { - ringPoint(λ__, φ__); - d3_geo_area.lineEnd(); - if (abs(dλSum) > ε) λ0 = -(λ1 = 180); - range[0] = λ0, range[1] = λ1; - p0 = null; - } - function angle(λ0, λ1) { - return (λ1 -= λ0) < 0 ? λ1 + 360 : λ1; - } - function compareRanges(a, b) { - return a[0] - b[0]; - } - function withinRange(x, range) { - return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x; - } - return function(feature) { - φ1 = λ1 = -(λ0 = φ0 = Infinity); - ranges = []; - d3.geo.stream(feature, bound); - var n = ranges.length; - if (n) { - ranges.sort(compareRanges); - for (var i = 1, a = ranges[0], b, merged = [ a ]; i < n; ++i) { - b = ranges[i]; - if (withinRange(b[0], a) || withinRange(b[1], a)) { - if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1]; - if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0]; - } else { - merged.push(a = b); - } - } - var best = -Infinity, dλ; - for (var n = merged.length - 1, i = 0, a = merged[n], b; i <= n; a = b, ++i) { - b = merged[i]; - if ((dλ = angle(a[1], b[0])) > best) best = dλ, λ0 = b[0], λ1 = a[1]; - } - } - ranges = range = null; - return λ0 === Infinity || φ0 === Infinity ? [ [ NaN, NaN ], [ NaN, NaN ] ] : [ [ λ0, φ0 ], [ λ1, φ1 ] ]; - }; - }(); - d3.geo.centroid = function(object) { - d3_geo_centroidW0 = d3_geo_centroidW1 = d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0; - d3.geo.stream(object, d3_geo_centroid); - var x = d3_geo_centroidX2, y = d3_geo_centroidY2, z = d3_geo_centroidZ2, m = x * x + y * y + z * z; - if (m < ε2) { - x = d3_geo_centroidX1, y = d3_geo_centroidY1, z = d3_geo_centroidZ1; - if (d3_geo_centroidW1 < ε) x = d3_geo_centroidX0, y = d3_geo_centroidY0, z = d3_geo_centroidZ0; - m = x * x + y * y + z * z; - if (m < ε2) return [ NaN, NaN ]; - } - return [ Math.atan2(y, x) * d3_degrees, d3_asin(z / Math.sqrt(m)) * d3_degrees ]; - }; - var d3_geo_centroidW0, d3_geo_centroidW1, d3_geo_centroidX0, d3_geo_centroidY0, d3_geo_centroidZ0, d3_geo_centroidX1, d3_geo_centroidY1, d3_geo_centroidZ1, d3_geo_centroidX2, d3_geo_centroidY2, d3_geo_centroidZ2; - var d3_geo_centroid = { - sphere: d3_noop, - point: d3_geo_centroidPoint, - lineStart: d3_geo_centroidLineStart, - lineEnd: d3_geo_centroidLineEnd, - polygonStart: function() { - d3_geo_centroid.lineStart = d3_geo_centroidRingStart; - }, - polygonEnd: function() { - d3_geo_centroid.lineStart = d3_geo_centroidLineStart; - } - }; - function d3_geo_centroidPoint(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians); - d3_geo_centroidPointXYZ(cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ)); - } - function d3_geo_centroidPointXYZ(x, y, z) { - ++d3_geo_centroidW0; - d3_geo_centroidX0 += (x - d3_geo_centroidX0) / d3_geo_centroidW0; - d3_geo_centroidY0 += (y - d3_geo_centroidY0) / d3_geo_centroidW0; - d3_geo_centroidZ0 += (z - d3_geo_centroidZ0) / d3_geo_centroidW0; - } - function d3_geo_centroidLineStart() { - var x0, y0, z0; - d3_geo_centroid.point = function(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians); - x0 = cosφ * Math.cos(λ); - y0 = cosφ * Math.sin(λ); - z0 = Math.sin(φ); - d3_geo_centroid.point = nextPoint; - d3_geo_centroidPointXYZ(x0, y0, z0); - }; - function nextPoint(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), w = Math.atan2(Math.sqrt((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z); - d3_geo_centroidW1 += w; - d3_geo_centroidX1 += w * (x0 + (x0 = x)); - d3_geo_centroidY1 += w * (y0 + (y0 = y)); - d3_geo_centroidZ1 += w * (z0 + (z0 = z)); - d3_geo_centroidPointXYZ(x0, y0, z0); - } - } - function d3_geo_centroidLineEnd() { - d3_geo_centroid.point = d3_geo_centroidPoint; - } - function d3_geo_centroidRingStart() { - var λ00, φ00, x0, y0, z0; - d3_geo_centroid.point = function(λ, φ) { - λ00 = λ, φ00 = φ; - d3_geo_centroid.point = nextPoint; - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians); - x0 = cosφ * Math.cos(λ); - y0 = cosφ * Math.sin(λ); - z0 = Math.sin(φ); - d3_geo_centroidPointXYZ(x0, y0, z0); - }; - d3_geo_centroid.lineEnd = function() { - nextPoint(λ00, φ00); - d3_geo_centroid.lineEnd = d3_geo_centroidLineEnd; - d3_geo_centroid.point = d3_geo_centroidPoint; - }; - function nextPoint(λ, φ) { - λ *= d3_radians; - var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), cx = y0 * z - z0 * y, cy = z0 * x - x0 * z, cz = x0 * y - y0 * x, m = Math.sqrt(cx * cx + cy * cy + cz * cz), u = x0 * x + y0 * y + z0 * z, v = m && -d3_acos(u) / m, w = Math.atan2(m, u); - d3_geo_centroidX2 += v * cx; - d3_geo_centroidY2 += v * cy; - d3_geo_centroidZ2 += v * cz; - d3_geo_centroidW1 += w; - d3_geo_centroidX1 += w * (x0 + (x0 = x)); - d3_geo_centroidY1 += w * (y0 + (y0 = y)); - d3_geo_centroidZ1 += w * (z0 + (z0 = z)); - d3_geo_centroidPointXYZ(x0, y0, z0); - } - } - function d3_geo_compose(a, b) { - function compose(x, y) { - return x = a(x, y), b(x[0], x[1]); - } - if (a.invert && b.invert) compose.invert = function(x, y) { - return x = b.invert(x, y), x && a.invert(x[0], x[1]); - }; - return compose; - } - function d3_true() { - return true; - } - function d3_geo_clipPolygon(segments, compare, clipStartInside, interpolate, listener) { - var subject = [], clip = []; - segments.forEach(function(segment) { - if ((n = segment.length - 1) <= 0) return; - var n, p0 = segment[0], p1 = segment[n]; - if (d3_geo_sphericalEqual(p0, p1)) { - listener.lineStart(); - for (var i = 0; i < n; ++i) listener.point((p0 = segment[i])[0], p0[1]); - listener.lineEnd(); - return; - } - var a = new d3_geo_clipPolygonIntersection(p0, segment, null, true), b = new d3_geo_clipPolygonIntersection(p0, null, a, false); - a.o = b; - subject.push(a); - clip.push(b); - a = new d3_geo_clipPolygonIntersection(p1, segment, null, false); - b = new d3_geo_clipPolygonIntersection(p1, null, a, true); - a.o = b; - subject.push(a); - clip.push(b); - }); - clip.sort(compare); - d3_geo_clipPolygonLinkCircular(subject); - d3_geo_clipPolygonLinkCircular(clip); - if (!subject.length) return; - for (var i = 0, entry = clipStartInside, n = clip.length; i < n; ++i) { - clip[i].e = entry = !entry; - } - var start = subject[0], points, point; - while (1) { - var current = start, isSubject = true; - while (current.v) if ((current = current.n) === start) return; - points = current.z; - listener.lineStart(); - do { - current.v = current.o.v = true; - if (current.e) { - if (isSubject) { - for (var i = 0, n = points.length; i < n; ++i) listener.point((point = points[i])[0], point[1]); - } else { - interpolate(current.x, current.n.x, 1, listener); - } - current = current.n; - } else { - if (isSubject) { - points = current.p.z; - for (var i = points.length - 1; i >= 0; --i) listener.point((point = points[i])[0], point[1]); - } else { - interpolate(current.x, current.p.x, -1, listener); - } - current = current.p; - } - current = current.o; - points = current.z; - isSubject = !isSubject; - } while (!current.v); - listener.lineEnd(); - } - } - function d3_geo_clipPolygonLinkCircular(array) { - if (!(n = array.length)) return; - var n, i = 0, a = array[0], b; - while (++i < n) { - a.n = b = array[i]; - b.p = a; - a = b; - } - a.n = b = array[0]; - b.p = a; - } - function d3_geo_clipPolygonIntersection(point, points, other, entry) { - this.x = point; - this.z = points; - this.o = other; - this.e = entry; - this.v = false; - this.n = this.p = null; - } - function d3_geo_clip(pointVisible, clipLine, interpolate, clipStart) { - return function(rotate, listener) { - var line = clipLine(listener), rotatedClipStart = rotate.invert(clipStart[0], clipStart[1]); - var clip = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { - clip.point = pointRing; - clip.lineStart = ringStart; - clip.lineEnd = ringEnd; - segments = []; - polygon = []; - }, - polygonEnd: function() { - clip.point = point; - clip.lineStart = lineStart; - clip.lineEnd = lineEnd; - segments = d3.merge(segments); - var clipStartInside = d3_geo_pointInPolygon(rotatedClipStart, polygon); - if (segments.length) { - if (!polygonStarted) listener.polygonStart(), polygonStarted = true; - d3_geo_clipPolygon(segments, d3_geo_clipSort, clipStartInside, interpolate, listener); - } else if (clipStartInside) { - if (!polygonStarted) listener.polygonStart(), polygonStarted = true; - listener.lineStart(); - interpolate(null, null, 1, listener); - listener.lineEnd(); - } - if (polygonStarted) listener.polygonEnd(), polygonStarted = false; - segments = polygon = null; - }, - sphere: function() { - listener.polygonStart(); - listener.lineStart(); - interpolate(null, null, 1, listener); - listener.lineEnd(); - listener.polygonEnd(); - } - }; - function point(λ, φ) { - var point = rotate(λ, φ); - if (pointVisible(λ = point[0], φ = point[1])) listener.point(λ, φ); - } - function pointLine(λ, φ) { - var point = rotate(λ, φ); - line.point(point[0], point[1]); - } - function lineStart() { - clip.point = pointLine; - line.lineStart(); - } - function lineEnd() { - clip.point = point; - line.lineEnd(); - } - var segments; - var buffer = d3_geo_clipBufferListener(), ringListener = clipLine(buffer), polygonStarted = false, polygon, ring; - function pointRing(λ, φ) { - ring.push([ λ, φ ]); - var point = rotate(λ, φ); - ringListener.point(point[0], point[1]); - } - function ringStart() { - ringListener.lineStart(); - ring = []; - } - function ringEnd() { - pointRing(ring[0][0], ring[0][1]); - ringListener.lineEnd(); - var clean = ringListener.clean(), ringSegments = buffer.buffer(), segment, n = ringSegments.length; - ring.pop(); - polygon.push(ring); - ring = null; - if (!n) return; - if (clean & 1) { - segment = ringSegments[0]; - var n = segment.length - 1, i = -1, point; - if (n > 0) { - if (!polygonStarted) listener.polygonStart(), polygonStarted = true; - listener.lineStart(); - while (++i < n) listener.point((point = segment[i])[0], point[1]); - listener.lineEnd(); - } - return; - } - if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift())); - segments.push(ringSegments.filter(d3_geo_clipSegmentLength1)); - } - return clip; - }; - } - function d3_geo_clipSegmentLength1(segment) { - return segment.length > 1; - } - function d3_geo_clipBufferListener() { - var lines = [], line; - return { - lineStart: function() { - lines.push(line = []); - }, - point: function(λ, φ) { - line.push([ λ, φ ]); - }, - lineEnd: d3_noop, - buffer: function() { - var buffer = lines; - lines = []; - line = null; - return buffer; - }, - rejoin: function() { - if (lines.length > 1) lines.push(lines.pop().concat(lines.shift())); - } - }; - } - function d3_geo_clipSort(a, b) { - return ((a = a.x)[0] < 0 ? a[1] - halfπ - ε : halfπ - a[1]) - ((b = b.x)[0] < 0 ? b[1] - halfπ - ε : halfπ - b[1]); - } - var d3_geo_clipAntimeridian = d3_geo_clip(d3_true, d3_geo_clipAntimeridianLine, d3_geo_clipAntimeridianInterpolate, [ -π, -π / 2 ]); - function d3_geo_clipAntimeridianLine(listener) { - var λ0 = NaN, φ0 = NaN, sλ0 = NaN, clean; - return { - lineStart: function() { - listener.lineStart(); - clean = 1; - }, - point: function(λ1, φ1) { - var sλ1 = λ1 > 0 ? π : -π, dλ = abs(λ1 - λ0); - if (abs(dλ - π) < ε) { - listener.point(λ0, φ0 = (φ0 + φ1) / 2 > 0 ? halfπ : -halfπ); - listener.point(sλ0, φ0); - listener.lineEnd(); - listener.lineStart(); - listener.point(sλ1, φ0); - listener.point(λ1, φ0); - clean = 0; - } else if (sλ0 !== sλ1 && dλ >= π) { - if (abs(λ0 - sλ0) < ε) λ0 -= sλ0 * ε; - if (abs(λ1 - sλ1) < ε) λ1 -= sλ1 * ε; - φ0 = d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1); - listener.point(sλ0, φ0); - listener.lineEnd(); - listener.lineStart(); - listener.point(sλ1, φ0); - clean = 0; - } - listener.point(λ0 = λ1, φ0 = φ1); - sλ0 = sλ1; - }, - lineEnd: function() { - listener.lineEnd(); - λ0 = φ0 = NaN; - }, - clean: function() { - return 2 - clean; - } - }; - } - function d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1) { - var cosφ0, cosφ1, sinλ0_λ1 = Math.sin(λ0 - λ1); - return abs(sinλ0_λ1) > ε ? Math.atan((Math.sin(φ0) * (cosφ1 = Math.cos(φ1)) * Math.sin(λ1) - Math.sin(φ1) * (cosφ0 = Math.cos(φ0)) * Math.sin(λ0)) / (cosφ0 * cosφ1 * sinλ0_λ1)) : (φ0 + φ1) / 2; - } - function d3_geo_clipAntimeridianInterpolate(from, to, direction, listener) { - var φ; - if (from == null) { - φ = direction * halfπ; - listener.point(-π, φ); - listener.point(0, φ); - listener.point(π, φ); - listener.point(π, 0); - listener.point(π, -φ); - listener.point(0, -φ); - listener.point(-π, -φ); - listener.point(-π, 0); - listener.point(-π, φ); - } else if (abs(from[0] - to[0]) > ε) { - var s = from[0] < to[0] ? π : -π; - φ = direction * s / 2; - listener.point(-s, φ); - listener.point(0, φ); - listener.point(s, φ); - } else { - listener.point(to[0], to[1]); - } - } - function d3_geo_pointInPolygon(point, polygon) { - var meridian = point[0], parallel = point[1], meridianNormal = [ Math.sin(meridian), -Math.cos(meridian), 0 ], polarAngle = 0, winding = 0; - d3_geo_areaRingSum.reset(); - for (var i = 0, n = polygon.length; i < n; ++i) { - var ring = polygon[i], m = ring.length; - if (!m) continue; - var point0 = ring[0], λ0 = point0[0], φ0 = point0[1] / 2 + π / 4, sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), j = 1; - while (true) { - if (j === m) j = 0; - point = ring[j]; - var λ = point[0], φ = point[1] / 2 + π / 4, sinφ = Math.sin(φ), cosφ = Math.cos(φ), dλ = λ - λ0, sdλ = dλ >= 0 ? 1 : -1, adλ = sdλ * dλ, antimeridian = adλ > π, k = sinφ0 * sinφ; - d3_geo_areaRingSum.add(Math.atan2(k * sdλ * Math.sin(adλ), cosφ0 * cosφ + k * Math.cos(adλ))); - polarAngle += antimeridian ? dλ + sdλ * τ : dλ; - if (antimeridian ^ λ0 >= meridian ^ λ >= meridian) { - var arc = d3_geo_cartesianCross(d3_geo_cartesian(point0), d3_geo_cartesian(point)); - d3_geo_cartesianNormalize(arc); - var intersection = d3_geo_cartesianCross(meridianNormal, arc); - d3_geo_cartesianNormalize(intersection); - var φarc = (antimeridian ^ dλ >= 0 ? -1 : 1) * d3_asin(intersection[2]); - if (parallel > φarc || parallel === φarc && (arc[0] || arc[1])) { - winding += antimeridian ^ dλ >= 0 ? 1 : -1; - } - } - if (!j++) break; - λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ, point0 = point; - } - } - return (polarAngle < -ε || polarAngle < ε && d3_geo_areaRingSum < 0) ^ winding & 1; - } - function d3_geo_clipCircle(radius) { - var cr = Math.cos(radius), smallRadius = cr > 0, notHemisphere = abs(cr) > ε, interpolate = d3_geo_circleInterpolate(radius, 6 * d3_radians); - return d3_geo_clip(visible, clipLine, interpolate, smallRadius ? [ 0, -radius ] : [ -π, radius - π ]); - function visible(λ, φ) { - return Math.cos(λ) * Math.cos(φ) > cr; - } - function clipLine(listener) { - var point0, c0, v0, v00, clean; - return { - lineStart: function() { - v00 = v0 = false; - clean = 1; - }, - point: function(λ, φ) { - var point1 = [ λ, φ ], point2, v = visible(λ, φ), c = smallRadius ? v ? 0 : code(λ, φ) : v ? code(λ + (λ < 0 ? π : -π), φ) : 0; - if (!point0 && (v00 = v0 = v)) listener.lineStart(); - if (v !== v0) { - point2 = intersect(point0, point1); - if (d3_geo_sphericalEqual(point0, point2) || d3_geo_sphericalEqual(point1, point2)) { - point1[0] += ε; - point1[1] += ε; - v = visible(point1[0], point1[1]); - } - } - if (v !== v0) { - clean = 0; - if (v) { - listener.lineStart(); - point2 = intersect(point1, point0); - listener.point(point2[0], point2[1]); - } else { - point2 = intersect(point0, point1); - listener.point(point2[0], point2[1]); - listener.lineEnd(); - } - point0 = point2; - } else if (notHemisphere && point0 && smallRadius ^ v) { - var t; - if (!(c & c0) && (t = intersect(point1, point0, true))) { - clean = 0; - if (smallRadius) { - listener.lineStart(); - listener.point(t[0][0], t[0][1]); - listener.point(t[1][0], t[1][1]); - listener.lineEnd(); - } else { - listener.point(t[1][0], t[1][1]); - listener.lineEnd(); - listener.lineStart(); - listener.point(t[0][0], t[0][1]); - } - } - } - if (v && (!point0 || !d3_geo_sphericalEqual(point0, point1))) { - listener.point(point1[0], point1[1]); - } - point0 = point1, v0 = v, c0 = c; - }, - lineEnd: function() { - if (v0) listener.lineEnd(); - point0 = null; - }, - clean: function() { - return clean | (v00 && v0) << 1; - } - }; - } - function intersect(a, b, two) { - var pa = d3_geo_cartesian(a), pb = d3_geo_cartesian(b); - var n1 = [ 1, 0, 0 ], n2 = d3_geo_cartesianCross(pa, pb), n2n2 = d3_geo_cartesianDot(n2, n2), n1n2 = n2[0], determinant = n2n2 - n1n2 * n1n2; - if (!determinant) return !two && a; - var c1 = cr * n2n2 / determinant, c2 = -cr * n1n2 / determinant, n1xn2 = d3_geo_cartesianCross(n1, n2), A = d3_geo_cartesianScale(n1, c1), B = d3_geo_cartesianScale(n2, c2); - d3_geo_cartesianAdd(A, B); - var u = n1xn2, w = d3_geo_cartesianDot(A, u), uu = d3_geo_cartesianDot(u, u), t2 = w * w - uu * (d3_geo_cartesianDot(A, A) - 1); - if (t2 < 0) return; - var t = Math.sqrt(t2), q = d3_geo_cartesianScale(u, (-w - t) / uu); - d3_geo_cartesianAdd(q, A); - q = d3_geo_spherical(q); - if (!two) return q; - var λ0 = a[0], λ1 = b[0], φ0 = a[1], φ1 = b[1], z; - if (λ1 < λ0) z = λ0, λ0 = λ1, λ1 = z; - var δλ = λ1 - λ0, polar = abs(δλ - π) < ε, meridian = polar || δλ < ε; - if (!polar && φ1 < φ0) z = φ0, φ0 = φ1, φ1 = z; - if (meridian ? polar ? φ0 + φ1 > 0 ^ q[1] < (abs(q[0] - λ0) < ε ? φ0 : φ1) : φ0 <= q[1] && q[1] <= φ1 : δλ > π ^ (λ0 <= q[0] && q[0] <= λ1)) { - var q1 = d3_geo_cartesianScale(u, (-w + t) / uu); - d3_geo_cartesianAdd(q1, A); - return [ q, d3_geo_spherical(q1) ]; - } - } - function code(λ, φ) { - var r = smallRadius ? radius : π - radius, code = 0; - if (λ < -r) code |= 1; else if (λ > r) code |= 2; - if (φ < -r) code |= 4; else if (φ > r) code |= 8; - return code; - } - } - function d3_geom_clipLine(x0, y0, x1, y1) { - return function(line) { - var a = line.a, b = line.b, ax = a.x, ay = a.y, bx = b.x, by = b.y, t0 = 0, t1 = 1, dx = bx - ax, dy = by - ay, r; - r = x0 - ax; - if (!dx && r > 0) return; - r /= dx; - if (dx < 0) { - if (r < t0) return; - if (r < t1) t1 = r; - } else if (dx > 0) { - if (r > t1) return; - if (r > t0) t0 = r; - } - r = x1 - ax; - if (!dx && r < 0) return; - r /= dx; - if (dx < 0) { - if (r > t1) return; - if (r > t0) t0 = r; - } else if (dx > 0) { - if (r < t0) return; - if (r < t1) t1 = r; - } - r = y0 - ay; - if (!dy && r > 0) return; - r /= dy; - if (dy < 0) { - if (r < t0) return; - if (r < t1) t1 = r; - } else if (dy > 0) { - if (r > t1) return; - if (r > t0) t0 = r; - } - r = y1 - ay; - if (!dy && r < 0) return; - r /= dy; - if (dy < 0) { - if (r > t1) return; - if (r > t0) t0 = r; - } else if (dy > 0) { - if (r < t0) return; - if (r < t1) t1 = r; - } - if (t0 > 0) line.a = { - x: ax + t0 * dx, - y: ay + t0 * dy - }; - if (t1 < 1) line.b = { - x: ax + t1 * dx, - y: ay + t1 * dy - }; - return line; - }; - } - var d3_geo_clipExtentMAX = 1e9; - d3.geo.clipExtent = function() { - var x0, y0, x1, y1, stream, clip, clipExtent = { - stream: function(output) { - if (stream) stream.valid = false; - stream = clip(output); - stream.valid = true; - return stream; - }, - extent: function(_) { - if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ]; - clip = d3_geo_clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]); - if (stream) stream.valid = false, stream = null; - return clipExtent; - } - }; - return clipExtent.extent([ [ 0, 0 ], [ 960, 500 ] ]); - }; - function d3_geo_clipExtent(x0, y0, x1, y1) { - return function(listener) { - var listener_ = listener, bufferListener = d3_geo_clipBufferListener(), clipLine = d3_geom_clipLine(x0, y0, x1, y1), segments, polygon, ring; - var clip = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { - listener = bufferListener; - segments = []; - polygon = []; - clean = true; - }, - polygonEnd: function() { - listener = listener_; - segments = d3.merge(segments); - var clipStartInside = insidePolygon([ x0, y1 ]), inside = clean && clipStartInside, visible = segments.length; - if (inside || visible) { - listener.polygonStart(); - if (inside) { - listener.lineStart(); - interpolate(null, null, 1, listener); - listener.lineEnd(); - } - if (visible) { - d3_geo_clipPolygon(segments, compare, clipStartInside, interpolate, listener); - } - listener.polygonEnd(); - } - segments = polygon = ring = null; - } - }; - function insidePolygon(p) { - var wn = 0, n = polygon.length, y = p[1]; - for (var i = 0; i < n; ++i) { - for (var j = 1, v = polygon[i], m = v.length, a = v[0], b; j < m; ++j) { - b = v[j]; - if (a[1] <= y) { - if (b[1] > y && d3_cross2d(a, b, p) > 0) ++wn; - } else { - if (b[1] <= y && d3_cross2d(a, b, p) < 0) --wn; - } - a = b; - } - } - return wn !== 0; - } - function interpolate(from, to, direction, listener) { - var a = 0, a1 = 0; - if (from == null || (a = corner(from, direction)) !== (a1 = corner(to, direction)) || comparePoints(from, to) < 0 ^ direction > 0) { - do { - listener.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0); - } while ((a = (a + direction + 4) % 4) !== a1); - } else { - listener.point(to[0], to[1]); - } - } - function pointVisible(x, y) { - return x0 <= x && x <= x1 && y0 <= y && y <= y1; - } - function point(x, y) { - if (pointVisible(x, y)) listener.point(x, y); - } - var x__, y__, v__, x_, y_, v_, first, clean; - function lineStart() { - clip.point = linePoint; - if (polygon) polygon.push(ring = []); - first = true; - v_ = false; - x_ = y_ = NaN; - } - function lineEnd() { - if (segments) { - linePoint(x__, y__); - if (v__ && v_) bufferListener.rejoin(); - segments.push(bufferListener.buffer()); - } - clip.point = point; - if (v_) listener.lineEnd(); - } - function linePoint(x, y) { - x = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, x)); - y = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, y)); - var v = pointVisible(x, y); - if (polygon) ring.push([ x, y ]); - if (first) { - x__ = x, y__ = y, v__ = v; - first = false; - if (v) { - listener.lineStart(); - listener.point(x, y); - } - } else { - if (v && v_) listener.point(x, y); else { - var l = { - a: { - x: x_, - y: y_ - }, - b: { - x: x, - y: y - } - }; - if (clipLine(l)) { - if (!v_) { - listener.lineStart(); - listener.point(l.a.x, l.a.y); - } - listener.point(l.b.x, l.b.y); - if (!v) listener.lineEnd(); - clean = false; - } else if (v) { - listener.lineStart(); - listener.point(x, y); - clean = false; - } - } - } - x_ = x, y_ = y, v_ = v; - } - return clip; - }; - function corner(p, direction) { - return abs(p[0] - x0) < ε ? direction > 0 ? 0 : 3 : abs(p[0] - x1) < ε ? direction > 0 ? 2 : 1 : abs(p[1] - y0) < ε ? direction > 0 ? 1 : 0 : direction > 0 ? 3 : 2; - } - function compare(a, b) { - return comparePoints(a.x, b.x); - } - function comparePoints(a, b) { - var ca = corner(a, 1), cb = corner(b, 1); - return ca !== cb ? ca - cb : ca === 0 ? b[1] - a[1] : ca === 1 ? a[0] - b[0] : ca === 2 ? a[1] - b[1] : b[0] - a[0]; - } - } - function d3_geo_conic(projectAt) { - var φ0 = 0, φ1 = π / 3, m = d3_geo_projectionMutator(projectAt), p = m(φ0, φ1); - p.parallels = function(_) { - if (!arguments.length) return [ φ0 / π * 180, φ1 / π * 180 ]; - return m(φ0 = _[0] * π / 180, φ1 = _[1] * π / 180); - }; - return p; - } - function d3_geo_conicEqualArea(φ0, φ1) { - var sinφ0 = Math.sin(φ0), n = (sinφ0 + Math.sin(φ1)) / 2, C = 1 + sinφ0 * (2 * n - sinφ0), ρ0 = Math.sqrt(C) / n; - function forward(λ, φ) { - var ρ = Math.sqrt(C - 2 * n * Math.sin(φ)) / n; - return [ ρ * Math.sin(λ *= n), ρ0 - ρ * Math.cos(λ) ]; - } - forward.invert = function(x, y) { - var ρ0_y = ρ0 - y; - return [ Math.atan2(x, ρ0_y) / n, d3_asin((C - (x * x + ρ0_y * ρ0_y) * n * n) / (2 * n)) ]; - }; - return forward; - } - (d3.geo.conicEqualArea = function() { - return d3_geo_conic(d3_geo_conicEqualArea); - }).raw = d3_geo_conicEqualArea; - d3.geo.albers = function() { - return d3.geo.conicEqualArea().rotate([ 96, 0 ]).center([ -.6, 38.7 ]).parallels([ 29.5, 45.5 ]).scale(1070); - }; - d3.geo.albersUsa = function() { - var lower48 = d3.geo.albers(); - var alaska = d3.geo.conicEqualArea().rotate([ 154, 0 ]).center([ -2, 58.5 ]).parallels([ 55, 65 ]); - var hawaii = d3.geo.conicEqualArea().rotate([ 157, 0 ]).center([ -3, 19.9 ]).parallels([ 8, 18 ]); - var point, pointStream = { - point: function(x, y) { - point = [ x, y ]; - } - }, lower48Point, alaskaPoint, hawaiiPoint; - function albersUsa(coordinates) { - var x = coordinates[0], y = coordinates[1]; - point = null; - (lower48Point(x, y), point) || (alaskaPoint(x, y), point) || hawaiiPoint(x, y); - return point; - } - albersUsa.invert = function(coordinates) { - var k = lower48.scale(), t = lower48.translate(), x = (coordinates[0] - t[0]) / k, y = (coordinates[1] - t[1]) / k; - return (y >= .12 && y < .234 && x >= -.425 && x < -.214 ? alaska : y >= .166 && y < .234 && x >= -.214 && x < -.115 ? hawaii : lower48).invert(coordinates); - }; - albersUsa.stream = function(stream) { - var lower48Stream = lower48.stream(stream), alaskaStream = alaska.stream(stream), hawaiiStream = hawaii.stream(stream); - return { - point: function(x, y) { - lower48Stream.point(x, y); - alaskaStream.point(x, y); - hawaiiStream.point(x, y); - }, - sphere: function() { - lower48Stream.sphere(); - alaskaStream.sphere(); - hawaiiStream.sphere(); - }, - lineStart: function() { - lower48Stream.lineStart(); - alaskaStream.lineStart(); - hawaiiStream.lineStart(); - }, - lineEnd: function() { - lower48Stream.lineEnd(); - alaskaStream.lineEnd(); - hawaiiStream.lineEnd(); - }, - polygonStart: function() { - lower48Stream.polygonStart(); - alaskaStream.polygonStart(); - hawaiiStream.polygonStart(); - }, - polygonEnd: function() { - lower48Stream.polygonEnd(); - alaskaStream.polygonEnd(); - hawaiiStream.polygonEnd(); - } - }; - }; - albersUsa.precision = function(_) { - if (!arguments.length) return lower48.precision(); - lower48.precision(_); - alaska.precision(_); - hawaii.precision(_); - return albersUsa; - }; - albersUsa.scale = function(_) { - if (!arguments.length) return lower48.scale(); - lower48.scale(_); - alaska.scale(_ * .35); - hawaii.scale(_); - return albersUsa.translate(lower48.translate()); - }; - albersUsa.translate = function(_) { - if (!arguments.length) return lower48.translate(); - var k = lower48.scale(), x = +_[0], y = +_[1]; - lower48Point = lower48.translate(_).clipExtent([ [ x - .455 * k, y - .238 * k ], [ x + .455 * k, y + .238 * k ] ]).stream(pointStream).point; - alaskaPoint = alaska.translate([ x - .307 * k, y + .201 * k ]).clipExtent([ [ x - .425 * k + ε, y + .12 * k + ε ], [ x - .214 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point; - hawaiiPoint = hawaii.translate([ x - .205 * k, y + .212 * k ]).clipExtent([ [ x - .214 * k + ε, y + .166 * k + ε ], [ x - .115 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point; - return albersUsa; - }; - return albersUsa.scale(1070); - }; - var d3_geo_pathAreaSum, d3_geo_pathAreaPolygon, d3_geo_pathArea = { - point: d3_noop, - lineStart: d3_noop, - lineEnd: d3_noop, - polygonStart: function() { - d3_geo_pathAreaPolygon = 0; - d3_geo_pathArea.lineStart = d3_geo_pathAreaRingStart; - }, - polygonEnd: function() { - d3_geo_pathArea.lineStart = d3_geo_pathArea.lineEnd = d3_geo_pathArea.point = d3_noop; - d3_geo_pathAreaSum += abs(d3_geo_pathAreaPolygon / 2); - } - }; - function d3_geo_pathAreaRingStart() { - var x00, y00, x0, y0; - d3_geo_pathArea.point = function(x, y) { - d3_geo_pathArea.point = nextPoint; - x00 = x0 = x, y00 = y0 = y; - }; - function nextPoint(x, y) { - d3_geo_pathAreaPolygon += y0 * x - x0 * y; - x0 = x, y0 = y; - } - d3_geo_pathArea.lineEnd = function() { - nextPoint(x00, y00); - }; - } - var d3_geo_pathBoundsX0, d3_geo_pathBoundsY0, d3_geo_pathBoundsX1, d3_geo_pathBoundsY1; - var d3_geo_pathBounds = { - point: d3_geo_pathBoundsPoint, - lineStart: d3_noop, - lineEnd: d3_noop, - polygonStart: d3_noop, - polygonEnd: d3_noop - }; - function d3_geo_pathBoundsPoint(x, y) { - if (x < d3_geo_pathBoundsX0) d3_geo_pathBoundsX0 = x; - if (x > d3_geo_pathBoundsX1) d3_geo_pathBoundsX1 = x; - if (y < d3_geo_pathBoundsY0) d3_geo_pathBoundsY0 = y; - if (y > d3_geo_pathBoundsY1) d3_geo_pathBoundsY1 = y; - } - function d3_geo_pathBuffer() { - var pointCircle = d3_geo_pathBufferCircle(4.5), buffer = []; - var stream = { - point: point, - lineStart: function() { - stream.point = pointLineStart; - }, - lineEnd: lineEnd, - polygonStart: function() { - stream.lineEnd = lineEndPolygon; - }, - polygonEnd: function() { - stream.lineEnd = lineEnd; - stream.point = point; - }, - pointRadius: function(_) { - pointCircle = d3_geo_pathBufferCircle(_); - return stream; - }, - result: function() { - if (buffer.length) { - var result = buffer.join(""); - buffer = []; - return result; - } - } - }; - function point(x, y) { - buffer.push("M", x, ",", y, pointCircle); - } - function pointLineStart(x, y) { - buffer.push("M", x, ",", y); - stream.point = pointLine; - } - function pointLine(x, y) { - buffer.push("L", x, ",", y); - } - function lineEnd() { - stream.point = point; - } - function lineEndPolygon() { - buffer.push("Z"); - } - return stream; - } - function d3_geo_pathBufferCircle(radius) { - return "m0," + radius + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius + "z"; - } - var d3_geo_pathCentroid = { - point: d3_geo_pathCentroidPoint, - lineStart: d3_geo_pathCentroidLineStart, - lineEnd: d3_geo_pathCentroidLineEnd, - polygonStart: function() { - d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidRingStart; - }, - polygonEnd: function() { - d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint; - d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidLineStart; - d3_geo_pathCentroid.lineEnd = d3_geo_pathCentroidLineEnd; - } - }; - function d3_geo_pathCentroidPoint(x, y) { - d3_geo_centroidX0 += x; - d3_geo_centroidY0 += y; - ++d3_geo_centroidZ0; - } - function d3_geo_pathCentroidLineStart() { - var x0, y0; - d3_geo_pathCentroid.point = function(x, y) { - d3_geo_pathCentroid.point = nextPoint; - d3_geo_pathCentroidPoint(x0 = x, y0 = y); - }; - function nextPoint(x, y) { - var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy); - d3_geo_centroidX1 += z * (x0 + x) / 2; - d3_geo_centroidY1 += z * (y0 + y) / 2; - d3_geo_centroidZ1 += z; - d3_geo_pathCentroidPoint(x0 = x, y0 = y); - } - } - function d3_geo_pathCentroidLineEnd() { - d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint; - } - function d3_geo_pathCentroidRingStart() { - var x00, y00, x0, y0; - d3_geo_pathCentroid.point = function(x, y) { - d3_geo_pathCentroid.point = nextPoint; - d3_geo_pathCentroidPoint(x00 = x0 = x, y00 = y0 = y); - }; - function nextPoint(x, y) { - var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy); - d3_geo_centroidX1 += z * (x0 + x) / 2; - d3_geo_centroidY1 += z * (y0 + y) / 2; - d3_geo_centroidZ1 += z; - z = y0 * x - x0 * y; - d3_geo_centroidX2 += z * (x0 + x); - d3_geo_centroidY2 += z * (y0 + y); - d3_geo_centroidZ2 += z * 3; - d3_geo_pathCentroidPoint(x0 = x, y0 = y); - } - d3_geo_pathCentroid.lineEnd = function() { - nextPoint(x00, y00); - }; - } - function d3_geo_pathContext(context) { - var pointRadius = 4.5; - var stream = { - point: point, - lineStart: function() { - stream.point = pointLineStart; - }, - lineEnd: lineEnd, - polygonStart: function() { - stream.lineEnd = lineEndPolygon; - }, - polygonEnd: function() { - stream.lineEnd = lineEnd; - stream.point = point; - }, - pointRadius: function(_) { - pointRadius = _; - return stream; - }, - result: d3_noop - }; - function point(x, y) { - context.moveTo(x + pointRadius, y); - context.arc(x, y, pointRadius, 0, τ); - } - function pointLineStart(x, y) { - context.moveTo(x, y); - stream.point = pointLine; - } - function pointLine(x, y) { - context.lineTo(x, y); - } - function lineEnd() { - stream.point = point; - } - function lineEndPolygon() { - context.closePath(); - } - return stream; - } - function d3_geo_resample(project) { - var δ2 = .5, cosMinDistance = Math.cos(30 * d3_radians), maxDepth = 16; - function resample(stream) { - return (maxDepth ? resampleRecursive : resampleNone)(stream); - } - function resampleNone(stream) { - return d3_geo_transformPoint(stream, function(x, y) { - x = project(x, y); - stream.point(x[0], x[1]); - }); - } - function resampleRecursive(stream) { - var λ00, φ00, x00, y00, a00, b00, c00, λ0, x0, y0, a0, b0, c0; - var resample = { - point: point, - lineStart: lineStart, - lineEnd: lineEnd, - polygonStart: function() { - stream.polygonStart(); - resample.lineStart = ringStart; - }, - polygonEnd: function() { - stream.polygonEnd(); - resample.lineStart = lineStart; - } - }; - function point(x, y) { - x = project(x, y); - stream.point(x[0], x[1]); - } - function lineStart() { - x0 = NaN; - resample.point = linePoint; - stream.lineStart(); - } - function linePoint(λ, φ) { - var c = d3_geo_cartesian([ λ, φ ]), p = project(λ, φ); - resampleLineTo(x0, y0, λ0, a0, b0, c0, x0 = p[0], y0 = p[1], λ0 = λ, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream); - stream.point(x0, y0); - } - function lineEnd() { - resample.point = point; - stream.lineEnd(); - } - function ringStart() { - lineStart(); - resample.point = ringPoint; - resample.lineEnd = ringEnd; - } - function ringPoint(λ, φ) { - linePoint(λ00 = λ, φ00 = φ), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0; - resample.point = linePoint; - } - function ringEnd() { - resampleLineTo(x0, y0, λ0, a0, b0, c0, x00, y00, λ00, a00, b00, c00, maxDepth, stream); - resample.lineEnd = lineEnd; - lineEnd(); - } - return resample; - } - function resampleLineTo(x0, y0, λ0, a0, b0, c0, x1, y1, λ1, a1, b1, c1, depth, stream) { - var dx = x1 - x0, dy = y1 - y0, d2 = dx * dx + dy * dy; - if (d2 > 4 * δ2 && depth--) { - var a = a0 + a1, b = b0 + b1, c = c0 + c1, m = Math.sqrt(a * a + b * b + c * c), φ2 = Math.asin(c /= m), λ2 = abs(abs(c) - 1) < ε || abs(λ0 - λ1) < ε ? (λ0 + λ1) / 2 : Math.atan2(b, a), p = project(λ2, φ2), x2 = p[0], y2 = p[1], dx2 = x2 - x0, dy2 = y2 - y0, dz = dy * dx2 - dx * dy2; - if (dz * dz / d2 > δ2 || abs((dx * dx2 + dy * dy2) / d2 - .5) > .3 || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { - resampleLineTo(x0, y0, λ0, a0, b0, c0, x2, y2, λ2, a /= m, b /= m, c, depth, stream); - stream.point(x2, y2); - resampleLineTo(x2, y2, λ2, a, b, c, x1, y1, λ1, a1, b1, c1, depth, stream); - } - } - } - resample.precision = function(_) { - if (!arguments.length) return Math.sqrt(δ2); - maxDepth = (δ2 = _ * _) > 0 && 16; - return resample; - }; - return resample; - } - d3.geo.path = function() { - var pointRadius = 4.5, projection, context, projectStream, contextStream, cacheStream; - function path(object) { - if (object) { - if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments)); - if (!cacheStream || !cacheStream.valid) cacheStream = projectStream(contextStream); - d3.geo.stream(object, cacheStream); - } - return contextStream.result(); - } - path.area = function(object) { - d3_geo_pathAreaSum = 0; - d3.geo.stream(object, projectStream(d3_geo_pathArea)); - return d3_geo_pathAreaSum; - }; - path.centroid = function(object) { - d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0; - d3.geo.stream(object, projectStream(d3_geo_pathCentroid)); - return d3_geo_centroidZ2 ? [ d3_geo_centroidX2 / d3_geo_centroidZ2, d3_geo_centroidY2 / d3_geo_centroidZ2 ] : d3_geo_centroidZ1 ? [ d3_geo_centroidX1 / d3_geo_centroidZ1, d3_geo_centroidY1 / d3_geo_centroidZ1 ] : d3_geo_centroidZ0 ? [ d3_geo_centroidX0 / d3_geo_centroidZ0, d3_geo_centroidY0 / d3_geo_centroidZ0 ] : [ NaN, NaN ]; - }; - path.bounds = function(object) { - d3_geo_pathBoundsX1 = d3_geo_pathBoundsY1 = -(d3_geo_pathBoundsX0 = d3_geo_pathBoundsY0 = Infinity); - d3.geo.stream(object, projectStream(d3_geo_pathBounds)); - return [ [ d3_geo_pathBoundsX0, d3_geo_pathBoundsY0 ], [ d3_geo_pathBoundsX1, d3_geo_pathBoundsY1 ] ]; - }; - path.projection = function(_) { - if (!arguments.length) return projection; - projectStream = (projection = _) ? _.stream || d3_geo_pathProjectStream(_) : d3_identity; - return reset(); - }; - path.context = function(_) { - if (!arguments.length) return context; - contextStream = (context = _) == null ? new d3_geo_pathBuffer() : new d3_geo_pathContext(_); - if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius); - return reset(); - }; - path.pointRadius = function(_) { - if (!arguments.length) return pointRadius; - pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_); - return path; - }; - function reset() { - cacheStream = null; - return path; - } - return path.projection(d3.geo.albersUsa()).context(null); - }; - function d3_geo_pathProjectStream(project) { - var resample = d3_geo_resample(function(x, y) { - return project([ x * d3_degrees, y * d3_degrees ]); - }); - return function(stream) { - return d3_geo_projectionRadians(resample(stream)); - }; - } - d3.geo.transform = function(methods) { - return { - stream: function(stream) { - var transform = new d3_geo_transform(stream); - for (var k in methods) transform[k] = methods[k]; - return transform; - } - }; - }; - function d3_geo_transform(stream) { - this.stream = stream; - } - d3_geo_transform.prototype = { - point: function(x, y) { - this.stream.point(x, y); - }, - sphere: function() { - this.stream.sphere(); - }, - lineStart: function() { - this.stream.lineStart(); - }, - lineEnd: function() { - this.stream.lineEnd(); - }, - polygonStart: function() { - this.stream.polygonStart(); - }, - polygonEnd: function() { - this.stream.polygonEnd(); - } - }; - function d3_geo_transformPoint(stream, point) { - return { - point: point, - sphere: function() { - stream.sphere(); - }, - lineStart: function() { - stream.lineStart(); - }, - lineEnd: function() { - stream.lineEnd(); - }, - polygonStart: function() { - stream.polygonStart(); - }, - polygonEnd: function() { - stream.polygonEnd(); - } - }; - } - d3.geo.projection = d3_geo_projection; - d3.geo.projectionMutator = d3_geo_projectionMutator; - function d3_geo_projection(project) { - return d3_geo_projectionMutator(function() { - return project; - })(); - } - function d3_geo_projectionMutator(projectAt) { - var project, rotate, projectRotate, projectResample = d3_geo_resample(function(x, y) { - x = project(x, y); - return [ x[0] * k + δx, δy - x[1] * k ]; - }), k = 150, x = 480, y = 250, λ = 0, φ = 0, δλ = 0, δφ = 0, δγ = 0, δx, δy, preclip = d3_geo_clipAntimeridian, postclip = d3_identity, clipAngle = null, clipExtent = null, stream; - function projection(point) { - point = projectRotate(point[0] * d3_radians, point[1] * d3_radians); - return [ point[0] * k + δx, δy - point[1] * k ]; - } - function invert(point) { - point = projectRotate.invert((point[0] - δx) / k, (δy - point[1]) / k); - return point && [ point[0] * d3_degrees, point[1] * d3_degrees ]; - } - projection.stream = function(output) { - if (stream) stream.valid = false; - stream = d3_geo_projectionRadians(preclip(rotate, projectResample(postclip(output)))); - stream.valid = true; - return stream; - }; - projection.clipAngle = function(_) { - if (!arguments.length) return clipAngle; - preclip = _ == null ? (clipAngle = _, d3_geo_clipAntimeridian) : d3_geo_clipCircle((clipAngle = +_) * d3_radians); - return invalidate(); - }; - projection.clipExtent = function(_) { - if (!arguments.length) return clipExtent; - clipExtent = _; - postclip = _ ? d3_geo_clipExtent(_[0][0], _[0][1], _[1][0], _[1][1]) : d3_identity; - return invalidate(); - }; - projection.scale = function(_) { - if (!arguments.length) return k; - k = +_; - return reset(); - }; - projection.translate = function(_) { - if (!arguments.length) return [ x, y ]; - x = +_[0]; - y = +_[1]; - return reset(); - }; - projection.center = function(_) { - if (!arguments.length) return [ λ * d3_degrees, φ * d3_degrees ]; - λ = _[0] % 360 * d3_radians; - φ = _[1] % 360 * d3_radians; - return reset(); - }; - projection.rotate = function(_) { - if (!arguments.length) return [ δλ * d3_degrees, δφ * d3_degrees, δγ * d3_degrees ]; - δλ = _[0] % 360 * d3_radians; - δφ = _[1] % 360 * d3_radians; - δγ = _.length > 2 ? _[2] % 360 * d3_radians : 0; - return reset(); - }; - d3.rebind(projection, projectResample, "precision"); - function reset() { - projectRotate = d3_geo_compose(rotate = d3_geo_rotation(δλ, δφ, δγ), project); - var center = project(λ, φ); - δx = x - center[0] * k; - δy = y + center[1] * k; - return invalidate(); - } - function invalidate() { - if (stream) stream.valid = false, stream = null; - return projection; - } - return function() { - project = projectAt.apply(this, arguments); - projection.invert = project.invert && invert; - return reset(); - }; - } - function d3_geo_projectionRadians(stream) { - return d3_geo_transformPoint(stream, function(x, y) { - stream.point(x * d3_radians, y * d3_radians); - }); - } - function d3_geo_equirectangular(λ, φ) { - return [ λ, φ ]; - } - (d3.geo.equirectangular = function() { - return d3_geo_projection(d3_geo_equirectangular); - }).raw = d3_geo_equirectangular.invert = d3_geo_equirectangular; - d3.geo.rotation = function(rotate) { - rotate = d3_geo_rotation(rotate[0] % 360 * d3_radians, rotate[1] * d3_radians, rotate.length > 2 ? rotate[2] * d3_radians : 0); - function forward(coordinates) { - coordinates = rotate(coordinates[0] * d3_radians, coordinates[1] * d3_radians); - return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates; - } - forward.invert = function(coordinates) { - coordinates = rotate.invert(coordinates[0] * d3_radians, coordinates[1] * d3_radians); - return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates; - }; - return forward; - }; - function d3_geo_identityRotation(λ, φ) { - return [ λ > π ? λ - τ : λ < -π ? λ + τ : λ, φ ]; - } - d3_geo_identityRotation.invert = d3_geo_equirectangular; - function d3_geo_rotation(δλ, δφ, δγ) { - return δλ ? δφ || δγ ? d3_geo_compose(d3_geo_rotationλ(δλ), d3_geo_rotationφγ(δφ, δγ)) : d3_geo_rotationλ(δλ) : δφ || δγ ? d3_geo_rotationφγ(δφ, δγ) : d3_geo_identityRotation; - } - function d3_geo_forwardRotationλ(δλ) { - return function(λ, φ) { - return λ += δλ, [ λ > π ? λ - τ : λ < -π ? λ + τ : λ, φ ]; - }; - } - function d3_geo_rotationλ(δλ) { - var rotation = d3_geo_forwardRotationλ(δλ); - rotation.invert = d3_geo_forwardRotationλ(-δλ); - return rotation; - } - function d3_geo_rotationφγ(δφ, δγ) { - var cosδφ = Math.cos(δφ), sinδφ = Math.sin(δφ), cosδγ = Math.cos(δγ), sinδγ = Math.sin(δγ); - function rotation(λ, φ) { - var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδφ + x * sinδφ; - return [ Math.atan2(y * cosδγ - k * sinδγ, x * cosδφ - z * sinδφ), d3_asin(k * cosδγ + y * sinδγ) ]; - } - rotation.invert = function(λ, φ) { - var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδγ - y * sinδγ; - return [ Math.atan2(y * cosδγ + z * sinδγ, x * cosδφ + k * sinδφ), d3_asin(k * cosδφ - x * sinδφ) ]; - }; - return rotation; - } - d3.geo.circle = function() { - var origin = [ 0, 0 ], angle, precision = 6, interpolate; - function circle() { - var center = typeof origin === "function" ? origin.apply(this, arguments) : origin, rotate = d3_geo_rotation(-center[0] * d3_radians, -center[1] * d3_radians, 0).invert, ring = []; - interpolate(null, null, 1, { - point: function(x, y) { - ring.push(x = rotate(x, y)); - x[0] *= d3_degrees, x[1] *= d3_degrees; - } - }); - return { - type: "Polygon", - coordinates: [ ring ] - }; - } - circle.origin = function(x) { - if (!arguments.length) return origin; - origin = x; - return circle; - }; - circle.angle = function(x) { - if (!arguments.length) return angle; - interpolate = d3_geo_circleInterpolate((angle = +x) * d3_radians, precision * d3_radians); - return circle; - }; - circle.precision = function(_) { - if (!arguments.length) return precision; - interpolate = d3_geo_circleInterpolate(angle * d3_radians, (precision = +_) * d3_radians); - return circle; - }; - return circle.angle(90); - }; - function d3_geo_circleInterpolate(radius, precision) { - var cr = Math.cos(radius), sr = Math.sin(radius); - return function(from, to, direction, listener) { - var step = direction * precision; - if (from != null) { - from = d3_geo_circleAngle(cr, from); - to = d3_geo_circleAngle(cr, to); - if (direction > 0 ? from < to : from > to) from += direction * τ; - } else { - from = radius + direction * τ; - to = radius - .5 * step; - } - for (var point, t = from; direction > 0 ? t > to : t < to; t -= step) { - listener.point((point = d3_geo_spherical([ cr, -sr * Math.cos(t), -sr * Math.sin(t) ]))[0], point[1]); - } - }; - } - function d3_geo_circleAngle(cr, point) { - var a = d3_geo_cartesian(point); - a[0] -= cr; - d3_geo_cartesianNormalize(a); - var angle = d3_acos(-a[1]); - return ((-a[2] < 0 ? -angle : angle) + 2 * Math.PI - ε) % (2 * Math.PI); - } - d3.geo.distance = function(a, b) { - var Δλ = (b[0] - a[0]) * d3_radians, φ0 = a[1] * d3_radians, φ1 = b[1] * d3_radians, sinΔλ = Math.sin(Δλ), cosΔλ = Math.cos(Δλ), sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), sinφ1 = Math.sin(φ1), cosφ1 = Math.cos(φ1), t; - return Math.atan2(Math.sqrt((t = cosφ1 * sinΔλ) * t + (t = cosφ0 * sinφ1 - sinφ0 * cosφ1 * cosΔλ) * t), sinφ0 * sinφ1 + cosφ0 * cosφ1 * cosΔλ); - }; - d3.geo.graticule = function() { - var x1, x0, X1, X0, y1, y0, Y1, Y0, dx = 10, dy = dx, DX = 90, DY = 360, x, y, X, Y, precision = 2.5; - function graticule() { - return { - type: "MultiLineString", - coordinates: lines() - }; - } - function lines() { - return d3.range(Math.ceil(X0 / DX) * DX, X1, DX).map(X).concat(d3.range(Math.ceil(Y0 / DY) * DY, Y1, DY).map(Y)).concat(d3.range(Math.ceil(x0 / dx) * dx, x1, dx).filter(function(x) { - return abs(x % DX) > ε; - }).map(x)).concat(d3.range(Math.ceil(y0 / dy) * dy, y1, dy).filter(function(y) { - return abs(y % DY) > ε; - }).map(y)); - } - graticule.lines = function() { - return lines().map(function(coordinates) { - return { - type: "LineString", - coordinates: coordinates - }; - }); - }; - graticule.outline = function() { - return { - type: "Polygon", - coordinates: [ X(X0).concat(Y(Y1).slice(1), X(X1).reverse().slice(1), Y(Y0).reverse().slice(1)) ] - }; - }; - graticule.extent = function(_) { - if (!arguments.length) return graticule.minorExtent(); - return graticule.majorExtent(_).minorExtent(_); - }; - graticule.majorExtent = function(_) { - if (!arguments.length) return [ [ X0, Y0 ], [ X1, Y1 ] ]; - X0 = +_[0][0], X1 = +_[1][0]; - Y0 = +_[0][1], Y1 = +_[1][1]; - if (X0 > X1) _ = X0, X0 = X1, X1 = _; - if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _; - return graticule.precision(precision); - }; - graticule.minorExtent = function(_) { - if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ]; - x0 = +_[0][0], x1 = +_[1][0]; - y0 = +_[0][1], y1 = +_[1][1]; - if (x0 > x1) _ = x0, x0 = x1, x1 = _; - if (y0 > y1) _ = y0, y0 = y1, y1 = _; - return graticule.precision(precision); - }; - graticule.step = function(_) { - if (!arguments.length) return graticule.minorStep(); - return graticule.majorStep(_).minorStep(_); - }; - graticule.majorStep = function(_) { - if (!arguments.length) return [ DX, DY ]; - DX = +_[0], DY = +_[1]; - return graticule; - }; - graticule.minorStep = function(_) { - if (!arguments.length) return [ dx, dy ]; - dx = +_[0], dy = +_[1]; - return graticule; - }; - graticule.precision = function(_) { - if (!arguments.length) return precision; - precision = +_; - x = d3_geo_graticuleX(y0, y1, 90); - y = d3_geo_graticuleY(x0, x1, precision); - X = d3_geo_graticuleX(Y0, Y1, 90); - Y = d3_geo_graticuleY(X0, X1, precision); - return graticule; - }; - return graticule.majorExtent([ [ -180, -90 + ε ], [ 180, 90 - ε ] ]).minorExtent([ [ -180, -80 - ε ], [ 180, 80 + ε ] ]); - }; - function d3_geo_graticuleX(y0, y1, dy) { - var y = d3.range(y0, y1 - ε, dy).concat(y1); - return function(x) { - return y.map(function(y) { - return [ x, y ]; - }); - }; - } - function d3_geo_graticuleY(x0, x1, dx) { - var x = d3.range(x0, x1 - ε, dx).concat(x1); - return function(y) { - return x.map(function(x) { - return [ x, y ]; - }); - }; - } - function d3_source(d) { - return d.source; - } - function d3_target(d) { - return d.target; - } - d3.geo.greatArc = function() { - var source = d3_source, source_, target = d3_target, target_; - function greatArc() { - return { - type: "LineString", - coordinates: [ source_ || source.apply(this, arguments), target_ || target.apply(this, arguments) ] - }; - } - greatArc.distance = function() { - return d3.geo.distance(source_ || source.apply(this, arguments), target_ || target.apply(this, arguments)); - }; - greatArc.source = function(_) { - if (!arguments.length) return source; - source = _, source_ = typeof _ === "function" ? null : _; - return greatArc; - }; - greatArc.target = function(_) { - if (!arguments.length) return target; - target = _, target_ = typeof _ === "function" ? null : _; - return greatArc; - }; - greatArc.precision = function() { - return arguments.length ? greatArc : 0; - }; - return greatArc; - }; - d3.geo.interpolate = function(source, target) { - return d3_geo_interpolate(source[0] * d3_radians, source[1] * d3_radians, target[0] * d3_radians, target[1] * d3_radians); - }; - function d3_geo_interpolate(x0, y0, x1, y1) { - var cy0 = Math.cos(y0), sy0 = Math.sin(y0), cy1 = Math.cos(y1), sy1 = Math.sin(y1), kx0 = cy0 * Math.cos(x0), ky0 = cy0 * Math.sin(x0), kx1 = cy1 * Math.cos(x1), ky1 = cy1 * Math.sin(x1), d = 2 * Math.asin(Math.sqrt(d3_haversin(y1 - y0) + cy0 * cy1 * d3_haversin(x1 - x0))), k = 1 / Math.sin(d); - var interpolate = d ? function(t) { - var B = Math.sin(t *= d) * k, A = Math.sin(d - t) * k, x = A * kx0 + B * kx1, y = A * ky0 + B * ky1, z = A * sy0 + B * sy1; - return [ Math.atan2(y, x) * d3_degrees, Math.atan2(z, Math.sqrt(x * x + y * y)) * d3_degrees ]; - } : function() { - return [ x0 * d3_degrees, y0 * d3_degrees ]; - }; - interpolate.distance = d; - return interpolate; - } - d3.geo.length = function(object) { - d3_geo_lengthSum = 0; - d3.geo.stream(object, d3_geo_length); - return d3_geo_lengthSum; - }; - var d3_geo_lengthSum; - var d3_geo_length = { - sphere: d3_noop, - point: d3_noop, - lineStart: d3_geo_lengthLineStart, - lineEnd: d3_noop, - polygonStart: d3_noop, - polygonEnd: d3_noop - }; - function d3_geo_lengthLineStart() { - var λ0, sinφ0, cosφ0; - d3_geo_length.point = function(λ, φ) { - λ0 = λ * d3_radians, sinφ0 = Math.sin(φ *= d3_radians), cosφ0 = Math.cos(φ); - d3_geo_length.point = nextPoint; - }; - d3_geo_length.lineEnd = function() { - d3_geo_length.point = d3_geo_length.lineEnd = d3_noop; - }; - function nextPoint(λ, φ) { - var sinφ = Math.sin(φ *= d3_radians), cosφ = Math.cos(φ), t = abs((λ *= d3_radians) - λ0), cosΔλ = Math.cos(t); - d3_geo_lengthSum += Math.atan2(Math.sqrt((t = cosφ * Math.sin(t)) * t + (t = cosφ0 * sinφ - sinφ0 * cosφ * cosΔλ) * t), sinφ0 * sinφ + cosφ0 * cosφ * cosΔλ); - λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ; - } - } - function d3_geo_azimuthal(scale, angle) { - function azimuthal(λ, φ) { - var cosλ = Math.cos(λ), cosφ = Math.cos(φ), k = scale(cosλ * cosφ); - return [ k * cosφ * Math.sin(λ), k * Math.sin(φ) ]; - } - azimuthal.invert = function(x, y) { - var ρ = Math.sqrt(x * x + y * y), c = angle(ρ), sinc = Math.sin(c), cosc = Math.cos(c); - return [ Math.atan2(x * sinc, ρ * cosc), Math.asin(ρ && y * sinc / ρ) ]; - }; - return azimuthal; - } - var d3_geo_azimuthalEqualArea = d3_geo_azimuthal(function(cosλcosφ) { - return Math.sqrt(2 / (1 + cosλcosφ)); - }, function(ρ) { - return 2 * Math.asin(ρ / 2); - }); - (d3.geo.azimuthalEqualArea = function() { - return d3_geo_projection(d3_geo_azimuthalEqualArea); - }).raw = d3_geo_azimuthalEqualArea; - var d3_geo_azimuthalEquidistant = d3_geo_azimuthal(function(cosλcosφ) { - var c = Math.acos(cosλcosφ); - return c && c / Math.sin(c); - }, d3_identity); - (d3.geo.azimuthalEquidistant = function() { - return d3_geo_projection(d3_geo_azimuthalEquidistant); - }).raw = d3_geo_azimuthalEquidistant; - function d3_geo_conicConformal(φ0, φ1) { - var cosφ0 = Math.cos(φ0), t = function(φ) { - return Math.tan(π / 4 + φ / 2); - }, n = φ0 === φ1 ? Math.sin(φ0) : Math.log(cosφ0 / Math.cos(φ1)) / Math.log(t(φ1) / t(φ0)), F = cosφ0 * Math.pow(t(φ0), n) / n; - if (!n) return d3_geo_mercator; - function forward(λ, φ) { - if (F > 0) { - if (φ < -halfπ + ε) φ = -halfπ + ε; - } else { - if (φ > halfπ - ε) φ = halfπ - ε; - } - var ρ = F / Math.pow(t(φ), n); - return [ ρ * Math.sin(n * λ), F - ρ * Math.cos(n * λ) ]; - } - forward.invert = function(x, y) { - var ρ0_y = F - y, ρ = d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y); - return [ Math.atan2(x, ρ0_y) / n, 2 * Math.atan(Math.pow(F / ρ, 1 / n)) - halfπ ]; - }; - return forward; - } - (d3.geo.conicConformal = function() { - return d3_geo_conic(d3_geo_conicConformal); - }).raw = d3_geo_conicConformal; - function d3_geo_conicEquidistant(φ0, φ1) { - var cosφ0 = Math.cos(φ0), n = φ0 === φ1 ? Math.sin(φ0) : (cosφ0 - Math.cos(φ1)) / (φ1 - φ0), G = cosφ0 / n + φ0; - if (abs(n) < ε) return d3_geo_equirectangular; - function forward(λ, φ) { - var ρ = G - φ; - return [ ρ * Math.sin(n * λ), G - ρ * Math.cos(n * λ) ]; - } - forward.invert = function(x, y) { - var ρ0_y = G - y; - return [ Math.atan2(x, ρ0_y) / n, G - d3_sgn(n) * Math.sqrt(x * x + ρ0_y * ρ0_y) ]; - }; - return forward; - } - (d3.geo.conicEquidistant = function() { - return d3_geo_conic(d3_geo_conicEquidistant); - }).raw = d3_geo_conicEquidistant; - var d3_geo_gnomonic = d3_geo_azimuthal(function(cosλcosφ) { - return 1 / cosλcosφ; - }, Math.atan); - (d3.geo.gnomonic = function() { - return d3_geo_projection(d3_geo_gnomonic); - }).raw = d3_geo_gnomonic; - function d3_geo_mercator(λ, φ) { - return [ λ, Math.log(Math.tan(π / 4 + φ / 2)) ]; - } - d3_geo_mercator.invert = function(x, y) { - return [ x, 2 * Math.atan(Math.exp(y)) - halfπ ]; - }; - function d3_geo_mercatorProjection(project) { - var m = d3_geo_projection(project), scale = m.scale, translate = m.translate, clipExtent = m.clipExtent, clipAuto; - m.scale = function() { - var v = scale.apply(m, arguments); - return v === m ? clipAuto ? m.clipExtent(null) : m : v; - }; - m.translate = function() { - var v = translate.apply(m, arguments); - return v === m ? clipAuto ? m.clipExtent(null) : m : v; - }; - m.clipExtent = function(_) { - var v = clipExtent.apply(m, arguments); - if (v === m) { - if (clipAuto = _ == null) { - var k = π * scale(), t = translate(); - clipExtent([ [ t[0] - k, t[1] - k ], [ t[0] + k, t[1] + k ] ]); - } - } else if (clipAuto) { - v = null; - } - return v; - }; - return m.clipExtent(null); - } - (d3.geo.mercator = function() { - return d3_geo_mercatorProjection(d3_geo_mercator); - }).raw = d3_geo_mercator; - var d3_geo_orthographic = d3_geo_azimuthal(function() { - return 1; - }, Math.asin); - (d3.geo.orthographic = function() { - return d3_geo_projection(d3_geo_orthographic); - }).raw = d3_geo_orthographic; - var d3_geo_stereographic = d3_geo_azimuthal(function(cosλcosφ) { - return 1 / (1 + cosλcosφ); - }, function(ρ) { - return 2 * Math.atan(ρ); - }); - (d3.geo.stereographic = function() { - return d3_geo_projection(d3_geo_stereographic); - }).raw = d3_geo_stereographic; - function d3_geo_transverseMercator(λ, φ) { - return [ Math.log(Math.tan(π / 4 + φ / 2)), -λ ]; - } - d3_geo_transverseMercator.invert = function(x, y) { - return [ -y, 2 * Math.atan(Math.exp(x)) - halfπ ]; - }; - (d3.geo.transverseMercator = function() { - var projection = d3_geo_mercatorProjection(d3_geo_transverseMercator), center = projection.center, rotate = projection.rotate; - projection.center = function(_) { - return _ ? center([ -_[1], _[0] ]) : (_ = center(), [ _[1], -_[0] ]); - }; - projection.rotate = function(_) { - return _ ? rotate([ _[0], _[1], _.length > 2 ? _[2] + 90 : 90 ]) : (_ = rotate(), - [ _[0], _[1], _[2] - 90 ]); - }; - return rotate([ 0, 0, 90 ]); - }).raw = d3_geo_transverseMercator; - d3.geom = {}; - function d3_geom_pointX(d) { - return d[0]; - } - function d3_geom_pointY(d) { - return d[1]; - } - d3.geom.hull = function(vertices) { - var x = d3_geom_pointX, y = d3_geom_pointY; - if (arguments.length) return hull(vertices); - function hull(data) { - if (data.length < 3) return []; - var fx = d3_functor(x), fy = d3_functor(y), i, n = data.length, points = [], flippedPoints = []; - for (i = 0; i < n; i++) { - points.push([ +fx.call(this, data[i], i), +fy.call(this, data[i], i), i ]); - } - points.sort(d3_geom_hullOrder); - for (i = 0; i < n; i++) flippedPoints.push([ points[i][0], -points[i][1] ]); - var upper = d3_geom_hullUpper(points), lower = d3_geom_hullUpper(flippedPoints); - var skipLeft = lower[0] === upper[0], skipRight = lower[lower.length - 1] === upper[upper.length - 1], polygon = []; - for (i = upper.length - 1; i >= 0; --i) polygon.push(data[points[upper[i]][2]]); - for (i = +skipLeft; i < lower.length - skipRight; ++i) polygon.push(data[points[lower[i]][2]]); - return polygon; - } - hull.x = function(_) { - return arguments.length ? (x = _, hull) : x; - }; - hull.y = function(_) { - return arguments.length ? (y = _, hull) : y; - }; - return hull; - }; - function d3_geom_hullUpper(points) { - var n = points.length, hull = [ 0, 1 ], hs = 2; - for (var i = 2; i < n; i++) { - while (hs > 1 && d3_cross2d(points[hull[hs - 2]], points[hull[hs - 1]], points[i]) <= 0) --hs; - hull[hs++] = i; - } - return hull.slice(0, hs); - } - function d3_geom_hullOrder(a, b) { - return a[0] - b[0] || a[1] - b[1]; - } - d3.geom.polygon = function(coordinates) { - d3_subclass(coordinates, d3_geom_polygonPrototype); - return coordinates; - }; - var d3_geom_polygonPrototype = d3.geom.polygon.prototype = []; - d3_geom_polygonPrototype.area = function() { - var i = -1, n = this.length, a, b = this[n - 1], area = 0; - while (++i < n) { - a = b; - b = this[i]; - area += a[1] * b[0] - a[0] * b[1]; - } - return area * .5; - }; - d3_geom_polygonPrototype.centroid = function(k) { - var i = -1, n = this.length, x = 0, y = 0, a, b = this[n - 1], c; - if (!arguments.length) k = -1 / (6 * this.area()); - while (++i < n) { - a = b; - b = this[i]; - c = a[0] * b[1] - b[0] * a[1]; - x += (a[0] + b[0]) * c; - y += (a[1] + b[1]) * c; - } - return [ x * k, y * k ]; - }; - d3_geom_polygonPrototype.clip = function(subject) { - var input, closed = d3_geom_polygonClosed(subject), i = -1, n = this.length - d3_geom_polygonClosed(this), j, m, a = this[n - 1], b, c, d; - while (++i < n) { - input = subject.slice(); - subject.length = 0; - b = this[i]; - c = input[(m = input.length - closed) - 1]; - j = -1; - while (++j < m) { - d = input[j]; - if (d3_geom_polygonInside(d, a, b)) { - if (!d3_geom_polygonInside(c, a, b)) { - subject.push(d3_geom_polygonIntersect(c, d, a, b)); - } - subject.push(d); - } else if (d3_geom_polygonInside(c, a, b)) { - subject.push(d3_geom_polygonIntersect(c, d, a, b)); - } - c = d; - } - if (closed) subject.push(subject[0]); - a = b; - } - return subject; - }; - function d3_geom_polygonInside(p, a, b) { - return (b[0] - a[0]) * (p[1] - a[1]) < (b[1] - a[1]) * (p[0] - a[0]); - } - function d3_geom_polygonIntersect(c, d, a, b) { - var x1 = c[0], x3 = a[0], x21 = d[0] - x1, x43 = b[0] - x3, y1 = c[1], y3 = a[1], y21 = d[1] - y1, y43 = b[1] - y3, ua = (x43 * (y1 - y3) - y43 * (x1 - x3)) / (y43 * x21 - x43 * y21); - return [ x1 + ua * x21, y1 + ua * y21 ]; - } - function d3_geom_polygonClosed(coordinates) { - var a = coordinates[0], b = coordinates[coordinates.length - 1]; - return !(a[0] - b[0] || a[1] - b[1]); - } - var d3_geom_voronoiEdges, d3_geom_voronoiCells, d3_geom_voronoiBeaches, d3_geom_voronoiBeachPool = [], d3_geom_voronoiFirstCircle, d3_geom_voronoiCircles, d3_geom_voronoiCirclePool = []; - function d3_geom_voronoiBeach() { - d3_geom_voronoiRedBlackNode(this); - this.edge = this.site = this.circle = null; - } - function d3_geom_voronoiCreateBeach(site) { - var beach = d3_geom_voronoiBeachPool.pop() || new d3_geom_voronoiBeach(); - beach.site = site; - return beach; - } - function d3_geom_voronoiDetachBeach(beach) { - d3_geom_voronoiDetachCircle(beach); - d3_geom_voronoiBeaches.remove(beach); - d3_geom_voronoiBeachPool.push(beach); - d3_geom_voronoiRedBlackNode(beach); - } - function d3_geom_voronoiRemoveBeach(beach) { - var circle = beach.circle, x = circle.x, y = circle.cy, vertex = { - x: x, - y: y - }, previous = beach.P, next = beach.N, disappearing = [ beach ]; - d3_geom_voronoiDetachBeach(beach); - var lArc = previous; - while (lArc.circle && abs(x - lArc.circle.x) < ε && abs(y - lArc.circle.cy) < ε) { - previous = lArc.P; - disappearing.unshift(lArc); - d3_geom_voronoiDetachBeach(lArc); - lArc = previous; - } - disappearing.unshift(lArc); - d3_geom_voronoiDetachCircle(lArc); - var rArc = next; - while (rArc.circle && abs(x - rArc.circle.x) < ε && abs(y - rArc.circle.cy) < ε) { - next = rArc.N; - disappearing.push(rArc); - d3_geom_voronoiDetachBeach(rArc); - rArc = next; - } - disappearing.push(rArc); - d3_geom_voronoiDetachCircle(rArc); - var nArcs = disappearing.length, iArc; - for (iArc = 1; iArc < nArcs; ++iArc) { - rArc = disappearing[iArc]; - lArc = disappearing[iArc - 1]; - d3_geom_voronoiSetEdgeEnd(rArc.edge, lArc.site, rArc.site, vertex); - } - lArc = disappearing[0]; - rArc = disappearing[nArcs - 1]; - rArc.edge = d3_geom_voronoiCreateEdge(lArc.site, rArc.site, null, vertex); - d3_geom_voronoiAttachCircle(lArc); - d3_geom_voronoiAttachCircle(rArc); - } - function d3_geom_voronoiAddBeach(site) { - var x = site.x, directrix = site.y, lArc, rArc, dxl, dxr, node = d3_geom_voronoiBeaches._; - while (node) { - dxl = d3_geom_voronoiLeftBreakPoint(node, directrix) - x; - if (dxl > ε) node = node.L; else { - dxr = x - d3_geom_voronoiRightBreakPoint(node, directrix); - if (dxr > ε) { - if (!node.R) { - lArc = node; - break; - } - node = node.R; - } else { - if (dxl > -ε) { - lArc = node.P; - rArc = node; - } else if (dxr > -ε) { - lArc = node; - rArc = node.N; - } else { - lArc = rArc = node; - } - break; - } - } - } - var newArc = d3_geom_voronoiCreateBeach(site); - d3_geom_voronoiBeaches.insert(lArc, newArc); - if (!lArc && !rArc) return; - if (lArc === rArc) { - d3_geom_voronoiDetachCircle(lArc); - rArc = d3_geom_voronoiCreateBeach(lArc.site); - d3_geom_voronoiBeaches.insert(newArc, rArc); - newArc.edge = rArc.edge = d3_geom_voronoiCreateEdge(lArc.site, newArc.site); - d3_geom_voronoiAttachCircle(lArc); - d3_geom_voronoiAttachCircle(rArc); - return; - } - if (!rArc) { - newArc.edge = d3_geom_voronoiCreateEdge(lArc.site, newArc.site); - return; - } - d3_geom_voronoiDetachCircle(lArc); - d3_geom_voronoiDetachCircle(rArc); - var lSite = lArc.site, ax = lSite.x, ay = lSite.y, bx = site.x - ax, by = site.y - ay, rSite = rArc.site, cx = rSite.x - ax, cy = rSite.y - ay, d = 2 * (bx * cy - by * cx), hb = bx * bx + by * by, hc = cx * cx + cy * cy, vertex = { - x: (cy * hb - by * hc) / d + ax, - y: (bx * hc - cx * hb) / d + ay - }; - d3_geom_voronoiSetEdgeEnd(rArc.edge, lSite, rSite, vertex); - newArc.edge = d3_geom_voronoiCreateEdge(lSite, site, null, vertex); - rArc.edge = d3_geom_voronoiCreateEdge(site, rSite, null, vertex); - d3_geom_voronoiAttachCircle(lArc); - d3_geom_voronoiAttachCircle(rArc); - } - function d3_geom_voronoiLeftBreakPoint(arc, directrix) { - var site = arc.site, rfocx = site.x, rfocy = site.y, pby2 = rfocy - directrix; - if (!pby2) return rfocx; - var lArc = arc.P; - if (!lArc) return -Infinity; - site = lArc.site; - var lfocx = site.x, lfocy = site.y, plby2 = lfocy - directrix; - if (!plby2) return lfocx; - var hl = lfocx - rfocx, aby2 = 1 / pby2 - 1 / plby2, b = hl / plby2; - if (aby2) return (-b + Math.sqrt(b * b - 2 * aby2 * (hl * hl / (-2 * plby2) - lfocy + plby2 / 2 + rfocy - pby2 / 2))) / aby2 + rfocx; - return (rfocx + lfocx) / 2; - } - function d3_geom_voronoiRightBreakPoint(arc, directrix) { - var rArc = arc.N; - if (rArc) return d3_geom_voronoiLeftBreakPoint(rArc, directrix); - var site = arc.site; - return site.y === directrix ? site.x : Infinity; - } - function d3_geom_voronoiCell(site) { - this.site = site; - this.edges = []; - } - d3_geom_voronoiCell.prototype.prepare = function() { - var halfEdges = this.edges, iHalfEdge = halfEdges.length, edge; - while (iHalfEdge--) { - edge = halfEdges[iHalfEdge].edge; - if (!edge.b || !edge.a) halfEdges.splice(iHalfEdge, 1); - } - halfEdges.sort(d3_geom_voronoiHalfEdgeOrder); - return halfEdges.length; - }; - function d3_geom_voronoiCloseCells(extent) { - var x0 = extent[0][0], x1 = extent[1][0], y0 = extent[0][1], y1 = extent[1][1], x2, y2, x3, y3, cells = d3_geom_voronoiCells, iCell = cells.length, cell, iHalfEdge, halfEdges, nHalfEdges, start, end; - while (iCell--) { - cell = cells[iCell]; - if (!cell || !cell.prepare()) continue; - halfEdges = cell.edges; - nHalfEdges = halfEdges.length; - iHalfEdge = 0; - while (iHalfEdge < nHalfEdges) { - end = halfEdges[iHalfEdge].end(), x3 = end.x, y3 = end.y; - start = halfEdges[++iHalfEdge % nHalfEdges].start(), x2 = start.x, y2 = start.y; - if (abs(x3 - x2) > ε || abs(y3 - y2) > ε) { - halfEdges.splice(iHalfEdge, 0, new d3_geom_voronoiHalfEdge(d3_geom_voronoiCreateBorderEdge(cell.site, end, abs(x3 - x0) < ε && y1 - y3 > ε ? { - x: x0, - y: abs(x2 - x0) < ε ? y2 : y1 - } : abs(y3 - y1) < ε && x1 - x3 > ε ? { - x: abs(y2 - y1) < ε ? x2 : x1, - y: y1 - } : abs(x3 - x1) < ε && y3 - y0 > ε ? { - x: x1, - y: abs(x2 - x1) < ε ? y2 : y0 - } : abs(y3 - y0) < ε && x3 - x0 > ε ? { - x: abs(y2 - y0) < ε ? x2 : x0, - y: y0 - } : null), cell.site, null)); - ++nHalfEdges; - } - } - } - } - function d3_geom_voronoiHalfEdgeOrder(a, b) { - return b.angle - a.angle; - } - function d3_geom_voronoiCircle() { - d3_geom_voronoiRedBlackNode(this); - this.x = this.y = this.arc = this.site = this.cy = null; - } - function d3_geom_voronoiAttachCircle(arc) { - var lArc = arc.P, rArc = arc.N; - if (!lArc || !rArc) return; - var lSite = lArc.site, cSite = arc.site, rSite = rArc.site; - if (lSite === rSite) return; - var bx = cSite.x, by = cSite.y, ax = lSite.x - bx, ay = lSite.y - by, cx = rSite.x - bx, cy = rSite.y - by; - var d = 2 * (ax * cy - ay * cx); - if (d >= -ε2) return; - var ha = ax * ax + ay * ay, hc = cx * cx + cy * cy, x = (cy * ha - ay * hc) / d, y = (ax * hc - cx * ha) / d, cy = y + by; - var circle = d3_geom_voronoiCirclePool.pop() || new d3_geom_voronoiCircle(); - circle.arc = arc; - circle.site = cSite; - circle.x = x + bx; - circle.y = cy + Math.sqrt(x * x + y * y); - circle.cy = cy; - arc.circle = circle; - var before = null, node = d3_geom_voronoiCircles._; - while (node) { - if (circle.y < node.y || circle.y === node.y && circle.x <= node.x) { - if (node.L) node = node.L; else { - before = node.P; - break; - } - } else { - if (node.R) node = node.R; else { - before = node; - break; - } - } - } - d3_geom_voronoiCircles.insert(before, circle); - if (!before) d3_geom_voronoiFirstCircle = circle; - } - function d3_geom_voronoiDetachCircle(arc) { - var circle = arc.circle; - if (circle) { - if (!circle.P) d3_geom_voronoiFirstCircle = circle.N; - d3_geom_voronoiCircles.remove(circle); - d3_geom_voronoiCirclePool.push(circle); - d3_geom_voronoiRedBlackNode(circle); - arc.circle = null; - } - } - function d3_geom_voronoiClipEdges(extent) { - var edges = d3_geom_voronoiEdges, clip = d3_geom_clipLine(extent[0][0], extent[0][1], extent[1][0], extent[1][1]), i = edges.length, e; - while (i--) { - e = edges[i]; - if (!d3_geom_voronoiConnectEdge(e, extent) || !clip(e) || abs(e.a.x - e.b.x) < ε && abs(e.a.y - e.b.y) < ε) { - e.a = e.b = null; - edges.splice(i, 1); - } - } - } - function d3_geom_voronoiConnectEdge(edge, extent) { - var vb = edge.b; - if (vb) return true; - var va = edge.a, x0 = extent[0][0], x1 = extent[1][0], y0 = extent[0][1], y1 = extent[1][1], lSite = edge.l, rSite = edge.r, lx = lSite.x, ly = lSite.y, rx = rSite.x, ry = rSite.y, fx = (lx + rx) / 2, fy = (ly + ry) / 2, fm, fb; - if (ry === ly) { - if (fx < x0 || fx >= x1) return; - if (lx > rx) { - if (!va) va = { - x: fx, - y: y0 - }; else if (va.y >= y1) return; - vb = { - x: fx, - y: y1 - }; - } else { - if (!va) va = { - x: fx, - y: y1 - }; else if (va.y < y0) return; - vb = { - x: fx, - y: y0 - }; - } - } else { - fm = (lx - rx) / (ry - ly); - fb = fy - fm * fx; - if (fm < -1 || fm > 1) { - if (lx > rx) { - if (!va) va = { - x: (y0 - fb) / fm, - y: y0 - }; else if (va.y >= y1) return; - vb = { - x: (y1 - fb) / fm, - y: y1 - }; - } else { - if (!va) va = { - x: (y1 - fb) / fm, - y: y1 - }; else if (va.y < y0) return; - vb = { - x: (y0 - fb) / fm, - y: y0 - }; - } - } else { - if (ly < ry) { - if (!va) va = { - x: x0, - y: fm * x0 + fb - }; else if (va.x >= x1) return; - vb = { - x: x1, - y: fm * x1 + fb - }; - } else { - if (!va) va = { - x: x1, - y: fm * x1 + fb - }; else if (va.x < x0) return; - vb = { - x: x0, - y: fm * x0 + fb - }; - } - } - } - edge.a = va; - edge.b = vb; - return true; - } - function d3_geom_voronoiEdge(lSite, rSite) { - this.l = lSite; - this.r = rSite; - this.a = this.b = null; - } - function d3_geom_voronoiCreateEdge(lSite, rSite, va, vb) { - var edge = new d3_geom_voronoiEdge(lSite, rSite); - d3_geom_voronoiEdges.push(edge); - if (va) d3_geom_voronoiSetEdgeEnd(edge, lSite, rSite, va); - if (vb) d3_geom_voronoiSetEdgeEnd(edge, rSite, lSite, vb); - d3_geom_voronoiCells[lSite.i].edges.push(new d3_geom_voronoiHalfEdge(edge, lSite, rSite)); - d3_geom_voronoiCells[rSite.i].edges.push(new d3_geom_voronoiHalfEdge(edge, rSite, lSite)); - return edge; - } - function d3_geom_voronoiCreateBorderEdge(lSite, va, vb) { - var edge = new d3_geom_voronoiEdge(lSite, null); - edge.a = va; - edge.b = vb; - d3_geom_voronoiEdges.push(edge); - return edge; - } - function d3_geom_voronoiSetEdgeEnd(edge, lSite, rSite, vertex) { - if (!edge.a && !edge.b) { - edge.a = vertex; - edge.l = lSite; - edge.r = rSite; - } else if (edge.l === rSite) { - edge.b = vertex; - } else { - edge.a = vertex; - } - } - function d3_geom_voronoiHalfEdge(edge, lSite, rSite) { - var va = edge.a, vb = edge.b; - this.edge = edge; - this.site = lSite; - this.angle = rSite ? Math.atan2(rSite.y - lSite.y, rSite.x - lSite.x) : edge.l === lSite ? Math.atan2(vb.x - va.x, va.y - vb.y) : Math.atan2(va.x - vb.x, vb.y - va.y); - } - d3_geom_voronoiHalfEdge.prototype = { - start: function() { - return this.edge.l === this.site ? this.edge.a : this.edge.b; - }, - end: function() { - return this.edge.l === this.site ? this.edge.b : this.edge.a; - } - }; - function d3_geom_voronoiRedBlackTree() { - this._ = null; - } - function d3_geom_voronoiRedBlackNode(node) { - node.U = node.C = node.L = node.R = node.P = node.N = null; - } - d3_geom_voronoiRedBlackTree.prototype = { - insert: function(after, node) { - var parent, grandpa, uncle; - if (after) { - node.P = after; - node.N = after.N; - if (after.N) after.N.P = node; - after.N = node; - if (after.R) { - after = after.R; - while (after.L) after = after.L; - after.L = node; - } else { - after.R = node; - } - parent = after; - } else if (this._) { - after = d3_geom_voronoiRedBlackFirst(this._); - node.P = null; - node.N = after; - after.P = after.L = node; - parent = after; - } else { - node.P = node.N = null; - this._ = node; - parent = null; - } - node.L = node.R = null; - node.U = parent; - node.C = true; - after = node; - while (parent && parent.C) { - grandpa = parent.U; - if (parent === grandpa.L) { - uncle = grandpa.R; - if (uncle && uncle.C) { - parent.C = uncle.C = false; - grandpa.C = true; - after = grandpa; - } else { - if (after === parent.R) { - d3_geom_voronoiRedBlackRotateLeft(this, parent); - after = parent; - parent = after.U; - } - parent.C = false; - grandpa.C = true; - d3_geom_voronoiRedBlackRotateRight(this, grandpa); - } - } else { - uncle = grandpa.L; - if (uncle && uncle.C) { - parent.C = uncle.C = false; - grandpa.C = true; - after = grandpa; - } else { - if (after === parent.L) { - d3_geom_voronoiRedBlackRotateRight(this, parent); - after = parent; - parent = after.U; - } - parent.C = false; - grandpa.C = true; - d3_geom_voronoiRedBlackRotateLeft(this, grandpa); - } - } - parent = after.U; - } - this._.C = false; - }, - remove: function(node) { - if (node.N) node.N.P = node.P; - if (node.P) node.P.N = node.N; - node.N = node.P = null; - var parent = node.U, sibling, left = node.L, right = node.R, next, red; - if (!left) next = right; else if (!right) next = left; else next = d3_geom_voronoiRedBlackFirst(right); - if (parent) { - if (parent.L === node) parent.L = next; else parent.R = next; - } else { - this._ = next; - } - if (left && right) { - red = next.C; - next.C = node.C; - next.L = left; - left.U = next; - if (next !== right) { - parent = next.U; - next.U = node.U; - node = next.R; - parent.L = node; - next.R = right; - right.U = next; - } else { - next.U = parent; - parent = next; - node = next.R; - } - } else { - red = node.C; - node = next; - } - if (node) node.U = parent; - if (red) return; - if (node && node.C) { - node.C = false; - return; - } - do { - if (node === this._) break; - if (node === parent.L) { - sibling = parent.R; - if (sibling.C) { - sibling.C = false; - parent.C = true; - d3_geom_voronoiRedBlackRotateLeft(this, parent); - sibling = parent.R; - } - if (sibling.L && sibling.L.C || sibling.R && sibling.R.C) { - if (!sibling.R || !sibling.R.C) { - sibling.L.C = false; - sibling.C = true; - d3_geom_voronoiRedBlackRotateRight(this, sibling); - sibling = parent.R; - } - sibling.C = parent.C; - parent.C = sibling.R.C = false; - d3_geom_voronoiRedBlackRotateLeft(this, parent); - node = this._; - break; - } - } else { - sibling = parent.L; - if (sibling.C) { - sibling.C = false; - parent.C = true; - d3_geom_voronoiRedBlackRotateRight(this, parent); - sibling = parent.L; - } - if (sibling.L && sibling.L.C || sibling.R && sibling.R.C) { - if (!sibling.L || !sibling.L.C) { - sibling.R.C = false; - sibling.C = true; - d3_geom_voronoiRedBlackRotateLeft(this, sibling); - sibling = parent.L; - } - sibling.C = parent.C; - parent.C = sibling.L.C = false; - d3_geom_voronoiRedBlackRotateRight(this, parent); - node = this._; - break; - } - } - sibling.C = true; - node = parent; - parent = parent.U; - } while (!node.C); - if (node) node.C = false; - } - }; - function d3_geom_voronoiRedBlackRotateLeft(tree, node) { - var p = node, q = node.R, parent = p.U; - if (parent) { - if (parent.L === p) parent.L = q; else parent.R = q; - } else { - tree._ = q; - } - q.U = parent; - p.U = q; - p.R = q.L; - if (p.R) p.R.U = p; - q.L = p; - } - function d3_geom_voronoiRedBlackRotateRight(tree, node) { - var p = node, q = node.L, parent = p.U; - if (parent) { - if (parent.L === p) parent.L = q; else parent.R = q; - } else { - tree._ = q; - } - q.U = parent; - p.U = q; - p.L = q.R; - if (p.L) p.L.U = p; - q.R = p; - } - function d3_geom_voronoiRedBlackFirst(node) { - while (node.L) node = node.L; - return node; - } - function d3_geom_voronoi(sites, bbox) { - var site = sites.sort(d3_geom_voronoiVertexOrder).pop(), x0, y0, circle; - d3_geom_voronoiEdges = []; - d3_geom_voronoiCells = new Array(sites.length); - d3_geom_voronoiBeaches = new d3_geom_voronoiRedBlackTree(); - d3_geom_voronoiCircles = new d3_geom_voronoiRedBlackTree(); - while (true) { - circle = d3_geom_voronoiFirstCircle; - if (site && (!circle || site.y < circle.y || site.y === circle.y && site.x < circle.x)) { - if (site.x !== x0 || site.y !== y0) { - d3_geom_voronoiCells[site.i] = new d3_geom_voronoiCell(site); - d3_geom_voronoiAddBeach(site); - x0 = site.x, y0 = site.y; - } - site = sites.pop(); - } else if (circle) { - d3_geom_voronoiRemoveBeach(circle.arc); - } else { - break; - } - } - if (bbox) d3_geom_voronoiClipEdges(bbox), d3_geom_voronoiCloseCells(bbox); - var diagram = { - cells: d3_geom_voronoiCells, - edges: d3_geom_voronoiEdges - }; - d3_geom_voronoiBeaches = d3_geom_voronoiCircles = d3_geom_voronoiEdges = d3_geom_voronoiCells = null; - return diagram; - } - function d3_geom_voronoiVertexOrder(a, b) { - return b.y - a.y || b.x - a.x; - } - d3.geom.voronoi = function(points) { - var x = d3_geom_pointX, y = d3_geom_pointY, fx = x, fy = y, clipExtent = d3_geom_voronoiClipExtent; - if (points) return voronoi(points); - function voronoi(data) { - var polygons = new Array(data.length), x0 = clipExtent[0][0], y0 = clipExtent[0][1], x1 = clipExtent[1][0], y1 = clipExtent[1][1]; - d3_geom_voronoi(sites(data), clipExtent).cells.forEach(function(cell, i) { - var edges = cell.edges, site = cell.site, polygon = polygons[i] = edges.length ? edges.map(function(e) { - var s = e.start(); - return [ s.x, s.y ]; - }) : site.x >= x0 && site.x <= x1 && site.y >= y0 && site.y <= y1 ? [ [ x0, y1 ], [ x1, y1 ], [ x1, y0 ], [ x0, y0 ] ] : []; - polygon.point = data[i]; - }); - return polygons; - } - function sites(data) { - return data.map(function(d, i) { - return { - x: Math.round(fx(d, i) / ε) * ε, - y: Math.round(fy(d, i) / ε) * ε, - i: i - }; - }); - } - voronoi.links = function(data) { - return d3_geom_voronoi(sites(data)).edges.filter(function(edge) { - return edge.l && edge.r; - }).map(function(edge) { - return { - source: data[edge.l.i], - target: data[edge.r.i] - }; - }); - }; - voronoi.triangles = function(data) { - var triangles = []; - d3_geom_voronoi(sites(data)).cells.forEach(function(cell, i) { - var site = cell.site, edges = cell.edges.sort(d3_geom_voronoiHalfEdgeOrder), j = -1, m = edges.length, e0, s0, e1 = edges[m - 1].edge, s1 = e1.l === site ? e1.r : e1.l; - while (++j < m) { - e0 = e1; - s0 = s1; - e1 = edges[j].edge; - s1 = e1.l === site ? e1.r : e1.l; - if (i < s0.i && i < s1.i && d3_geom_voronoiTriangleArea(site, s0, s1) < 0) { - triangles.push([ data[i], data[s0.i], data[s1.i] ]); - } - } - }); - return triangles; - }; - voronoi.x = function(_) { - return arguments.length ? (fx = d3_functor(x = _), voronoi) : x; - }; - voronoi.y = function(_) { - return arguments.length ? (fy = d3_functor(y = _), voronoi) : y; - }; - voronoi.clipExtent = function(_) { - if (!arguments.length) return clipExtent === d3_geom_voronoiClipExtent ? null : clipExtent; - clipExtent = _ == null ? d3_geom_voronoiClipExtent : _; - return voronoi; - }; - voronoi.size = function(_) { - if (!arguments.length) return clipExtent === d3_geom_voronoiClipExtent ? null : clipExtent && clipExtent[1]; - return voronoi.clipExtent(_ && [ [ 0, 0 ], _ ]); - }; - return voronoi; - }; - var d3_geom_voronoiClipExtent = [ [ -1e6, -1e6 ], [ 1e6, 1e6 ] ]; - function d3_geom_voronoiTriangleArea(a, b, c) { - return (a.x - c.x) * (b.y - a.y) - (a.x - b.x) * (c.y - a.y); - } - d3.geom.delaunay = function(vertices) { - return d3.geom.voronoi().triangles(vertices); - }; - d3.geom.quadtree = function(points, x1, y1, x2, y2) { - var x = d3_geom_pointX, y = d3_geom_pointY, compat; - if (compat = arguments.length) { - x = d3_geom_quadtreeCompatX; - y = d3_geom_quadtreeCompatY; - if (compat === 3) { - y2 = y1; - x2 = x1; - y1 = x1 = 0; - } - return quadtree(points); - } - function quadtree(data) { - var d, fx = d3_functor(x), fy = d3_functor(y), xs, ys, i, n, x1_, y1_, x2_, y2_; - if (x1 != null) { - x1_ = x1, y1_ = y1, x2_ = x2, y2_ = y2; - } else { - x2_ = y2_ = -(x1_ = y1_ = Infinity); - xs = [], ys = []; - n = data.length; - if (compat) for (i = 0; i < n; ++i) { - d = data[i]; - if (d.x < x1_) x1_ = d.x; - if (d.y < y1_) y1_ = d.y; - if (d.x > x2_) x2_ = d.x; - if (d.y > y2_) y2_ = d.y; - xs.push(d.x); - ys.push(d.y); - } else for (i = 0; i < n; ++i) { - var x_ = +fx(d = data[i], i), y_ = +fy(d, i); - if (x_ < x1_) x1_ = x_; - if (y_ < y1_) y1_ = y_; - if (x_ > x2_) x2_ = x_; - if (y_ > y2_) y2_ = y_; - xs.push(x_); - ys.push(y_); - } - } - var dx = x2_ - x1_, dy = y2_ - y1_; - if (dx > dy) y2_ = y1_ + dx; else x2_ = x1_ + dy; - function insert(n, d, x, y, x1, y1, x2, y2) { - if (isNaN(x) || isNaN(y)) return; - if (n.leaf) { - var nx = n.x, ny = n.y; - if (nx != null) { - if (abs(nx - x) + abs(ny - y) < .01) { - insertChild(n, d, x, y, x1, y1, x2, y2); - } else { - var nPoint = n.point; - n.x = n.y = n.point = null; - insertChild(n, nPoint, nx, ny, x1, y1, x2, y2); - insertChild(n, d, x, y, x1, y1, x2, y2); - } - } else { - n.x = x, n.y = y, n.point = d; - } - } else { - insertChild(n, d, x, y, x1, y1, x2, y2); - } - } - function insertChild(n, d, x, y, x1, y1, x2, y2) { - var xm = (x1 + x2) * .5, ym = (y1 + y2) * .5, right = x >= xm, below = y >= ym, i = below << 1 | right; - n.leaf = false; - n = n.nodes[i] || (n.nodes[i] = d3_geom_quadtreeNode()); - if (right) x1 = xm; else x2 = xm; - if (below) y1 = ym; else y2 = ym; - insert(n, d, x, y, x1, y1, x2, y2); - } - var root = d3_geom_quadtreeNode(); - root.add = function(d) { - insert(root, d, +fx(d, ++i), +fy(d, i), x1_, y1_, x2_, y2_); - }; - root.visit = function(f) { - d3_geom_quadtreeVisit(f, root, x1_, y1_, x2_, y2_); - }; - root.find = function(point) { - return d3_geom_quadtreeFind(root, point[0], point[1], x1_, y1_, x2_, y2_); - }; - i = -1; - if (x1 == null) { - while (++i < n) { - insert(root, data[i], xs[i], ys[i], x1_, y1_, x2_, y2_); - } - --i; - } else data.forEach(root.add); - xs = ys = data = d = null; - return root; - } - quadtree.x = function(_) { - return arguments.length ? (x = _, quadtree) : x; - }; - quadtree.y = function(_) { - return arguments.length ? (y = _, quadtree) : y; - }; - quadtree.extent = function(_) { - if (!arguments.length) return x1 == null ? null : [ [ x1, y1 ], [ x2, y2 ] ]; - if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = +_[0][0], y1 = +_[0][1], x2 = +_[1][0], - y2 = +_[1][1]; - return quadtree; - }; - quadtree.size = function(_) { - if (!arguments.length) return x1 == null ? null : [ x2 - x1, y2 - y1 ]; - if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = y1 = 0, x2 = +_[0], y2 = +_[1]; - return quadtree; - }; - return quadtree; - }; - function d3_geom_quadtreeCompatX(d) { - return d.x; - } - function d3_geom_quadtreeCompatY(d) { - return d.y; - } - function d3_geom_quadtreeNode() { - return { - leaf: true, - nodes: [], - point: null, - x: null, - y: null - }; - } - function d3_geom_quadtreeVisit(f, node, x1, y1, x2, y2) { - if (!f(node, x1, y1, x2, y2)) { - var sx = (x1 + x2) * .5, sy = (y1 + y2) * .5, children = node.nodes; - if (children[0]) d3_geom_quadtreeVisit(f, children[0], x1, y1, sx, sy); - if (children[1]) d3_geom_quadtreeVisit(f, children[1], sx, y1, x2, sy); - if (children[2]) d3_geom_quadtreeVisit(f, children[2], x1, sy, sx, y2); - if (children[3]) d3_geom_quadtreeVisit(f, children[3], sx, sy, x2, y2); - } - } - function d3_geom_quadtreeFind(root, x, y, x0, y0, x3, y3) { - var minDistance2 = Infinity, closestPoint; - (function find(node, x1, y1, x2, y2) { - if (x1 > x3 || y1 > y3 || x2 < x0 || y2 < y0) return; - if (point = node.point) { - var point, dx = x - node.x, dy = y - node.y, distance2 = dx * dx + dy * dy; - if (distance2 < minDistance2) { - var distance = Math.sqrt(minDistance2 = distance2); - x0 = x - distance, y0 = y - distance; - x3 = x + distance, y3 = y + distance; - closestPoint = point; - } - } - var children = node.nodes, xm = (x1 + x2) * .5, ym = (y1 + y2) * .5, right = x >= xm, below = y >= ym; - for (var i = below << 1 | right, j = i + 4; i < j; ++i) { - if (node = children[i & 3]) switch (i & 3) { - case 0: - find(node, x1, y1, xm, ym); - break; - - case 1: - find(node, xm, y1, x2, ym); - break; - - case 2: - find(node, x1, ym, xm, y2); - break; - - case 3: - find(node, xm, ym, x2, y2); - break; - } - } - })(root, x0, y0, x3, y3); - return closestPoint; - } - d3.interpolateRgb = d3_interpolateRgb; - function d3_interpolateRgb(a, b) { - a = d3.rgb(a); - b = d3.rgb(b); - var ar = a.r, ag = a.g, ab = a.b, br = b.r - ar, bg = b.g - ag, bb = b.b - ab; - return function(t) { - return "#" + d3_rgb_hex(Math.round(ar + br * t)) + d3_rgb_hex(Math.round(ag + bg * t)) + d3_rgb_hex(Math.round(ab + bb * t)); - }; - } - d3.interpolateObject = d3_interpolateObject; - function d3_interpolateObject(a, b) { - var i = {}, c = {}, k; - for (k in a) { - if (k in b) { - i[k] = d3_interpolate(a[k], b[k]); - } else { - c[k] = a[k]; - } - } - for (k in b) { - if (!(k in a)) { - c[k] = b[k]; - } - } - return function(t) { - for (k in i) c[k] = i[k](t); - return c; - }; - } - d3.interpolateNumber = d3_interpolateNumber; - function d3_interpolateNumber(a, b) { - a = +a, b = +b; - return function(t) { - return a * (1 - t) + b * t; - }; - } - d3.interpolateString = d3_interpolateString; - function d3_interpolateString(a, b) { - var bi = d3_interpolate_numberA.lastIndex = d3_interpolate_numberB.lastIndex = 0, am, bm, bs, i = -1, s = [], q = []; - a = a + "", b = b + ""; - while ((am = d3_interpolate_numberA.exec(a)) && (bm = d3_interpolate_numberB.exec(b))) { - if ((bs = bm.index) > bi) { - bs = b.slice(bi, bs); - if (s[i]) s[i] += bs; else s[++i] = bs; - } - if ((am = am[0]) === (bm = bm[0])) { - if (s[i]) s[i] += bm; else s[++i] = bm; - } else { - s[++i] = null; - q.push({ - i: i, - x: d3_interpolateNumber(am, bm) - }); - } - bi = d3_interpolate_numberB.lastIndex; - } - if (bi < b.length) { - bs = b.slice(bi); - if (s[i]) s[i] += bs; else s[++i] = bs; - } - return s.length < 2 ? q[0] ? (b = q[0].x, function(t) { - return b(t) + ""; - }) : function() { - return b; - } : (b = q.length, function(t) { - for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t); - return s.join(""); - }); - } - var d3_interpolate_numberA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g, d3_interpolate_numberB = new RegExp(d3_interpolate_numberA.source, "g"); - d3.interpolate = d3_interpolate; - function d3_interpolate(a, b) { - var i = d3.interpolators.length, f; - while (--i >= 0 && !(f = d3.interpolators[i](a, b))) ; - return f; - } - d3.interpolators = [ function(a, b) { - var t = typeof b; - return (t === "string" ? d3_rgb_names.has(b.toLowerCase()) || /^(#|rgb\(|hsl\()/i.test(b) ? d3_interpolateRgb : d3_interpolateString : b instanceof d3_color ? d3_interpolateRgb : Array.isArray(b) ? d3_interpolateArray : t === "object" && isNaN(b) ? d3_interpolateObject : d3_interpolateNumber)(a, b); - } ]; - d3.interpolateArray = d3_interpolateArray; - function d3_interpolateArray(a, b) { - var x = [], c = [], na = a.length, nb = b.length, n0 = Math.min(a.length, b.length), i; - for (i = 0; i < n0; ++i) x.push(d3_interpolate(a[i], b[i])); - for (;i < na; ++i) c[i] = a[i]; - for (;i < nb; ++i) c[i] = b[i]; - return function(t) { - for (i = 0; i < n0; ++i) c[i] = x[i](t); - return c; - }; - } - var d3_ease_default = function() { - return d3_identity; - }; - var d3_ease = d3.map({ - linear: d3_ease_default, - poly: d3_ease_poly, - quad: function() { - return d3_ease_quad; - }, - cubic: function() { - return d3_ease_cubic; - }, - sin: function() { - return d3_ease_sin; - }, - exp: function() { - return d3_ease_exp; - }, - circle: function() { - return d3_ease_circle; - }, - elastic: d3_ease_elastic, - back: d3_ease_back, - bounce: function() { - return d3_ease_bounce; - } - }); - var d3_ease_mode = d3.map({ - "in": d3_identity, - out: d3_ease_reverse, - "in-out": d3_ease_reflect, - "out-in": function(f) { - return d3_ease_reflect(d3_ease_reverse(f)); - } - }); - d3.ease = function(name) { - var i = name.indexOf("-"), t = i >= 0 ? name.slice(0, i) : name, m = i >= 0 ? name.slice(i + 1) : "in"; - t = d3_ease.get(t) || d3_ease_default; - m = d3_ease_mode.get(m) || d3_identity; - return d3_ease_clamp(m(t.apply(null, d3_arraySlice.call(arguments, 1)))); - }; - function d3_ease_clamp(f) { - return function(t) { - return t <= 0 ? 0 : t >= 1 ? 1 : f(t); - }; - } - function d3_ease_reverse(f) { - return function(t) { - return 1 - f(1 - t); - }; - } - function d3_ease_reflect(f) { - return function(t) { - return .5 * (t < .5 ? f(2 * t) : 2 - f(2 - 2 * t)); - }; - } - function d3_ease_quad(t) { - return t * t; - } - function d3_ease_cubic(t) { - return t * t * t; - } - function d3_ease_cubicInOut(t) { - if (t <= 0) return 0; - if (t >= 1) return 1; - var t2 = t * t, t3 = t2 * t; - return 4 * (t < .5 ? t3 : 3 * (t - t2) + t3 - .75); - } - function d3_ease_poly(e) { - return function(t) { - return Math.pow(t, e); - }; - } - function d3_ease_sin(t) { - return 1 - Math.cos(t * halfπ); - } - function d3_ease_exp(t) { - return Math.pow(2, 10 * (t - 1)); - } - function d3_ease_circle(t) { - return 1 - Math.sqrt(1 - t * t); - } - function d3_ease_elastic(a, p) { - var s; - if (arguments.length < 2) p = .45; - if (arguments.length) s = p / τ * Math.asin(1 / a); else a = 1, s = p / 4; - return function(t) { - return 1 + a * Math.pow(2, -10 * t) * Math.sin((t - s) * τ / p); - }; - } - function d3_ease_back(s) { - if (!s) s = 1.70158; - return function(t) { - return t * t * ((s + 1) * t - s); - }; - } - function d3_ease_bounce(t) { - return t < 1 / 2.75 ? 7.5625 * t * t : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75 : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375 : 7.5625 * (t -= 2.625 / 2.75) * t + .984375; - } - d3.interpolateHcl = d3_interpolateHcl; - function d3_interpolateHcl(a, b) { - a = d3.hcl(a); - b = d3.hcl(b); - var ah = a.h, ac = a.c, al = a.l, bh = b.h - ah, bc = b.c - ac, bl = b.l - al; - if (isNaN(bc)) bc = 0, ac = isNaN(ac) ? b.c : ac; - if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; - return function(t) { - return d3_hcl_lab(ah + bh * t, ac + bc * t, al + bl * t) + ""; - }; - } - d3.interpolateHsl = d3_interpolateHsl; - function d3_interpolateHsl(a, b) { - a = d3.hsl(a); - b = d3.hsl(b); - var ah = a.h, as = a.s, al = a.l, bh = b.h - ah, bs = b.s - as, bl = b.l - al; - if (isNaN(bs)) bs = 0, as = isNaN(as) ? b.s : as; - if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; - return function(t) { - return d3_hsl_rgb(ah + bh * t, as + bs * t, al + bl * t) + ""; - }; - } - d3.interpolateLab = d3_interpolateLab; - function d3_interpolateLab(a, b) { - a = d3.lab(a); - b = d3.lab(b); - var al = a.l, aa = a.a, ab = a.b, bl = b.l - al, ba = b.a - aa, bb = b.b - ab; - return function(t) { - return d3_lab_rgb(al + bl * t, aa + ba * t, ab + bb * t) + ""; - }; - } - d3.interpolateRound = d3_interpolateRound; - function d3_interpolateRound(a, b) { - b -= a; - return function(t) { - return Math.round(a + b * t); - }; - } - d3.transform = function(string) { - var g = d3_document.createElementNS(d3.ns.prefix.svg, "g"); - return (d3.transform = function(string) { - if (string != null) { - g.setAttribute("transform", string); - var t = g.transform.baseVal.consolidate(); - } - return new d3_transform(t ? t.matrix : d3_transformIdentity); - })(string); - }; - function d3_transform(m) { - var r0 = [ m.a, m.b ], r1 = [ m.c, m.d ], kx = d3_transformNormalize(r0), kz = d3_transformDot(r0, r1), ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz)) || 0; - if (r0[0] * r1[1] < r1[0] * r0[1]) { - r0[0] *= -1; - r0[1] *= -1; - kx *= -1; - kz *= -1; - } - this.rotate = (kx ? Math.atan2(r0[1], r0[0]) : Math.atan2(-r1[0], r1[1])) * d3_degrees; - this.translate = [ m.e, m.f ]; - this.scale = [ kx, ky ]; - this.skew = ky ? Math.atan2(kz, ky) * d3_degrees : 0; - } - d3_transform.prototype.toString = function() { - return "translate(" + this.translate + ")rotate(" + this.rotate + ")skewX(" + this.skew + ")scale(" + this.scale + ")"; - }; - function d3_transformDot(a, b) { - return a[0] * b[0] + a[1] * b[1]; - } - function d3_transformNormalize(a) { - var k = Math.sqrt(d3_transformDot(a, a)); - if (k) { - a[0] /= k; - a[1] /= k; - } - return k; - } - function d3_transformCombine(a, b, k) { - a[0] += k * b[0]; - a[1] += k * b[1]; - return a; - } - var d3_transformIdentity = { - a: 1, - b: 0, - c: 0, - d: 1, - e: 0, - f: 0 - }; - d3.interpolateTransform = d3_interpolateTransform; - function d3_interpolateTransform(a, b) { - var s = [], q = [], n, A = d3.transform(a), B = d3.transform(b), ta = A.translate, tb = B.translate, ra = A.rotate, rb = B.rotate, wa = A.skew, wb = B.skew, ka = A.scale, kb = B.scale; - if (ta[0] != tb[0] || ta[1] != tb[1]) { - s.push("translate(", null, ",", null, ")"); - q.push({ - i: 1, - x: d3_interpolateNumber(ta[0], tb[0]) - }, { - i: 3, - x: d3_interpolateNumber(ta[1], tb[1]) - }); - } else if (tb[0] || tb[1]) { - s.push("translate(" + tb + ")"); - } else { - s.push(""); - } - if (ra != rb) { - if (ra - rb > 180) rb += 360; else if (rb - ra > 180) ra += 360; - q.push({ - i: s.push(s.pop() + "rotate(", null, ")") - 2, - x: d3_interpolateNumber(ra, rb) - }); - } else if (rb) { - s.push(s.pop() + "rotate(" + rb + ")"); - } - if (wa != wb) { - q.push({ - i: s.push(s.pop() + "skewX(", null, ")") - 2, - x: d3_interpolateNumber(wa, wb) - }); - } else if (wb) { - s.push(s.pop() + "skewX(" + wb + ")"); - } - if (ka[0] != kb[0] || ka[1] != kb[1]) { - n = s.push(s.pop() + "scale(", null, ",", null, ")"); - q.push({ - i: n - 4, - x: d3_interpolateNumber(ka[0], kb[0]) - }, { - i: n - 2, - x: d3_interpolateNumber(ka[1], kb[1]) - }); - } else if (kb[0] != 1 || kb[1] != 1) { - s.push(s.pop() + "scale(" + kb + ")"); - } - n = q.length; - return function(t) { - var i = -1, o; - while (++i < n) s[(o = q[i]).i] = o.x(t); - return s.join(""); - }; - } - function d3_uninterpolateNumber(a, b) { - b = (b -= a = +a) || 1 / b; - return function(x) { - return (x - a) / b; - }; - } - function d3_uninterpolateClamp(a, b) { - b = (b -= a = +a) || 1 / b; - return function(x) { - return Math.max(0, Math.min(1, (x - a) / b)); - }; - } - d3.layout = {}; - d3.layout.bundle = function() { - return function(links) { - var paths = [], i = -1, n = links.length; - while (++i < n) paths.push(d3_layout_bundlePath(links[i])); - return paths; - }; - }; - function d3_layout_bundlePath(link) { - var start = link.source, end = link.target, lca = d3_layout_bundleLeastCommonAncestor(start, end), points = [ start ]; - while (start !== lca) { - start = start.parent; - points.push(start); - } - var k = points.length; - while (end !== lca) { - points.splice(k, 0, end); - end = end.parent; - } - return points; - } - function d3_layout_bundleAncestors(node) { - var ancestors = [], parent = node.parent; - while (parent != null) { - ancestors.push(node); - node = parent; - parent = parent.parent; - } - ancestors.push(node); - return ancestors; - } - function d3_layout_bundleLeastCommonAncestor(a, b) { - if (a === b) return a; - var aNodes = d3_layout_bundleAncestors(a), bNodes = d3_layout_bundleAncestors(b), aNode = aNodes.pop(), bNode = bNodes.pop(), sharedNode = null; - while (aNode === bNode) { - sharedNode = aNode; - aNode = aNodes.pop(); - bNode = bNodes.pop(); - } - return sharedNode; - } - d3.layout.chord = function() { - var chord = {}, chords, groups, matrix, n, padding = 0, sortGroups, sortSubgroups, sortChords; - function relayout() { - var subgroups = {}, groupSums = [], groupIndex = d3.range(n), subgroupIndex = [], k, x, x0, i, j; - chords = []; - groups = []; - k = 0, i = -1; - while (++i < n) { - x = 0, j = -1; - while (++j < n) { - x += matrix[i][j]; - } - groupSums.push(x); - subgroupIndex.push(d3.range(n)); - k += x; - } - if (sortGroups) { - groupIndex.sort(function(a, b) { - return sortGroups(groupSums[a], groupSums[b]); - }); - } - if (sortSubgroups) { - subgroupIndex.forEach(function(d, i) { - d.sort(function(a, b) { - return sortSubgroups(matrix[i][a], matrix[i][b]); - }); - }); - } - k = (τ - padding * n) / k; - x = 0, i = -1; - while (++i < n) { - x0 = x, j = -1; - while (++j < n) { - var di = groupIndex[i], dj = subgroupIndex[di][j], v = matrix[di][dj], a0 = x, a1 = x += v * k; - subgroups[di + "-" + dj] = { - index: di, - subindex: dj, - startAngle: a0, - endAngle: a1, - value: v - }; - } - groups[di] = { - index: di, - startAngle: x0, - endAngle: x, - value: (x - x0) / k - }; - x += padding; - } - i = -1; - while (++i < n) { - j = i - 1; - while (++j < n) { - var source = subgroups[i + "-" + j], target = subgroups[j + "-" + i]; - if (source.value || target.value) { - chords.push(source.value < target.value ? { - source: target, - target: source - } : { - source: source, - target: target - }); - } - } - } - if (sortChords) resort(); - } - function resort() { - chords.sort(function(a, b) { - return sortChords((a.source.value + a.target.value) / 2, (b.source.value + b.target.value) / 2); - }); - } - chord.matrix = function(x) { - if (!arguments.length) return matrix; - n = (matrix = x) && matrix.length; - chords = groups = null; - return chord; - }; - chord.padding = function(x) { - if (!arguments.length) return padding; - padding = x; - chords = groups = null; - return chord; - }; - chord.sortGroups = function(x) { - if (!arguments.length) return sortGroups; - sortGroups = x; - chords = groups = null; - return chord; - }; - chord.sortSubgroups = function(x) { - if (!arguments.length) return sortSubgroups; - sortSubgroups = x; - chords = null; - return chord; - }; - chord.sortChords = function(x) { - if (!arguments.length) return sortChords; - sortChords = x; - if (chords) resort(); - return chord; - }; - chord.chords = function() { - if (!chords) relayout(); - return chords; - }; - chord.groups = function() { - if (!groups) relayout(); - return groups; - }; - return chord; - }; - d3.layout.force = function() { - var force = {}, event = d3.dispatch("start", "tick", "end"), size = [ 1, 1 ], drag, alpha, friction = .9, linkDistance = d3_layout_forceLinkDistance, linkStrength = d3_layout_forceLinkStrength, charge = -30, chargeDistance2 = d3_layout_forceChargeDistance2, gravity = .1, theta2 = .64, nodes = [], links = [], distances, strengths, charges; - function repulse(node) { - return function(quad, x1, _, x2) { - if (quad.point !== node) { - var dx = quad.cx - node.x, dy = quad.cy - node.y, dw = x2 - x1, dn = dx * dx + dy * dy; - if (dw * dw / theta2 < dn) { - if (dn < chargeDistance2) { - var k = quad.charge / dn; - node.px -= dx * k; - node.py -= dy * k; - } - return true; - } - if (quad.point && dn && dn < chargeDistance2) { - var k = quad.pointCharge / dn; - node.px -= dx * k; - node.py -= dy * k; - } - } - return !quad.charge; - }; - } - force.tick = function() { - if ((alpha *= .99) < .005) { - event.end({ - type: "end", - alpha: alpha = 0 - }); - return true; - } - var n = nodes.length, m = links.length, q, i, o, s, t, l, k, x, y; - for (i = 0; i < m; ++i) { - o = links[i]; - s = o.source; - t = o.target; - x = t.x - s.x; - y = t.y - s.y; - if (l = x * x + y * y) { - l = alpha * strengths[i] * ((l = Math.sqrt(l)) - distances[i]) / l; - x *= l; - y *= l; - t.x -= x * (k = s.weight / (t.weight + s.weight)); - t.y -= y * k; - s.x += x * (k = 1 - k); - s.y += y * k; - } - } - if (k = alpha * gravity) { - x = size[0] / 2; - y = size[1] / 2; - i = -1; - if (k) while (++i < n) { - o = nodes[i]; - o.x += (x - o.x) * k; - o.y += (y - o.y) * k; - } - } - if (charge) { - d3_layout_forceAccumulate(q = d3.geom.quadtree(nodes), alpha, charges); - i = -1; - while (++i < n) { - if (!(o = nodes[i]).fixed) { - q.visit(repulse(o)); - } - } - } - i = -1; - while (++i < n) { - o = nodes[i]; - if (o.fixed) { - o.x = o.px; - o.y = o.py; - } else { - o.x -= (o.px - (o.px = o.x)) * friction; - o.y -= (o.py - (o.py = o.y)) * friction; - } - } - event.tick({ - type: "tick", - alpha: alpha - }); - }; - force.nodes = function(x) { - if (!arguments.length) return nodes; - nodes = x; - return force; - }; - force.links = function(x) { - if (!arguments.length) return links; - links = x; - return force; - }; - force.size = function(x) { - if (!arguments.length) return size; - size = x; - return force; - }; - force.linkDistance = function(x) { - if (!arguments.length) return linkDistance; - linkDistance = typeof x === "function" ? x : +x; - return force; - }; - force.distance = force.linkDistance; - force.linkStrength = function(x) { - if (!arguments.length) return linkStrength; - linkStrength = typeof x === "function" ? x : +x; - return force; - }; - force.friction = function(x) { - if (!arguments.length) return friction; - friction = +x; - return force; - }; - force.charge = function(x) { - if (!arguments.length) return charge; - charge = typeof x === "function" ? x : +x; - return force; - }; - force.chargeDistance = function(x) { - if (!arguments.length) return Math.sqrt(chargeDistance2); - chargeDistance2 = x * x; - return force; - }; - force.gravity = function(x) { - if (!arguments.length) return gravity; - gravity = +x; - return force; - }; - force.theta = function(x) { - if (!arguments.length) return Math.sqrt(theta2); - theta2 = x * x; - return force; - }; - force.alpha = function(x) { - if (!arguments.length) return alpha; - x = +x; - if (alpha) { - if (x > 0) alpha = x; else alpha = 0; - } else if (x > 0) { - event.start({ - type: "start", - alpha: alpha = x - }); - d3.timer(force.tick); - } - return force; - }; - force.start = function() { - var i, n = nodes.length, m = links.length, w = size[0], h = size[1], neighbors, o; - for (i = 0; i < n; ++i) { - (o = nodes[i]).index = i; - o.weight = 0; - } - for (i = 0; i < m; ++i) { - o = links[i]; - if (typeof o.source == "number") o.source = nodes[o.source]; - if (typeof o.target == "number") o.target = nodes[o.target]; - ++o.source.weight; - ++o.target.weight; - } - for (i = 0; i < n; ++i) { - o = nodes[i]; - if (isNaN(o.x)) o.x = position("x", w); - if (isNaN(o.y)) o.y = position("y", h); - if (isNaN(o.px)) o.px = o.x; - if (isNaN(o.py)) o.py = o.y; - } - distances = []; - if (typeof linkDistance === "function") for (i = 0; i < m; ++i) distances[i] = +linkDistance.call(this, links[i], i); else for (i = 0; i < m; ++i) distances[i] = linkDistance; - strengths = []; - if (typeof linkStrength === "function") for (i = 0; i < m; ++i) strengths[i] = +linkStrength.call(this, links[i], i); else for (i = 0; i < m; ++i) strengths[i] = linkStrength; - charges = []; - if (typeof charge === "function") for (i = 0; i < n; ++i) charges[i] = +charge.call(this, nodes[i], i); else for (i = 0; i < n; ++i) charges[i] = charge; - function position(dimension, size) { - if (!neighbors) { - neighbors = new Array(n); - for (j = 0; j < n; ++j) { - neighbors[j] = []; - } - for (j = 0; j < m; ++j) { - var o = links[j]; - neighbors[o.source.index].push(o.target); - neighbors[o.target.index].push(o.source); - } - } - var candidates = neighbors[i], j = -1, l = candidates.length, x; - while (++j < l) if (!isNaN(x = candidates[j][dimension])) return x; - return Math.random() * size; - } - return force.resume(); - }; - force.resume = function() { - return force.alpha(.1); - }; - force.stop = function() { - return force.alpha(0); - }; - force.drag = function() { - if (!drag) drag = d3.behavior.drag().origin(d3_identity).on("dragstart.force", d3_layout_forceDragstart).on("drag.force", dragmove).on("dragend.force", d3_layout_forceDragend); - if (!arguments.length) return drag; - this.on("mouseover.force", d3_layout_forceMouseover).on("mouseout.force", d3_layout_forceMouseout).call(drag); - }; - function dragmove(d) { - d.px = d3.event.x, d.py = d3.event.y; - force.resume(); - } - return d3.rebind(force, event, "on"); - }; - function d3_layout_forceDragstart(d) { - d.fixed |= 2; - } - function d3_layout_forceDragend(d) { - d.fixed &= ~6; - } - function d3_layout_forceMouseover(d) { - d.fixed |= 4; - d.px = d.x, d.py = d.y; - } - function d3_layout_forceMouseout(d) { - d.fixed &= ~4; - } - function d3_layout_forceAccumulate(quad, alpha, charges) { - var cx = 0, cy = 0; - quad.charge = 0; - if (!quad.leaf) { - var nodes = quad.nodes, n = nodes.length, i = -1, c; - while (++i < n) { - c = nodes[i]; - if (c == null) continue; - d3_layout_forceAccumulate(c, alpha, charges); - quad.charge += c.charge; - cx += c.charge * c.cx; - cy += c.charge * c.cy; - } - } - if (quad.point) { - if (!quad.leaf) { - quad.point.x += Math.random() - .5; - quad.point.y += Math.random() - .5; - } - var k = alpha * charges[quad.point.index]; - quad.charge += quad.pointCharge = k; - cx += k * quad.point.x; - cy += k * quad.point.y; - } - quad.cx = cx / quad.charge; - quad.cy = cy / quad.charge; - } - var d3_layout_forceLinkDistance = 20, d3_layout_forceLinkStrength = 1, d3_layout_forceChargeDistance2 = Infinity; - d3.layout.hierarchy = function() { - var sort = d3_layout_hierarchySort, children = d3_layout_hierarchyChildren, value = d3_layout_hierarchyValue; - function hierarchy(root) { - var stack = [ root ], nodes = [], node; - root.depth = 0; - while ((node = stack.pop()) != null) { - nodes.push(node); - if ((childs = children.call(hierarchy, node, node.depth)) && (n = childs.length)) { - var n, childs, child; - while (--n >= 0) { - stack.push(child = childs[n]); - child.parent = node; - child.depth = node.depth + 1; - } - if (value) node.value = 0; - node.children = childs; - } else { - if (value) node.value = +value.call(hierarchy, node, node.depth) || 0; - delete node.children; - } - } - d3_layout_hierarchyVisitAfter(root, function(node) { - var childs, parent; - if (sort && (childs = node.children)) childs.sort(sort); - if (value && (parent = node.parent)) parent.value += node.value; - }); - return nodes; - } - hierarchy.sort = function(x) { - if (!arguments.length) return sort; - sort = x; - return hierarchy; - }; - hierarchy.children = function(x) { - if (!arguments.length) return children; - children = x; - return hierarchy; - }; - hierarchy.value = function(x) { - if (!arguments.length) return value; - value = x; - return hierarchy; - }; - hierarchy.revalue = function(root) { - if (value) { - d3_layout_hierarchyVisitBefore(root, function(node) { - if (node.children) node.value = 0; - }); - d3_layout_hierarchyVisitAfter(root, function(node) { - var parent; - if (!node.children) node.value = +value.call(hierarchy, node, node.depth) || 0; - if (parent = node.parent) parent.value += node.value; - }); - } - return root; - }; - return hierarchy; - }; - function d3_layout_hierarchyRebind(object, hierarchy) { - d3.rebind(object, hierarchy, "sort", "children", "value"); - object.nodes = object; - object.links = d3_layout_hierarchyLinks; - return object; - } - function d3_layout_hierarchyVisitBefore(node, callback) { - var nodes = [ node ]; - while ((node = nodes.pop()) != null) { - callback(node); - if ((children = node.children) && (n = children.length)) { - var n, children; - while (--n >= 0) nodes.push(children[n]); - } - } - } - function d3_layout_hierarchyVisitAfter(node, callback) { - var nodes = [ node ], nodes2 = []; - while ((node = nodes.pop()) != null) { - nodes2.push(node); - if ((children = node.children) && (n = children.length)) { - var i = -1, n, children; - while (++i < n) nodes.push(children[i]); - } - } - while ((node = nodes2.pop()) != null) { - callback(node); - } - } - function d3_layout_hierarchyChildren(d) { - return d.children; - } - function d3_layout_hierarchyValue(d) { - return d.value; - } - function d3_layout_hierarchySort(a, b) { - return b.value - a.value; - } - function d3_layout_hierarchyLinks(nodes) { - return d3.merge(nodes.map(function(parent) { - return (parent.children || []).map(function(child) { - return { - source: parent, - target: child - }; - }); - })); - } - d3.layout.partition = function() { - var hierarchy = d3.layout.hierarchy(), size = [ 1, 1 ]; - function position(node, x, dx, dy) { - var children = node.children; - node.x = x; - node.y = node.depth * dy; - node.dx = dx; - node.dy = dy; - if (children && (n = children.length)) { - var i = -1, n, c, d; - dx = node.value ? dx / node.value : 0; - while (++i < n) { - position(c = children[i], x, d = c.value * dx, dy); - x += d; - } - } - } - function depth(node) { - var children = node.children, d = 0; - if (children && (n = children.length)) { - var i = -1, n; - while (++i < n) d = Math.max(d, depth(children[i])); - } - return 1 + d; - } - function partition(d, i) { - var nodes = hierarchy.call(this, d, i); - position(nodes[0], 0, size[0], size[1] / depth(nodes[0])); - return nodes; - } - partition.size = function(x) { - if (!arguments.length) return size; - size = x; - return partition; - }; - return d3_layout_hierarchyRebind(partition, hierarchy); - }; - d3.layout.pie = function() { - var value = Number, sort = d3_layout_pieSortByValue, startAngle = 0, endAngle = τ, padAngle = 0; - function pie(data) { - var n = data.length, values = data.map(function(d, i) { - return +value.call(pie, d, i); - }), a = +(typeof startAngle === "function" ? startAngle.apply(this, arguments) : startAngle), da = (typeof endAngle === "function" ? endAngle.apply(this, arguments) : endAngle) - a, p = Math.min(Math.abs(da) / n, +(typeof padAngle === "function" ? padAngle.apply(this, arguments) : padAngle)), pa = p * (da < 0 ? -1 : 1), k = (da - n * pa) / d3.sum(values), index = d3.range(n), arcs = [], v; - if (sort != null) index.sort(sort === d3_layout_pieSortByValue ? function(i, j) { - return values[j] - values[i]; - } : function(i, j) { - return sort(data[i], data[j]); - }); - index.forEach(function(i) { - arcs[i] = { - data: data[i], - value: v = values[i], - startAngle: a, - endAngle: a += v * k + pa, - padAngle: p - }; - }); - return arcs; - } - pie.value = function(_) { - if (!arguments.length) return value; - value = _; - return pie; - }; - pie.sort = function(_) { - if (!arguments.length) return sort; - sort = _; - return pie; - }; - pie.startAngle = function(_) { - if (!arguments.length) return startAngle; - startAngle = _; - return pie; - }; - pie.endAngle = function(_) { - if (!arguments.length) return endAngle; - endAngle = _; - return pie; - }; - pie.padAngle = function(_) { - if (!arguments.length) return padAngle; - padAngle = _; - return pie; - }; - return pie; - }; - var d3_layout_pieSortByValue = {}; - d3.layout.stack = function() { - var values = d3_identity, order = d3_layout_stackOrderDefault, offset = d3_layout_stackOffsetZero, out = d3_layout_stackOut, x = d3_layout_stackX, y = d3_layout_stackY; - function stack(data, index) { - if (!(n = data.length)) return data; - var series = data.map(function(d, i) { - return values.call(stack, d, i); - }); - var points = series.map(function(d) { - return d.map(function(v, i) { - return [ x.call(stack, v, i), y.call(stack, v, i) ]; - }); - }); - var orders = order.call(stack, points, index); - series = d3.permute(series, orders); - points = d3.permute(points, orders); - var offsets = offset.call(stack, points, index); - var m = series[0].length, n, i, j, o; - for (j = 0; j < m; ++j) { - out.call(stack, series[0][j], o = offsets[j], points[0][j][1]); - for (i = 1; i < n; ++i) { - out.call(stack, series[i][j], o += points[i - 1][j][1], points[i][j][1]); - } - } - return data; - } - stack.values = function(x) { - if (!arguments.length) return values; - values = x; - return stack; - }; - stack.order = function(x) { - if (!arguments.length) return order; - order = typeof x === "function" ? x : d3_layout_stackOrders.get(x) || d3_layout_stackOrderDefault; - return stack; - }; - stack.offset = function(x) { - if (!arguments.length) return offset; - offset = typeof x === "function" ? x : d3_layout_stackOffsets.get(x) || d3_layout_stackOffsetZero; - return stack; - }; - stack.x = function(z) { - if (!arguments.length) return x; - x = z; - return stack; - }; - stack.y = function(z) { - if (!arguments.length) return y; - y = z; - return stack; - }; - stack.out = function(z) { - if (!arguments.length) return out; - out = z; - return stack; - }; - return stack; - }; - function d3_layout_stackX(d) { - return d.x; - } - function d3_layout_stackY(d) { - return d.y; - } - function d3_layout_stackOut(d, y0, y) { - d.y0 = y0; - d.y = y; - } - var d3_layout_stackOrders = d3.map({ - "inside-out": function(data) { - var n = data.length, i, j, max = data.map(d3_layout_stackMaxIndex), sums = data.map(d3_layout_stackReduceSum), index = d3.range(n).sort(function(a, b) { - return max[a] - max[b]; - }), top = 0, bottom = 0, tops = [], bottoms = []; - for (i = 0; i < n; ++i) { - j = index[i]; - if (top < bottom) { - top += sums[j]; - tops.push(j); - } else { - bottom += sums[j]; - bottoms.push(j); - } - } - return bottoms.reverse().concat(tops); - }, - reverse: function(data) { - return d3.range(data.length).reverse(); - }, - "default": d3_layout_stackOrderDefault - }); - var d3_layout_stackOffsets = d3.map({ - silhouette: function(data) { - var n = data.length, m = data[0].length, sums = [], max = 0, i, j, o, y0 = []; - for (j = 0; j < m; ++j) { - for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; - if (o > max) max = o; - sums.push(o); - } - for (j = 0; j < m; ++j) { - y0[j] = (max - sums[j]) / 2; - } - return y0; - }, - wiggle: function(data) { - var n = data.length, x = data[0], m = x.length, i, j, k, s1, s2, s3, dx, o, o0, y0 = []; - y0[0] = o = o0 = 0; - for (j = 1; j < m; ++j) { - for (i = 0, s1 = 0; i < n; ++i) s1 += data[i][j][1]; - for (i = 0, s2 = 0, dx = x[j][0] - x[j - 1][0]; i < n; ++i) { - for (k = 0, s3 = (data[i][j][1] - data[i][j - 1][1]) / (2 * dx); k < i; ++k) { - s3 += (data[k][j][1] - data[k][j - 1][1]) / dx; - } - s2 += s3 * data[i][j][1]; - } - y0[j] = o -= s1 ? s2 / s1 * dx : 0; - if (o < o0) o0 = o; - } - for (j = 0; j < m; ++j) y0[j] -= o0; - return y0; - }, - expand: function(data) { - var n = data.length, m = data[0].length, k = 1 / n, i, j, o, y0 = []; - for (j = 0; j < m; ++j) { - for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; - if (o) for (i = 0; i < n; i++) data[i][j][1] /= o; else for (i = 0; i < n; i++) data[i][j][1] = k; - } - for (j = 0; j < m; ++j) y0[j] = 0; - return y0; - }, - zero: d3_layout_stackOffsetZero - }); - function d3_layout_stackOrderDefault(data) { - return d3.range(data.length); - } - function d3_layout_stackOffsetZero(data) { - var j = -1, m = data[0].length, y0 = []; - while (++j < m) y0[j] = 0; - return y0; - } - function d3_layout_stackMaxIndex(array) { - var i = 1, j = 0, v = array[0][1], k, n = array.length; - for (;i < n; ++i) { - if ((k = array[i][1]) > v) { - j = i; - v = k; - } - } - return j; - } - function d3_layout_stackReduceSum(d) { - return d.reduce(d3_layout_stackSum, 0); - } - function d3_layout_stackSum(p, d) { - return p + d[1]; - } - d3.layout.histogram = function() { - var frequency = true, valuer = Number, ranger = d3_layout_histogramRange, binner = d3_layout_histogramBinSturges; - function histogram(data, i) { - var bins = [], values = data.map(valuer, this), range = ranger.call(this, values, i), thresholds = binner.call(this, range, values, i), bin, i = -1, n = values.length, m = thresholds.length - 1, k = frequency ? 1 : 1 / n, x; - while (++i < m) { - bin = bins[i] = []; - bin.dx = thresholds[i + 1] - (bin.x = thresholds[i]); - bin.y = 0; - } - if (m > 0) { - i = -1; - while (++i < n) { - x = values[i]; - if (x >= range[0] && x <= range[1]) { - bin = bins[d3.bisect(thresholds, x, 1, m) - 1]; - bin.y += k; - bin.push(data[i]); - } - } - } - return bins; - } - histogram.value = function(x) { - if (!arguments.length) return valuer; - valuer = x; - return histogram; - }; - histogram.range = function(x) { - if (!arguments.length) return ranger; - ranger = d3_functor(x); - return histogram; - }; - histogram.bins = function(x) { - if (!arguments.length) return binner; - binner = typeof x === "number" ? function(range) { - return d3_layout_histogramBinFixed(range, x); - } : d3_functor(x); - return histogram; - }; - histogram.frequency = function(x) { - if (!arguments.length) return frequency; - frequency = !!x; - return histogram; - }; - return histogram; - }; - function d3_layout_histogramBinSturges(range, values) { - return d3_layout_histogramBinFixed(range, Math.ceil(Math.log(values.length) / Math.LN2 + 1)); - } - function d3_layout_histogramBinFixed(range, n) { - var x = -1, b = +range[0], m = (range[1] - b) / n, f = []; - while (++x <= n) f[x] = m * x + b; - return f; - } - function d3_layout_histogramRange(values) { - return [ d3.min(values), d3.max(values) ]; - } - d3.layout.pack = function() { - var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort), padding = 0, size = [ 1, 1 ], radius; - function pack(d, i) { - var nodes = hierarchy.call(this, d, i), root = nodes[0], w = size[0], h = size[1], r = radius == null ? Math.sqrt : typeof radius === "function" ? radius : function() { - return radius; - }; - root.x = root.y = 0; - d3_layout_hierarchyVisitAfter(root, function(d) { - d.r = +r(d.value); - }); - d3_layout_hierarchyVisitAfter(root, d3_layout_packSiblings); - if (padding) { - var dr = padding * (radius ? 1 : Math.max(2 * root.r / w, 2 * root.r / h)) / 2; - d3_layout_hierarchyVisitAfter(root, function(d) { - d.r += dr; - }); - d3_layout_hierarchyVisitAfter(root, d3_layout_packSiblings); - d3_layout_hierarchyVisitAfter(root, function(d) { - d.r -= dr; - }); - } - d3_layout_packTransform(root, w / 2, h / 2, radius ? 1 : 1 / Math.max(2 * root.r / w, 2 * root.r / h)); - return nodes; - } - pack.size = function(_) { - if (!arguments.length) return size; - size = _; - return pack; - }; - pack.radius = function(_) { - if (!arguments.length) return radius; - radius = _ == null || typeof _ === "function" ? _ : +_; - return pack; - }; - pack.padding = function(_) { - if (!arguments.length) return padding; - padding = +_; - return pack; - }; - return d3_layout_hierarchyRebind(pack, hierarchy); - }; - function d3_layout_packSort(a, b) { - return a.value - b.value; - } - function d3_layout_packInsert(a, b) { - var c = a._pack_next; - a._pack_next = b; - b._pack_prev = a; - b._pack_next = c; - c._pack_prev = b; - } - function d3_layout_packSplice(a, b) { - a._pack_next = b; - b._pack_prev = a; - } - function d3_layout_packIntersects(a, b) { - var dx = b.x - a.x, dy = b.y - a.y, dr = a.r + b.r; - return .999 * dr * dr > dx * dx + dy * dy; - } - function d3_layout_packSiblings(node) { - if (!(nodes = node.children) || !(n = nodes.length)) return; - var nodes, xMin = Infinity, xMax = -Infinity, yMin = Infinity, yMax = -Infinity, a, b, c, i, j, k, n; - function bound(node) { - xMin = Math.min(node.x - node.r, xMin); - xMax = Math.max(node.x + node.r, xMax); - yMin = Math.min(node.y - node.r, yMin); - yMax = Math.max(node.y + node.r, yMax); - } - nodes.forEach(d3_layout_packLink); - a = nodes[0]; - a.x = -a.r; - a.y = 0; - bound(a); - if (n > 1) { - b = nodes[1]; - b.x = b.r; - b.y = 0; - bound(b); - if (n > 2) { - c = nodes[2]; - d3_layout_packPlace(a, b, c); - bound(c); - d3_layout_packInsert(a, c); - a._pack_prev = c; - d3_layout_packInsert(c, b); - b = a._pack_next; - for (i = 3; i < n; i++) { - d3_layout_packPlace(a, b, c = nodes[i]); - var isect = 0, s1 = 1, s2 = 1; - for (j = b._pack_next; j !== b; j = j._pack_next, s1++) { - if (d3_layout_packIntersects(j, c)) { - isect = 1; - break; - } - } - if (isect == 1) { - for (k = a._pack_prev; k !== j._pack_prev; k = k._pack_prev, s2++) { - if (d3_layout_packIntersects(k, c)) { - break; - } - } - } - if (isect) { - if (s1 < s2 || s1 == s2 && b.r < a.r) d3_layout_packSplice(a, b = j); else d3_layout_packSplice(a = k, b); - i--; - } else { - d3_layout_packInsert(a, c); - b = c; - bound(c); - } - } - } - } - var cx = (xMin + xMax) / 2, cy = (yMin + yMax) / 2, cr = 0; - for (i = 0; i < n; i++) { - c = nodes[i]; - c.x -= cx; - c.y -= cy; - cr = Math.max(cr, c.r + Math.sqrt(c.x * c.x + c.y * c.y)); - } - node.r = cr; - nodes.forEach(d3_layout_packUnlink); - } - function d3_layout_packLink(node) { - node._pack_next = node._pack_prev = node; - } - function d3_layout_packUnlink(node) { - delete node._pack_next; - delete node._pack_prev; - } - function d3_layout_packTransform(node, x, y, k) { - var children = node.children; - node.x = x += k * node.x; - node.y = y += k * node.y; - node.r *= k; - if (children) { - var i = -1, n = children.length; - while (++i < n) d3_layout_packTransform(children[i], x, y, k); - } - } - function d3_layout_packPlace(a, b, c) { - var db = a.r + c.r, dx = b.x - a.x, dy = b.y - a.y; - if (db && (dx || dy)) { - var da = b.r + c.r, dc = dx * dx + dy * dy; - da *= da; - db *= db; - var x = .5 + (db - da) / (2 * dc), y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc); - c.x = a.x + x * dx + y * dy; - c.y = a.y + x * dy - y * dx; - } else { - c.x = a.x + db; - c.y = a.y; - } - } - d3.layout.tree = function() { - var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = null; - function tree(d, i) { - var nodes = hierarchy.call(this, d, i), root0 = nodes[0], root1 = wrapTree(root0); - d3_layout_hierarchyVisitAfter(root1, firstWalk), root1.parent.m = -root1.z; - d3_layout_hierarchyVisitBefore(root1, secondWalk); - if (nodeSize) d3_layout_hierarchyVisitBefore(root0, sizeNode); else { - var left = root0, right = root0, bottom = root0; - d3_layout_hierarchyVisitBefore(root0, function(node) { - if (node.x < left.x) left = node; - if (node.x > right.x) right = node; - if (node.depth > bottom.depth) bottom = node; - }); - var tx = separation(left, right) / 2 - left.x, kx = size[0] / (right.x + separation(right, left) / 2 + tx), ky = size[1] / (bottom.depth || 1); - d3_layout_hierarchyVisitBefore(root0, function(node) { - node.x = (node.x + tx) * kx; - node.y = node.depth * ky; - }); - } - return nodes; - } - function wrapTree(root0) { - var root1 = { - A: null, - children: [ root0 ] - }, queue = [ root1 ], node1; - while ((node1 = queue.pop()) != null) { - for (var children = node1.children, child, i = 0, n = children.length; i < n; ++i) { - queue.push((children[i] = child = { - _: children[i], - parent: node1, - children: (child = children[i].children) && child.slice() || [], - A: null, - a: null, - z: 0, - m: 0, - c: 0, - s: 0, - t: null, - i: i - }).a = child); - } - } - return root1.children[0]; - } - function firstWalk(v) { - var children = v.children, siblings = v.parent.children, w = v.i ? siblings[v.i - 1] : null; - if (children.length) { - d3_layout_treeShift(v); - var midpoint = (children[0].z + children[children.length - 1].z) / 2; - if (w) { - v.z = w.z + separation(v._, w._); - v.m = v.z - midpoint; - } else { - v.z = midpoint; - } - } else if (w) { - v.z = w.z + separation(v._, w._); - } - v.parent.A = apportion(v, w, v.parent.A || siblings[0]); - } - function secondWalk(v) { - v._.x = v.z + v.parent.m; - v.m += v.parent.m; - } - function apportion(v, w, ancestor) { - if (w) { - var vip = v, vop = v, vim = w, vom = vip.parent.children[0], sip = vip.m, sop = vop.m, sim = vim.m, som = vom.m, shift; - while (vim = d3_layout_treeRight(vim), vip = d3_layout_treeLeft(vip), vim && vip) { - vom = d3_layout_treeLeft(vom); - vop = d3_layout_treeRight(vop); - vop.a = v; - shift = vim.z + sim - vip.z - sip + separation(vim._, vip._); - if (shift > 0) { - d3_layout_treeMove(d3_layout_treeAncestor(vim, v, ancestor), v, shift); - sip += shift; - sop += shift; - } - sim += vim.m; - sip += vip.m; - som += vom.m; - sop += vop.m; - } - if (vim && !d3_layout_treeRight(vop)) { - vop.t = vim; - vop.m += sim - sop; - } - if (vip && !d3_layout_treeLeft(vom)) { - vom.t = vip; - vom.m += sip - som; - ancestor = v; - } - } - return ancestor; - } - function sizeNode(node) { - node.x *= size[0]; - node.y = node.depth * size[1]; - } - tree.separation = function(x) { - if (!arguments.length) return separation; - separation = x; - return tree; - }; - tree.size = function(x) { - if (!arguments.length) return nodeSize ? null : size; - nodeSize = (size = x) == null ? sizeNode : null; - return tree; - }; - tree.nodeSize = function(x) { - if (!arguments.length) return nodeSize ? size : null; - nodeSize = (size = x) == null ? null : sizeNode; - return tree; - }; - return d3_layout_hierarchyRebind(tree, hierarchy); - }; - function d3_layout_treeSeparation(a, b) { - return a.parent == b.parent ? 1 : 2; - } - function d3_layout_treeLeft(v) { - var children = v.children; - return children.length ? children[0] : v.t; - } - function d3_layout_treeRight(v) { - var children = v.children, n; - return (n = children.length) ? children[n - 1] : v.t; - } - function d3_layout_treeMove(wm, wp, shift) { - var change = shift / (wp.i - wm.i); - wp.c -= change; - wp.s += shift; - wm.c += change; - wp.z += shift; - wp.m += shift; - } - function d3_layout_treeShift(v) { - var shift = 0, change = 0, children = v.children, i = children.length, w; - while (--i >= 0) { - w = children[i]; - w.z += shift; - w.m += shift; - shift += w.s + (change += w.c); - } - } - function d3_layout_treeAncestor(vim, v, ancestor) { - return vim.a.parent === v.parent ? vim.a : ancestor; - } - d3.layout.cluster = function() { - var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = false; - function cluster(d, i) { - var nodes = hierarchy.call(this, d, i), root = nodes[0], previousNode, x = 0; - d3_layout_hierarchyVisitAfter(root, function(node) { - var children = node.children; - if (children && children.length) { - node.x = d3_layout_clusterX(children); - node.y = d3_layout_clusterY(children); - } else { - node.x = previousNode ? x += separation(node, previousNode) : 0; - node.y = 0; - previousNode = node; - } - }); - var left = d3_layout_clusterLeft(root), right = d3_layout_clusterRight(root), x0 = left.x - separation(left, right) / 2, x1 = right.x + separation(right, left) / 2; - d3_layout_hierarchyVisitAfter(root, nodeSize ? function(node) { - node.x = (node.x - root.x) * size[0]; - node.y = (root.y - node.y) * size[1]; - } : function(node) { - node.x = (node.x - x0) / (x1 - x0) * size[0]; - node.y = (1 - (root.y ? node.y / root.y : 1)) * size[1]; - }); - return nodes; - } - cluster.separation = function(x) { - if (!arguments.length) return separation; - separation = x; - return cluster; - }; - cluster.size = function(x) { - if (!arguments.length) return nodeSize ? null : size; - nodeSize = (size = x) == null; - return cluster; - }; - cluster.nodeSize = function(x) { - if (!arguments.length) return nodeSize ? size : null; - nodeSize = (size = x) != null; - return cluster; - }; - return d3_layout_hierarchyRebind(cluster, hierarchy); - }; - function d3_layout_clusterY(children) { - return 1 + d3.max(children, function(child) { - return child.y; - }); - } - function d3_layout_clusterX(children) { - return children.reduce(function(x, child) { - return x + child.x; - }, 0) / children.length; - } - function d3_layout_clusterLeft(node) { - var children = node.children; - return children && children.length ? d3_layout_clusterLeft(children[0]) : node; - } - function d3_layout_clusterRight(node) { - var children = node.children, n; - return children && (n = children.length) ? d3_layout_clusterRight(children[n - 1]) : node; - } - d3.layout.treemap = function() { - var hierarchy = d3.layout.hierarchy(), round = Math.round, size = [ 1, 1 ], padding = null, pad = d3_layout_treemapPadNull, sticky = false, stickies, mode = "squarify", ratio = .5 * (1 + Math.sqrt(5)); - function scale(children, k) { - var i = -1, n = children.length, child, area; - while (++i < n) { - area = (child = children[i]).value * (k < 0 ? 0 : k); - child.area = isNaN(area) || area <= 0 ? 0 : area; - } - } - function squarify(node) { - var children = node.children; - if (children && children.length) { - var rect = pad(node), row = [], remaining = children.slice(), child, best = Infinity, score, u = mode === "slice" ? rect.dx : mode === "dice" ? rect.dy : mode === "slice-dice" ? node.depth & 1 ? rect.dy : rect.dx : Math.min(rect.dx, rect.dy), n; - scale(remaining, rect.dx * rect.dy / node.value); - row.area = 0; - while ((n = remaining.length) > 0) { - row.push(child = remaining[n - 1]); - row.area += child.area; - if (mode !== "squarify" || (score = worst(row, u)) <= best) { - remaining.pop(); - best = score; - } else { - row.area -= row.pop().area; - position(row, u, rect, false); - u = Math.min(rect.dx, rect.dy); - row.length = row.area = 0; - best = Infinity; - } - } - if (row.length) { - position(row, u, rect, true); - row.length = row.area = 0; - } - children.forEach(squarify); - } - } - function stickify(node) { - var children = node.children; - if (children && children.length) { - var rect = pad(node), remaining = children.slice(), child, row = []; - scale(remaining, rect.dx * rect.dy / node.value); - row.area = 0; - while (child = remaining.pop()) { - row.push(child); - row.area += child.area; - if (child.z != null) { - position(row, child.z ? rect.dx : rect.dy, rect, !remaining.length); - row.length = row.area = 0; - } - } - children.forEach(stickify); - } - } - function worst(row, u) { - var s = row.area, r, rmax = 0, rmin = Infinity, i = -1, n = row.length; - while (++i < n) { - if (!(r = row[i].area)) continue; - if (r < rmin) rmin = r; - if (r > rmax) rmax = r; - } - s *= s; - u *= u; - return s ? Math.max(u * rmax * ratio / s, s / (u * rmin * ratio)) : Infinity; - } - function position(row, u, rect, flush) { - var i = -1, n = row.length, x = rect.x, y = rect.y, v = u ? round(row.area / u) : 0, o; - if (u == rect.dx) { - if (flush || v > rect.dy) v = rect.dy; - while (++i < n) { - o = row[i]; - o.x = x; - o.y = y; - o.dy = v; - x += o.dx = Math.min(rect.x + rect.dx - x, v ? round(o.area / v) : 0); - } - o.z = true; - o.dx += rect.x + rect.dx - x; - rect.y += v; - rect.dy -= v; - } else { - if (flush || v > rect.dx) v = rect.dx; - while (++i < n) { - o = row[i]; - o.x = x; - o.y = y; - o.dx = v; - y += o.dy = Math.min(rect.y + rect.dy - y, v ? round(o.area / v) : 0); - } - o.z = false; - o.dy += rect.y + rect.dy - y; - rect.x += v; - rect.dx -= v; - } - } - function treemap(d) { - var nodes = stickies || hierarchy(d), root = nodes[0]; - root.x = 0; - root.y = 0; - root.dx = size[0]; - root.dy = size[1]; - if (stickies) hierarchy.revalue(root); - scale([ root ], root.dx * root.dy / root.value); - (stickies ? stickify : squarify)(root); - if (sticky) stickies = nodes; - return nodes; - } - treemap.size = function(x) { - if (!arguments.length) return size; - size = x; - return treemap; - }; - treemap.padding = function(x) { - if (!arguments.length) return padding; - function padFunction(node) { - var p = x.call(treemap, node, node.depth); - return p == null ? d3_layout_treemapPadNull(node) : d3_layout_treemapPad(node, typeof p === "number" ? [ p, p, p, p ] : p); - } - function padConstant(node) { - return d3_layout_treemapPad(node, x); - } - var type; - pad = (padding = x) == null ? d3_layout_treemapPadNull : (type = typeof x) === "function" ? padFunction : type === "number" ? (x = [ x, x, x, x ], - padConstant) : padConstant; - return treemap; - }; - treemap.round = function(x) { - if (!arguments.length) return round != Number; - round = x ? Math.round : Number; - return treemap; - }; - treemap.sticky = function(x) { - if (!arguments.length) return sticky; - sticky = x; - stickies = null; - return treemap; - }; - treemap.ratio = function(x) { - if (!arguments.length) return ratio; - ratio = x; - return treemap; - }; - treemap.mode = function(x) { - if (!arguments.length) return mode; - mode = x + ""; - return treemap; - }; - return d3_layout_hierarchyRebind(treemap, hierarchy); - }; - function d3_layout_treemapPadNull(node) { - return { - x: node.x, - y: node.y, - dx: node.dx, - dy: node.dy - }; - } - function d3_layout_treemapPad(node, padding) { - var x = node.x + padding[3], y = node.y + padding[0], dx = node.dx - padding[1] - padding[3], dy = node.dy - padding[0] - padding[2]; - if (dx < 0) { - x += dx / 2; - dx = 0; - } - if (dy < 0) { - y += dy / 2; - dy = 0; - } - return { - x: x, - y: y, - dx: dx, - dy: dy - }; - } - d3.random = { - normal: function(µ, σ) { - var n = arguments.length; - if (n < 2) σ = 1; - if (n < 1) µ = 0; - return function() { - var x, y, r; - do { - x = Math.random() * 2 - 1; - y = Math.random() * 2 - 1; - r = x * x + y * y; - } while (!r || r > 1); - return µ + σ * x * Math.sqrt(-2 * Math.log(r) / r); - }; - }, - logNormal: function() { - var random = d3.random.normal.apply(d3, arguments); - return function() { - return Math.exp(random()); - }; - }, - bates: function(m) { - var random = d3.random.irwinHall(m); - return function() { - return random() / m; - }; - }, - irwinHall: function(m) { - return function() { - for (var s = 0, j = 0; j < m; j++) s += Math.random(); - return s; - }; - } - }; - d3.scale = {}; - function d3_scaleExtent(domain) { - var start = domain[0], stop = domain[domain.length - 1]; - return start < stop ? [ start, stop ] : [ stop, start ]; - } - function d3_scaleRange(scale) { - return scale.rangeExtent ? scale.rangeExtent() : d3_scaleExtent(scale.range()); - } - function d3_scale_bilinear(domain, range, uninterpolate, interpolate) { - var u = uninterpolate(domain[0], domain[1]), i = interpolate(range[0], range[1]); - return function(x) { - return i(u(x)); - }; - } - function d3_scale_nice(domain, nice) { - var i0 = 0, i1 = domain.length - 1, x0 = domain[i0], x1 = domain[i1], dx; - if (x1 < x0) { - dx = i0, i0 = i1, i1 = dx; - dx = x0, x0 = x1, x1 = dx; - } - domain[i0] = nice.floor(x0); - domain[i1] = nice.ceil(x1); - return domain; - } - function d3_scale_niceStep(step) { - return step ? { - floor: function(x) { - return Math.floor(x / step) * step; - }, - ceil: function(x) { - return Math.ceil(x / step) * step; - } - } : d3_scale_niceIdentity; - } - var d3_scale_niceIdentity = { - floor: d3_identity, - ceil: d3_identity - }; - function d3_scale_polylinear(domain, range, uninterpolate, interpolate) { - var u = [], i = [], j = 0, k = Math.min(domain.length, range.length) - 1; - if (domain[k] < domain[0]) { - domain = domain.slice().reverse(); - range = range.slice().reverse(); - } - while (++j <= k) { - u.push(uninterpolate(domain[j - 1], domain[j])); - i.push(interpolate(range[j - 1], range[j])); - } - return function(x) { - var j = d3.bisect(domain, x, 1, k) - 1; - return i[j](u[j](x)); - }; - } - d3.scale.linear = function() { - return d3_scale_linear([ 0, 1 ], [ 0, 1 ], d3_interpolate, false); - }; - function d3_scale_linear(domain, range, interpolate, clamp) { - var output, input; - function rescale() { - var linear = Math.min(domain.length, range.length) > 2 ? d3_scale_polylinear : d3_scale_bilinear, uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber; - output = linear(domain, range, uninterpolate, interpolate); - input = linear(range, domain, uninterpolate, d3_interpolate); - return scale; - } - function scale(x) { - return output(x); - } - scale.invert = function(y) { - return input(y); - }; - scale.domain = function(x) { - if (!arguments.length) return domain; - domain = x.map(Number); - return rescale(); - }; - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - return rescale(); - }; - scale.rangeRound = function(x) { - return scale.range(x).interpolate(d3_interpolateRound); - }; - scale.clamp = function(x) { - if (!arguments.length) return clamp; - clamp = x; - return rescale(); - }; - scale.interpolate = function(x) { - if (!arguments.length) return interpolate; - interpolate = x; - return rescale(); - }; - scale.ticks = function(m) { - return d3_scale_linearTicks(domain, m); - }; - scale.tickFormat = function(m, format) { - return d3_scale_linearTickFormat(domain, m, format); - }; - scale.nice = function(m) { - d3_scale_linearNice(domain, m); - return rescale(); - }; - scale.copy = function() { - return d3_scale_linear(domain, range, interpolate, clamp); - }; - return rescale(); - } - function d3_scale_linearRebind(scale, linear) { - return d3.rebind(scale, linear, "range", "rangeRound", "interpolate", "clamp"); - } - function d3_scale_linearNice(domain, m) { - return d3_scale_nice(domain, d3_scale_niceStep(d3_scale_linearTickRange(domain, m)[2])); - } - function d3_scale_linearTickRange(domain, m) { - if (m == null) m = 10; - var extent = d3_scaleExtent(domain), span = extent[1] - extent[0], step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)), err = m / span * step; - if (err <= .15) step *= 10; else if (err <= .35) step *= 5; else if (err <= .75) step *= 2; - extent[0] = Math.ceil(extent[0] / step) * step; - extent[1] = Math.floor(extent[1] / step) * step + step * .5; - extent[2] = step; - return extent; - } - function d3_scale_linearTicks(domain, m) { - return d3.range.apply(d3, d3_scale_linearTickRange(domain, m)); - } - function d3_scale_linearTickFormat(domain, m, format) { - var range = d3_scale_linearTickRange(domain, m); - if (format) { - var match = d3_format_re.exec(format); - match.shift(); - if (match[8] === "s") { - var prefix = d3.formatPrefix(Math.max(abs(range[0]), abs(range[1]))); - if (!match[7]) match[7] = "." + d3_scale_linearPrecision(prefix.scale(range[2])); - match[8] = "f"; - format = d3.format(match.join("")); - return function(d) { - return format(prefix.scale(d)) + prefix.symbol; - }; - } - if (!match[7]) match[7] = "." + d3_scale_linearFormatPrecision(match[8], range); - format = match.join(""); - } else { - format = ",." + d3_scale_linearPrecision(range[2]) + "f"; - } - return d3.format(format); - } - var d3_scale_linearFormatSignificant = { - s: 1, - g: 1, - p: 1, - r: 1, - e: 1 - }; - function d3_scale_linearPrecision(value) { - return -Math.floor(Math.log(value) / Math.LN10 + .01); - } - function d3_scale_linearFormatPrecision(type, range) { - var p = d3_scale_linearPrecision(range[2]); - return type in d3_scale_linearFormatSignificant ? Math.abs(p - d3_scale_linearPrecision(Math.max(abs(range[0]), abs(range[1])))) + +(type !== "e") : p - (type === "%") * 2; - } - d3.scale.log = function() { - return d3_scale_log(d3.scale.linear().domain([ 0, 1 ]), 10, true, [ 1, 10 ]); - }; - function d3_scale_log(linear, base, positive, domain) { - function log(x) { - return (positive ? Math.log(x < 0 ? 0 : x) : -Math.log(x > 0 ? 0 : -x)) / Math.log(base); - } - function pow(x) { - return positive ? Math.pow(base, x) : -Math.pow(base, -x); - } - function scale(x) { - return linear(log(x)); - } - scale.invert = function(x) { - return pow(linear.invert(x)); - }; - scale.domain = function(x) { - if (!arguments.length) return domain; - positive = x[0] >= 0; - linear.domain((domain = x.map(Number)).map(log)); - return scale; - }; - scale.base = function(_) { - if (!arguments.length) return base; - base = +_; - linear.domain(domain.map(log)); - return scale; - }; - scale.nice = function() { - var niced = d3_scale_nice(domain.map(log), positive ? Math : d3_scale_logNiceNegative); - linear.domain(niced); - domain = niced.map(pow); - return scale; - }; - scale.ticks = function() { - var extent = d3_scaleExtent(domain), ticks = [], u = extent[0], v = extent[1], i = Math.floor(log(u)), j = Math.ceil(log(v)), n = base % 1 ? 2 : base; - if (isFinite(j - i)) { - if (positive) { - for (;i < j; i++) for (var k = 1; k < n; k++) ticks.push(pow(i) * k); - ticks.push(pow(i)); - } else { - ticks.push(pow(i)); - for (;i++ < j; ) for (var k = n - 1; k > 0; k--) ticks.push(pow(i) * k); - } - for (i = 0; ticks[i] < u; i++) {} - for (j = ticks.length; ticks[j - 1] > v; j--) {} - ticks = ticks.slice(i, j); - } - return ticks; - }; - scale.tickFormat = function(n, format) { - if (!arguments.length) return d3_scale_logFormat; - if (arguments.length < 2) format = d3_scale_logFormat; else if (typeof format !== "function") format = d3.format(format); - var k = Math.max(.1, n / scale.ticks().length), f = positive ? (e = 1e-12, Math.ceil) : (e = -1e-12, - Math.floor), e; - return function(d) { - return d / pow(f(log(d) + e)) <= k ? format(d) : ""; - }; - }; - scale.copy = function() { - return d3_scale_log(linear.copy(), base, positive, domain); - }; - return d3_scale_linearRebind(scale, linear); - } - var d3_scale_logFormat = d3.format(".0e"), d3_scale_logNiceNegative = { - floor: function(x) { - return -Math.ceil(-x); - }, - ceil: function(x) { - return -Math.floor(-x); - } - }; - d3.scale.pow = function() { - return d3_scale_pow(d3.scale.linear(), 1, [ 0, 1 ]); - }; - function d3_scale_pow(linear, exponent, domain) { - var powp = d3_scale_powPow(exponent), powb = d3_scale_powPow(1 / exponent); - function scale(x) { - return linear(powp(x)); - } - scale.invert = function(x) { - return powb(linear.invert(x)); - }; - scale.domain = function(x) { - if (!arguments.length) return domain; - linear.domain((domain = x.map(Number)).map(powp)); - return scale; - }; - scale.ticks = function(m) { - return d3_scale_linearTicks(domain, m); - }; - scale.tickFormat = function(m, format) { - return d3_scale_linearTickFormat(domain, m, format); - }; - scale.nice = function(m) { - return scale.domain(d3_scale_linearNice(domain, m)); - }; - scale.exponent = function(x) { - if (!arguments.length) return exponent; - powp = d3_scale_powPow(exponent = x); - powb = d3_scale_powPow(1 / exponent); - linear.domain(domain.map(powp)); - return scale; - }; - scale.copy = function() { - return d3_scale_pow(linear.copy(), exponent, domain); - }; - return d3_scale_linearRebind(scale, linear); - } - function d3_scale_powPow(e) { - return function(x) { - return x < 0 ? -Math.pow(-x, e) : Math.pow(x, e); - }; - } - d3.scale.sqrt = function() { - return d3.scale.pow().exponent(.5); - }; - d3.scale.ordinal = function() { - return d3_scale_ordinal([], { - t: "range", - a: [ [] ] - }); - }; - function d3_scale_ordinal(domain, ranger) { - var index, range, rangeBand; - function scale(x) { - return range[((index.get(x) || (ranger.t === "range" ? index.set(x, domain.push(x)) : NaN)) - 1) % range.length]; - } - function steps(start, step) { - return d3.range(domain.length).map(function(i) { - return start + step * i; - }); - } - scale.domain = function(x) { - if (!arguments.length) return domain; - domain = []; - index = new d3_Map(); - var i = -1, n = x.length, xi; - while (++i < n) if (!index.has(xi = x[i])) index.set(xi, domain.push(xi)); - return scale[ranger.t].apply(scale, ranger.a); - }; - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - rangeBand = 0; - ranger = { - t: "range", - a: arguments - }; - return scale; - }; - scale.rangePoints = function(x, padding) { - if (arguments.length < 2) padding = 0; - var start = x[0], stop = x[1], step = domain.length < 2 ? (start = (start + stop) / 2, - 0) : (stop - start) / (domain.length - 1 + padding); - range = steps(start + step * padding / 2, step); - rangeBand = 0; - ranger = { - t: "rangePoints", - a: arguments - }; - return scale; - }; - scale.rangeRoundPoints = function(x, padding) { - if (arguments.length < 2) padding = 0; - var start = x[0], stop = x[1], step = domain.length < 2 ? (start = stop = Math.round((start + stop) / 2), - 0) : (stop - start) / (domain.length - 1 + padding) | 0; - range = steps(start + Math.round(step * padding / 2 + (stop - start - (domain.length - 1 + padding) * step) / 2), step); - rangeBand = 0; - ranger = { - t: "rangeRoundPoints", - a: arguments - }; - return scale; - }; - scale.rangeBands = function(x, padding, outerPadding) { - if (arguments.length < 2) padding = 0; - if (arguments.length < 3) outerPadding = padding; - var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = (stop - start) / (domain.length - padding + 2 * outerPadding); - range = steps(start + step * outerPadding, step); - if (reverse) range.reverse(); - rangeBand = step * (1 - padding); - ranger = { - t: "rangeBands", - a: arguments - }; - return scale; - }; - scale.rangeRoundBands = function(x, padding, outerPadding) { - if (arguments.length < 2) padding = 0; - if (arguments.length < 3) outerPadding = padding; - var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = Math.floor((stop - start) / (domain.length - padding + 2 * outerPadding)); - range = steps(start + Math.round((stop - start - (domain.length - padding) * step) / 2), step); - if (reverse) range.reverse(); - rangeBand = Math.round(step * (1 - padding)); - ranger = { - t: "rangeRoundBands", - a: arguments - }; - return scale; - }; - scale.rangeBand = function() { - return rangeBand; - }; - scale.rangeExtent = function() { - return d3_scaleExtent(ranger.a[0]); - }; - scale.copy = function() { - return d3_scale_ordinal(domain, ranger); - }; - return scale.domain(domain); - } - d3.scale.category10 = function() { - return d3.scale.ordinal().range(d3_category10); - }; - d3.scale.category20 = function() { - return d3.scale.ordinal().range(d3_category20); - }; - d3.scale.category20b = function() { - return d3.scale.ordinal().range(d3_category20b); - }; - d3.scale.category20c = function() { - return d3.scale.ordinal().range(d3_category20c); - }; - var d3_category10 = [ 2062260, 16744206, 2924588, 14034728, 9725885, 9197131, 14907330, 8355711, 12369186, 1556175 ].map(d3_rgbString); - var d3_category20 = [ 2062260, 11454440, 16744206, 16759672, 2924588, 10018698, 14034728, 16750742, 9725885, 12955861, 9197131, 12885140, 14907330, 16234194, 8355711, 13092807, 12369186, 14408589, 1556175, 10410725 ].map(d3_rgbString); - var d3_category20b = [ 3750777, 5395619, 7040719, 10264286, 6519097, 9216594, 11915115, 13556636, 9202993, 12426809, 15186514, 15190932, 8666169, 11356490, 14049643, 15177372, 8077683, 10834324, 13528509, 14589654 ].map(d3_rgbString); - var d3_category20c = [ 3244733, 7057110, 10406625, 13032431, 15095053, 16616764, 16625259, 16634018, 3253076, 7652470, 10607003, 13101504, 7695281, 10394312, 12369372, 14342891, 6513507, 9868950, 12434877, 14277081 ].map(d3_rgbString); - d3.scale.quantile = function() { - return d3_scale_quantile([], []); - }; - function d3_scale_quantile(domain, range) { - var thresholds; - function rescale() { - var k = 0, q = range.length; - thresholds = []; - while (++k < q) thresholds[k - 1] = d3.quantile(domain, k / q); - return scale; - } - function scale(x) { - if (!isNaN(x = +x)) return range[d3.bisect(thresholds, x)]; - } - scale.domain = function(x) { - if (!arguments.length) return domain; - domain = x.map(d3_number).filter(d3_numeric).sort(d3_ascending); - return rescale(); - }; - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - return rescale(); - }; - scale.quantiles = function() { - return thresholds; - }; - scale.invertExtent = function(y) { - y = range.indexOf(y); - return y < 0 ? [ NaN, NaN ] : [ y > 0 ? thresholds[y - 1] : domain[0], y < thresholds.length ? thresholds[y] : domain[domain.length - 1] ]; - }; - scale.copy = function() { - return d3_scale_quantile(domain, range); - }; - return rescale(); - } - d3.scale.quantize = function() { - return d3_scale_quantize(0, 1, [ 0, 1 ]); - }; - function d3_scale_quantize(x0, x1, range) { - var kx, i; - function scale(x) { - return range[Math.max(0, Math.min(i, Math.floor(kx * (x - x0))))]; - } - function rescale() { - kx = range.length / (x1 - x0); - i = range.length - 1; - return scale; - } - scale.domain = function(x) { - if (!arguments.length) return [ x0, x1 ]; - x0 = +x[0]; - x1 = +x[x.length - 1]; - return rescale(); - }; - scale.range = function(x) { - if (!arguments.length) return range; - range = x; - return rescale(); - }; - scale.invertExtent = function(y) { - y = range.indexOf(y); - y = y < 0 ? NaN : y / kx + x0; - return [ y, y + 1 / kx ]; - }; - scale.copy = function() { - return d3_scale_quantize(x0, x1, range); - }; - return rescale(); - } - d3.scale.threshold = function() { - return d3_scale_threshold([ .5 ], [ 0, 1 ]); - }; - function d3_scale_threshold(domain, range) { - function scale(x) { - if (x <= x) return range[d3.bisect(domain, x)]; - } - scale.domain = function(_) { - if (!arguments.length) return domain; - domain = _; - return scale; - }; - scale.range = function(_) { - if (!arguments.length) return range; - range = _; - return scale; - }; - scale.invertExtent = function(y) { - y = range.indexOf(y); - return [ domain[y - 1], domain[y] ]; - }; - scale.copy = function() { - return d3_scale_threshold(domain, range); - }; - return scale; - } - d3.scale.identity = function() { - return d3_scale_identity([ 0, 1 ]); - }; - function d3_scale_identity(domain) { - function identity(x) { - return +x; - } - identity.invert = identity; - identity.domain = identity.range = function(x) { - if (!arguments.length) return domain; - domain = x.map(identity); - return identity; - }; - identity.ticks = function(m) { - return d3_scale_linearTicks(domain, m); - }; - identity.tickFormat = function(m, format) { - return d3_scale_linearTickFormat(domain, m, format); - }; - identity.copy = function() { - return d3_scale_identity(domain); - }; - return identity; - } - d3.svg = {}; - function d3_zero() { - return 0; - } - d3.svg.arc = function() { - var innerRadius = d3_svg_arcInnerRadius, outerRadius = d3_svg_arcOuterRadius, cornerRadius = d3_zero, padRadius = d3_svg_arcAuto, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle, padAngle = d3_svg_arcPadAngle; - function arc() { - var r0 = Math.max(0, +innerRadius.apply(this, arguments)), r1 = Math.max(0, +outerRadius.apply(this, arguments)), a0 = startAngle.apply(this, arguments) - halfπ, a1 = endAngle.apply(this, arguments) - halfπ, da = Math.abs(a1 - a0), cw = a0 > a1 ? 0 : 1; - if (r1 < r0) rc = r1, r1 = r0, r0 = rc; - if (da >= τε) return circleSegment(r1, cw) + (r0 ? circleSegment(r0, 1 - cw) : "") + "Z"; - var rc, cr, rp, ap, p0 = 0, p1 = 0, x0, y0, x1, y1, x2, y2, x3, y3, path = []; - if (ap = (+padAngle.apply(this, arguments) || 0) / 2) { - rp = padRadius === d3_svg_arcAuto ? Math.sqrt(r0 * r0 + r1 * r1) : +padRadius.apply(this, arguments); - if (!cw) p1 *= -1; - if (r1) p1 = d3_asin(rp / r1 * Math.sin(ap)); - if (r0) p0 = d3_asin(rp / r0 * Math.sin(ap)); - } - if (r1) { - x0 = r1 * Math.cos(a0 + p1); - y0 = r1 * Math.sin(a0 + p1); - x1 = r1 * Math.cos(a1 - p1); - y1 = r1 * Math.sin(a1 - p1); - var l1 = Math.abs(a1 - a0 - 2 * p1) <= π ? 0 : 1; - if (p1 && d3_svg_arcSweep(x0, y0, x1, y1) === cw ^ l1) { - var h1 = (a0 + a1) / 2; - x0 = r1 * Math.cos(h1); - y0 = r1 * Math.sin(h1); - x1 = y1 = null; - } - } else { - x0 = y0 = 0; - } - if (r0) { - x2 = r0 * Math.cos(a1 - p0); - y2 = r0 * Math.sin(a1 - p0); - x3 = r0 * Math.cos(a0 + p0); - y3 = r0 * Math.sin(a0 + p0); - var l0 = Math.abs(a0 - a1 + 2 * p0) <= π ? 0 : 1; - if (p0 && d3_svg_arcSweep(x2, y2, x3, y3) === 1 - cw ^ l0) { - var h0 = (a0 + a1) / 2; - x2 = r0 * Math.cos(h0); - y2 = r0 * Math.sin(h0); - x3 = y3 = null; - } - } else { - x2 = y2 = 0; - } - if ((rc = Math.min(Math.abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments))) > .001) { - cr = r0 < r1 ^ cw ? 0 : 1; - var oc = x3 == null ? [ x2, y2 ] : x1 == null ? [ x0, y0 ] : d3_geom_polygonIntersect([ x0, y0 ], [ x3, y3 ], [ x1, y1 ], [ x2, y2 ]), ax = x0 - oc[0], ay = y0 - oc[1], bx = x1 - oc[0], by = y1 - oc[1], kc = 1 / Math.sin(Math.acos((ax * bx + ay * by) / (Math.sqrt(ax * ax + ay * ay) * Math.sqrt(bx * bx + by * by))) / 2), lc = Math.sqrt(oc[0] * oc[0] + oc[1] * oc[1]); - if (x1 != null) { - var rc1 = Math.min(rc, (r1 - lc) / (kc + 1)), t30 = d3_svg_arcCornerTangents(x3 == null ? [ x2, y2 ] : [ x3, y3 ], [ x0, y0 ], r1, rc1, cw), t12 = d3_svg_arcCornerTangents([ x1, y1 ], [ x2, y2 ], r1, rc1, cw); - if (rc === rc1) { - path.push("M", t30[0], "A", rc1, ",", rc1, " 0 0,", cr, " ", t30[1], "A", r1, ",", r1, " 0 ", 1 - cw ^ d3_svg_arcSweep(t30[1][0], t30[1][1], t12[1][0], t12[1][1]), ",", cw, " ", t12[1], "A", rc1, ",", rc1, " 0 0,", cr, " ", t12[0]); - } else { - path.push("M", t30[0], "A", rc1, ",", rc1, " 0 1,", cr, " ", t12[0]); - } - } else { - path.push("M", x0, ",", y0); - } - if (x3 != null) { - var rc0 = Math.min(rc, (r0 - lc) / (kc - 1)), t03 = d3_svg_arcCornerTangents([ x0, y0 ], [ x3, y3 ], r0, -rc0, cw), t21 = d3_svg_arcCornerTangents([ x2, y2 ], x1 == null ? [ x0, y0 ] : [ x1, y1 ], r0, -rc0, cw); - if (rc === rc0) { - path.push("L", t21[0], "A", rc0, ",", rc0, " 0 0,", cr, " ", t21[1], "A", r0, ",", r0, " 0 ", cw ^ d3_svg_arcSweep(t21[1][0], t21[1][1], t03[1][0], t03[1][1]), ",", 1 - cw, " ", t03[1], "A", rc0, ",", rc0, " 0 0,", cr, " ", t03[0]); - } else { - path.push("L", t21[0], "A", rc0, ",", rc0, " 0 0,", cr, " ", t03[0]); - } - } else { - path.push("L", x2, ",", y2); - } - } else { - path.push("M", x0, ",", y0); - if (x1 != null) path.push("A", r1, ",", r1, " 0 ", l1, ",", cw, " ", x1, ",", y1); - path.push("L", x2, ",", y2); - if (x3 != null) path.push("A", r0, ",", r0, " 0 ", l0, ",", 1 - cw, " ", x3, ",", y3); - } - path.push("Z"); - return path.join(""); - } - function circleSegment(r1, cw) { - return "M0," + r1 + "A" + r1 + "," + r1 + " 0 1," + cw + " 0," + -r1 + "A" + r1 + "," + r1 + " 0 1," + cw + " 0," + r1; - } - arc.innerRadius = function(v) { - if (!arguments.length) return innerRadius; - innerRadius = d3_functor(v); - return arc; - }; - arc.outerRadius = function(v) { - if (!arguments.length) return outerRadius; - outerRadius = d3_functor(v); - return arc; - }; - arc.cornerRadius = function(v) { - if (!arguments.length) return cornerRadius; - cornerRadius = d3_functor(v); - return arc; - }; - arc.padRadius = function(v) { - if (!arguments.length) return padRadius; - padRadius = v == d3_svg_arcAuto ? d3_svg_arcAuto : d3_functor(v); - return arc; - }; - arc.startAngle = function(v) { - if (!arguments.length) return startAngle; - startAngle = d3_functor(v); - return arc; - }; - arc.endAngle = function(v) { - if (!arguments.length) return endAngle; - endAngle = d3_functor(v); - return arc; - }; - arc.padAngle = function(v) { - if (!arguments.length) return padAngle; - padAngle = d3_functor(v); - return arc; - }; - arc.centroid = function() { - var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2, a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - halfπ; - return [ Math.cos(a) * r, Math.sin(a) * r ]; - }; - return arc; - }; - var d3_svg_arcAuto = "auto"; - function d3_svg_arcInnerRadius(d) { - return d.innerRadius; - } - function d3_svg_arcOuterRadius(d) { - return d.outerRadius; - } - function d3_svg_arcStartAngle(d) { - return d.startAngle; - } - function d3_svg_arcEndAngle(d) { - return d.endAngle; - } - function d3_svg_arcPadAngle(d) { - return d && d.padAngle; - } - function d3_svg_arcSweep(x0, y0, x1, y1) { - return (x0 - x1) * y0 - (y0 - y1) * x0 > 0 ? 0 : 1; - } - function d3_svg_arcCornerTangents(p0, p1, r1, rc, cw) { - var x01 = p0[0] - p1[0], y01 = p0[1] - p1[1], lo = (cw ? rc : -rc) / Math.sqrt(x01 * x01 + y01 * y01), ox = lo * y01, oy = -lo * x01, x1 = p0[0] + ox, y1 = p0[1] + oy, x2 = p1[0] + ox, y2 = p1[1] + oy, x3 = (x1 + x2) / 2, y3 = (y1 + y2) / 2, dx = x2 - x1, dy = y2 - y1, d2 = dx * dx + dy * dy, r = r1 - rc, D = x1 * y2 - x2 * y1, d = (dy < 0 ? -1 : 1) * Math.sqrt(r * r * d2 - D * D), cx0 = (D * dy - dx * d) / d2, cy0 = (-D * dx - dy * d) / d2, cx1 = (D * dy + dx * d) / d2, cy1 = (-D * dx + dy * d) / d2, dx0 = cx0 - x3, dy0 = cy0 - y3, dx1 = cx1 - x3, dy1 = cy1 - y3; - if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1; - return [ [ cx0 - ox, cy0 - oy ], [ cx0 * r1 / r, cy0 * r1 / r ] ]; - } - function d3_svg_line(projection) { - var x = d3_geom_pointX, y = d3_geom_pointY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, tension = .7; - function line(data) { - var segments = [], points = [], i = -1, n = data.length, d, fx = d3_functor(x), fy = d3_functor(y); - function segment() { - segments.push("M", interpolate(projection(points), tension)); - } - while (++i < n) { - if (defined.call(this, d = data[i], i)) { - points.push([ +fx.call(this, d, i), +fy.call(this, d, i) ]); - } else if (points.length) { - segment(); - points = []; - } - } - if (points.length) segment(); - return segments.length ? segments.join("") : null; - } - line.x = function(_) { - if (!arguments.length) return x; - x = _; - return line; - }; - line.y = function(_) { - if (!arguments.length) return y; - y = _; - return line; - }; - line.defined = function(_) { - if (!arguments.length) return defined; - defined = _; - return line; - }; - line.interpolate = function(_) { - if (!arguments.length) return interpolateKey; - if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key; - return line; - }; - line.tension = function(_) { - if (!arguments.length) return tension; - tension = _; - return line; - }; - return line; - } - d3.svg.line = function() { - return d3_svg_line(d3_identity); - }; - var d3_svg_lineInterpolators = d3.map({ - linear: d3_svg_lineLinear, - "linear-closed": d3_svg_lineLinearClosed, - step: d3_svg_lineStep, - "step-before": d3_svg_lineStepBefore, - "step-after": d3_svg_lineStepAfter, - basis: d3_svg_lineBasis, - "basis-open": d3_svg_lineBasisOpen, - "basis-closed": d3_svg_lineBasisClosed, - bundle: d3_svg_lineBundle, - cardinal: d3_svg_lineCardinal, - "cardinal-open": d3_svg_lineCardinalOpen, - "cardinal-closed": d3_svg_lineCardinalClosed, - monotone: d3_svg_lineMonotone - }); - d3_svg_lineInterpolators.forEach(function(key, value) { - value.key = key; - value.closed = /-closed$/.test(key); - }); - function d3_svg_lineLinear(points) { - return points.join("L"); - } - function d3_svg_lineLinearClosed(points) { - return d3_svg_lineLinear(points) + "Z"; - } - function d3_svg_lineStep(points) { - var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; - while (++i < n) path.push("H", (p[0] + (p = points[i])[0]) / 2, "V", p[1]); - if (n > 1) path.push("H", p[0]); - return path.join(""); - } - function d3_svg_lineStepBefore(points) { - var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; - while (++i < n) path.push("V", (p = points[i])[1], "H", p[0]); - return path.join(""); - } - function d3_svg_lineStepAfter(points) { - var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; - while (++i < n) path.push("H", (p = points[i])[0], "V", p[1]); - return path.join(""); - } - function d3_svg_lineCardinalOpen(points, tension) { - return points.length < 4 ? d3_svg_lineLinear(points) : points[1] + d3_svg_lineHermite(points.slice(1, -1), d3_svg_lineCardinalTangents(points, tension)); - } - function d3_svg_lineCardinalClosed(points, tension) { - return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite((points.push(points[0]), - points), d3_svg_lineCardinalTangents([ points[points.length - 2] ].concat(points, [ points[1] ]), tension)); - } - function d3_svg_lineCardinal(points, tension) { - return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineCardinalTangents(points, tension)); - } - function d3_svg_lineHermite(points, tangents) { - if (tangents.length < 1 || points.length != tangents.length && points.length != tangents.length + 2) { - return d3_svg_lineLinear(points); - } - var quad = points.length != tangents.length, path = "", p0 = points[0], p = points[1], t0 = tangents[0], t = t0, pi = 1; - if (quad) { - path += "Q" + (p[0] - t0[0] * 2 / 3) + "," + (p[1] - t0[1] * 2 / 3) + "," + p[0] + "," + p[1]; - p0 = points[1]; - pi = 2; - } - if (tangents.length > 1) { - t = tangents[1]; - p = points[pi]; - pi++; - path += "C" + (p0[0] + t0[0]) + "," + (p0[1] + t0[1]) + "," + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1]; - for (var i = 2; i < tangents.length; i++, pi++) { - p = points[pi]; - t = tangents[i]; - path += "S" + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1]; - } - } - if (quad) { - var lp = points[pi]; - path += "Q" + (p[0] + t[0] * 2 / 3) + "," + (p[1] + t[1] * 2 / 3) + "," + lp[0] + "," + lp[1]; - } - return path; - } - function d3_svg_lineCardinalTangents(points, tension) { - var tangents = [], a = (1 - tension) / 2, p0, p1 = points[0], p2 = points[1], i = 1, n = points.length; - while (++i < n) { - p0 = p1; - p1 = p2; - p2 = points[i]; - tangents.push([ a * (p2[0] - p0[0]), a * (p2[1] - p0[1]) ]); - } - return tangents; - } - function d3_svg_lineBasis(points) { - if (points.length < 3) return d3_svg_lineLinear(points); - var i = 1, n = points.length, pi = points[0], x0 = pi[0], y0 = pi[1], px = [ x0, x0, x0, (pi = points[1])[0] ], py = [ y0, y0, y0, pi[1] ], path = [ x0, ",", y0, "L", d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ]; - points.push(points[n - 1]); - while (++i <= n) { - pi = points[i]; - px.shift(); - px.push(pi[0]); - py.shift(); - py.push(pi[1]); - d3_svg_lineBasisBezier(path, px, py); - } - points.pop(); - path.push("L", pi); - return path.join(""); - } - function d3_svg_lineBasisOpen(points) { - if (points.length < 4) return d3_svg_lineLinear(points); - var path = [], i = -1, n = points.length, pi, px = [ 0 ], py = [ 0 ]; - while (++i < 3) { - pi = points[i]; - px.push(pi[0]); - py.push(pi[1]); - } - path.push(d3_svg_lineDot4(d3_svg_lineBasisBezier3, px) + "," + d3_svg_lineDot4(d3_svg_lineBasisBezier3, py)); - --i; - while (++i < n) { - pi = points[i]; - px.shift(); - px.push(pi[0]); - py.shift(); - py.push(pi[1]); - d3_svg_lineBasisBezier(path, px, py); - } - return path.join(""); - } - function d3_svg_lineBasisClosed(points) { - var path, i = -1, n = points.length, m = n + 4, pi, px = [], py = []; - while (++i < 4) { - pi = points[i % n]; - px.push(pi[0]); - py.push(pi[1]); - } - path = [ d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ]; - --i; - while (++i < m) { - pi = points[i % n]; - px.shift(); - px.push(pi[0]); - py.shift(); - py.push(pi[1]); - d3_svg_lineBasisBezier(path, px, py); - } - return path.join(""); - } - function d3_svg_lineBundle(points, tension) { - var n = points.length - 1; - if (n) { - var x0 = points[0][0], y0 = points[0][1], dx = points[n][0] - x0, dy = points[n][1] - y0, i = -1, p, t; - while (++i <= n) { - p = points[i]; - t = i / n; - p[0] = tension * p[0] + (1 - tension) * (x0 + t * dx); - p[1] = tension * p[1] + (1 - tension) * (y0 + t * dy); - } - } - return d3_svg_lineBasis(points); - } - function d3_svg_lineDot4(a, b) { - return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; - } - var d3_svg_lineBasisBezier1 = [ 0, 2 / 3, 1 / 3, 0 ], d3_svg_lineBasisBezier2 = [ 0, 1 / 3, 2 / 3, 0 ], d3_svg_lineBasisBezier3 = [ 0, 1 / 6, 2 / 3, 1 / 6 ]; - function d3_svg_lineBasisBezier(path, x, y) { - path.push("C", d3_svg_lineDot4(d3_svg_lineBasisBezier1, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier1, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, y)); - } - function d3_svg_lineSlope(p0, p1) { - return (p1[1] - p0[1]) / (p1[0] - p0[0]); - } - function d3_svg_lineFiniteDifferences(points) { - var i = 0, j = points.length - 1, m = [], p0 = points[0], p1 = points[1], d = m[0] = d3_svg_lineSlope(p0, p1); - while (++i < j) { - m[i] = (d + (d = d3_svg_lineSlope(p0 = p1, p1 = points[i + 1]))) / 2; - } - m[i] = d; - return m; - } - function d3_svg_lineMonotoneTangents(points) { - var tangents = [], d, a, b, s, m = d3_svg_lineFiniteDifferences(points), i = -1, j = points.length - 1; - while (++i < j) { - d = d3_svg_lineSlope(points[i], points[i + 1]); - if (abs(d) < ε) { - m[i] = m[i + 1] = 0; - } else { - a = m[i] / d; - b = m[i + 1] / d; - s = a * a + b * b; - if (s > 9) { - s = d * 3 / Math.sqrt(s); - m[i] = s * a; - m[i + 1] = s * b; - } - } - } - i = -1; - while (++i <= j) { - s = (points[Math.min(j, i + 1)][0] - points[Math.max(0, i - 1)][0]) / (6 * (1 + m[i] * m[i])); - tangents.push([ s || 0, m[i] * s || 0 ]); - } - return tangents; - } - function d3_svg_lineMonotone(points) { - return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineMonotoneTangents(points)); - } - d3.svg.line.radial = function() { - var line = d3_svg_line(d3_svg_lineRadial); - line.radius = line.x, delete line.x; - line.angle = line.y, delete line.y; - return line; - }; - function d3_svg_lineRadial(points) { - var point, i = -1, n = points.length, r, a; - while (++i < n) { - point = points[i]; - r = point[0]; - a = point[1] - halfπ; - point[0] = r * Math.cos(a); - point[1] = r * Math.sin(a); - } - return points; - } - function d3_svg_area(projection) { - var x0 = d3_geom_pointX, x1 = d3_geom_pointX, y0 = 0, y1 = d3_geom_pointY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, interpolateReverse = interpolate, L = "L", tension = .7; - function area(data) { - var segments = [], points0 = [], points1 = [], i = -1, n = data.length, d, fx0 = d3_functor(x0), fy0 = d3_functor(y0), fx1 = x0 === x1 ? function() { - return x; - } : d3_functor(x1), fy1 = y0 === y1 ? function() { - return y; - } : d3_functor(y1), x, y; - function segment() { - segments.push("M", interpolate(projection(points1), tension), L, interpolateReverse(projection(points0.reverse()), tension), "Z"); - } - while (++i < n) { - if (defined.call(this, d = data[i], i)) { - points0.push([ x = +fx0.call(this, d, i), y = +fy0.call(this, d, i) ]); - points1.push([ +fx1.call(this, d, i), +fy1.call(this, d, i) ]); - } else if (points0.length) { - segment(); - points0 = []; - points1 = []; - } - } - if (points0.length) segment(); - return segments.length ? segments.join("") : null; - } - area.x = function(_) { - if (!arguments.length) return x1; - x0 = x1 = _; - return area; - }; - area.x0 = function(_) { - if (!arguments.length) return x0; - x0 = _; - return area; - }; - area.x1 = function(_) { - if (!arguments.length) return x1; - x1 = _; - return area; - }; - area.y = function(_) { - if (!arguments.length) return y1; - y0 = y1 = _; - return area; - }; - area.y0 = function(_) { - if (!arguments.length) return y0; - y0 = _; - return area; - }; - area.y1 = function(_) { - if (!arguments.length) return y1; - y1 = _; - return area; - }; - area.defined = function(_) { - if (!arguments.length) return defined; - defined = _; - return area; - }; - area.interpolate = function(_) { - if (!arguments.length) return interpolateKey; - if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key; - interpolateReverse = interpolate.reverse || interpolate; - L = interpolate.closed ? "M" : "L"; - return area; - }; - area.tension = function(_) { - if (!arguments.length) return tension; - tension = _; - return area; - }; - return area; - } - d3_svg_lineStepBefore.reverse = d3_svg_lineStepAfter; - d3_svg_lineStepAfter.reverse = d3_svg_lineStepBefore; - d3.svg.area = function() { - return d3_svg_area(d3_identity); - }; - d3.svg.area.radial = function() { - var area = d3_svg_area(d3_svg_lineRadial); - area.radius = area.x, delete area.x; - area.innerRadius = area.x0, delete area.x0; - area.outerRadius = area.x1, delete area.x1; - area.angle = area.y, delete area.y; - area.startAngle = area.y0, delete area.y0; - area.endAngle = area.y1, delete area.y1; - return area; - }; - d3.svg.chord = function() { - var source = d3_source, target = d3_target, radius = d3_svg_chordRadius, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle; - function chord(d, i) { - var s = subgroup(this, source, d, i), t = subgroup(this, target, d, i); - return "M" + s.p0 + arc(s.r, s.p1, s.a1 - s.a0) + (equals(s, t) ? curve(s.r, s.p1, s.r, s.p0) : curve(s.r, s.p1, t.r, t.p0) + arc(t.r, t.p1, t.a1 - t.a0) + curve(t.r, t.p1, s.r, s.p0)) + "Z"; - } - function subgroup(self, f, d, i) { - var subgroup = f.call(self, d, i), r = radius.call(self, subgroup, i), a0 = startAngle.call(self, subgroup, i) - halfπ, a1 = endAngle.call(self, subgroup, i) - halfπ; - return { - r: r, - a0: a0, - a1: a1, - p0: [ r * Math.cos(a0), r * Math.sin(a0) ], - p1: [ r * Math.cos(a1), r * Math.sin(a1) ] - }; - } - function equals(a, b) { - return a.a0 == b.a0 && a.a1 == b.a1; - } - function arc(r, p, a) { - return "A" + r + "," + r + " 0 " + +(a > π) + ",1 " + p; - } - function curve(r0, p0, r1, p1) { - return "Q 0,0 " + p1; - } - chord.radius = function(v) { - if (!arguments.length) return radius; - radius = d3_functor(v); - return chord; - }; - chord.source = function(v) { - if (!arguments.length) return source; - source = d3_functor(v); - return chord; - }; - chord.target = function(v) { - if (!arguments.length) return target; - target = d3_functor(v); - return chord; - }; - chord.startAngle = function(v) { - if (!arguments.length) return startAngle; - startAngle = d3_functor(v); - return chord; - }; - chord.endAngle = function(v) { - if (!arguments.length) return endAngle; - endAngle = d3_functor(v); - return chord; - }; - return chord; - }; - function d3_svg_chordRadius(d) { - return d.radius; - } - d3.svg.diagonal = function() { - var source = d3_source, target = d3_target, projection = d3_svg_diagonalProjection; - function diagonal(d, i) { - var p0 = source.call(this, d, i), p3 = target.call(this, d, i), m = (p0.y + p3.y) / 2, p = [ p0, { - x: p0.x, - y: m - }, { - x: p3.x, - y: m - }, p3 ]; - p = p.map(projection); - return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3]; - } - diagonal.source = function(x) { - if (!arguments.length) return source; - source = d3_functor(x); - return diagonal; - }; - diagonal.target = function(x) { - if (!arguments.length) return target; - target = d3_functor(x); - return diagonal; - }; - diagonal.projection = function(x) { - if (!arguments.length) return projection; - projection = x; - return diagonal; - }; - return diagonal; - }; - function d3_svg_diagonalProjection(d) { - return [ d.x, d.y ]; - } - d3.svg.diagonal.radial = function() { - var diagonal = d3.svg.diagonal(), projection = d3_svg_diagonalProjection, projection_ = diagonal.projection; - diagonal.projection = function(x) { - return arguments.length ? projection_(d3_svg_diagonalRadialProjection(projection = x)) : projection; - }; - return diagonal; - }; - function d3_svg_diagonalRadialProjection(projection) { - return function() { - var d = projection.apply(this, arguments), r = d[0], a = d[1] - halfπ; - return [ r * Math.cos(a), r * Math.sin(a) ]; - }; - } - d3.svg.symbol = function() { - var type = d3_svg_symbolType, size = d3_svg_symbolSize; - function symbol(d, i) { - return (d3_svg_symbols.get(type.call(this, d, i)) || d3_svg_symbolCircle)(size.call(this, d, i)); - } - symbol.type = function(x) { - if (!arguments.length) return type; - type = d3_functor(x); - return symbol; - }; - symbol.size = function(x) { - if (!arguments.length) return size; - size = d3_functor(x); - return symbol; - }; - return symbol; - }; - function d3_svg_symbolSize() { - return 64; - } - function d3_svg_symbolType() { - return "circle"; - } - function d3_svg_symbolCircle(size) { - var r = Math.sqrt(size / π); - return "M0," + r + "A" + r + "," + r + " 0 1,1 0," + -r + "A" + r + "," + r + " 0 1,1 0," + r + "Z"; - } - var d3_svg_symbols = d3.map({ - circle: d3_svg_symbolCircle, - cross: function(size) { - var r = Math.sqrt(size / 5) / 2; - return "M" + -3 * r + "," + -r + "H" + -r + "V" + -3 * r + "H" + r + "V" + -r + "H" + 3 * r + "V" + r + "H" + r + "V" + 3 * r + "H" + -r + "V" + r + "H" + -3 * r + "Z"; - }, - diamond: function(size) { - var ry = Math.sqrt(size / (2 * d3_svg_symbolTan30)), rx = ry * d3_svg_symbolTan30; - return "M0," + -ry + "L" + rx + ",0" + " 0," + ry + " " + -rx + ",0" + "Z"; - }, - square: function(size) { - var r = Math.sqrt(size) / 2; - return "M" + -r + "," + -r + "L" + r + "," + -r + " " + r + "," + r + " " + -r + "," + r + "Z"; - }, - "triangle-down": function(size) { - var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2; - return "M0," + ry + "L" + rx + "," + -ry + " " + -rx + "," + -ry + "Z"; - }, - "triangle-up": function(size) { - var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2; - return "M0," + -ry + "L" + rx + "," + ry + " " + -rx + "," + ry + "Z"; - } - }); - d3.svg.symbolTypes = d3_svg_symbols.keys(); - var d3_svg_symbolSqrt3 = Math.sqrt(3), d3_svg_symbolTan30 = Math.tan(30 * d3_radians); - d3_selectionPrototype.transition = function(name) { - var id = d3_transitionInheritId || ++d3_transitionId, ns = d3_transitionNamespace(name), subgroups = [], subgroup, node, transition = d3_transitionInherit || { - time: Date.now(), - ease: d3_ease_cubicInOut, - delay: 0, - duration: 250 - }; - for (var j = -1, m = this.length; ++j < m; ) { - subgroups.push(subgroup = []); - for (var group = this[j], i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) d3_transitionNode(node, i, ns, id, transition); - subgroup.push(node); - } - } - return d3_transition(subgroups, ns, id); - }; - d3_selectionPrototype.interrupt = function(name) { - return this.each(name == null ? d3_selection_interrupt : d3_selection_interruptNS(d3_transitionNamespace(name))); - }; - var d3_selection_interrupt = d3_selection_interruptNS(d3_transitionNamespace()); - function d3_selection_interruptNS(ns) { - return function() { - var lock, active; - if ((lock = this[ns]) && (active = lock[lock.active])) { - if (--lock.count) delete lock[lock.active]; else delete this[ns]; - lock.active += .5; - active.event && active.event.interrupt.call(this, this.__data__, active.index); - } - }; - } - function d3_transition(groups, ns, id) { - d3_subclass(groups, d3_transitionPrototype); - groups.namespace = ns; - groups.id = id; - return groups; - } - var d3_transitionPrototype = [], d3_transitionId = 0, d3_transitionInheritId, d3_transitionInherit; - d3_transitionPrototype.call = d3_selectionPrototype.call; - d3_transitionPrototype.empty = d3_selectionPrototype.empty; - d3_transitionPrototype.node = d3_selectionPrototype.node; - d3_transitionPrototype.size = d3_selectionPrototype.size; - d3.transition = function(selection, name) { - return selection && selection.transition ? d3_transitionInheritId ? selection.transition(name) : selection : d3.selection().transition(selection); - }; - d3.transition.prototype = d3_transitionPrototype; - d3_transitionPrototype.select = function(selector) { - var id = this.id, ns = this.namespace, subgroups = [], subgroup, subnode, node; - selector = d3_selection_selector(selector); - for (var j = -1, m = this.length; ++j < m; ) { - subgroups.push(subgroup = []); - for (var group = this[j], i = -1, n = group.length; ++i < n; ) { - if ((node = group[i]) && (subnode = selector.call(node, node.__data__, i, j))) { - if ("__data__" in node) subnode.__data__ = node.__data__; - d3_transitionNode(subnode, i, ns, id, node[ns][id]); - subgroup.push(subnode); - } else { - subgroup.push(null); - } - } - } - return d3_transition(subgroups, ns, id); - }; - d3_transitionPrototype.selectAll = function(selector) { - var id = this.id, ns = this.namespace, subgroups = [], subgroup, subnodes, node, subnode, transition; - selector = d3_selection_selectorAll(selector); - for (var j = -1, m = this.length; ++j < m; ) { - for (var group = this[j], i = -1, n = group.length; ++i < n; ) { - if (node = group[i]) { - transition = node[ns][id]; - subnodes = selector.call(node, node.__data__, i, j); - subgroups.push(subgroup = []); - for (var k = -1, o = subnodes.length; ++k < o; ) { - if (subnode = subnodes[k]) d3_transitionNode(subnode, k, ns, id, transition); - subgroup.push(subnode); - } - } - } - } - return d3_transition(subgroups, ns, id); - }; - d3_transitionPrototype.filter = function(filter) { - var subgroups = [], subgroup, group, node; - if (typeof filter !== "function") filter = d3_selection_filter(filter); - for (var j = 0, m = this.length; j < m; j++) { - subgroups.push(subgroup = []); - for (var group = this[j], i = 0, n = group.length; i < n; i++) { - if ((node = group[i]) && filter.call(node, node.__data__, i, j)) { - subgroup.push(node); - } - } - } - return d3_transition(subgroups, this.namespace, this.id); - }; - d3_transitionPrototype.tween = function(name, tween) { - var id = this.id, ns = this.namespace; - if (arguments.length < 2) return this.node()[ns][id].tween.get(name); - return d3_selection_each(this, tween == null ? function(node) { - node[ns][id].tween.remove(name); - } : function(node) { - node[ns][id].tween.set(name, tween); - }); - }; - function d3_transition_tween(groups, name, value, tween) { - var id = groups.id, ns = groups.namespace; - return d3_selection_each(groups, typeof value === "function" ? function(node, i, j) { - node[ns][id].tween.set(name, tween(value.call(node, node.__data__, i, j))); - } : (value = tween(value), function(node) { - node[ns][id].tween.set(name, value); - })); - } - d3_transitionPrototype.attr = function(nameNS, value) { - if (arguments.length < 2) { - for (value in nameNS) this.attr(value, nameNS[value]); - return this; - } - var interpolate = nameNS == "transform" ? d3_interpolateTransform : d3_interpolate, name = d3.ns.qualify(nameNS); - function attrNull() { - this.removeAttribute(name); - } - function attrNullNS() { - this.removeAttributeNS(name.space, name.local); - } - function attrTween(b) { - return b == null ? attrNull : (b += "", function() { - var a = this.getAttribute(name), i; - return a !== b && (i = interpolate(a, b), function(t) { - this.setAttribute(name, i(t)); - }); - }); - } - function attrTweenNS(b) { - return b == null ? attrNullNS : (b += "", function() { - var a = this.getAttributeNS(name.space, name.local), i; - return a !== b && (i = interpolate(a, b), function(t) { - this.setAttributeNS(name.space, name.local, i(t)); - }); - }); - } - return d3_transition_tween(this, "attr." + nameNS, value, name.local ? attrTweenNS : attrTween); - }; - d3_transitionPrototype.attrTween = function(nameNS, tween) { - var name = d3.ns.qualify(nameNS); - function attrTween(d, i) { - var f = tween.call(this, d, i, this.getAttribute(name)); - return f && function(t) { - this.setAttribute(name, f(t)); - }; - } - function attrTweenNS(d, i) { - var f = tween.call(this, d, i, this.getAttributeNS(name.space, name.local)); - return f && function(t) { - this.setAttributeNS(name.space, name.local, f(t)); - }; - } - return this.tween("attr." + nameNS, name.local ? attrTweenNS : attrTween); - }; - d3_transitionPrototype.style = function(name, value, priority) { - var n = arguments.length; - if (n < 3) { - if (typeof name !== "string") { - if (n < 2) value = ""; - for (priority in name) this.style(priority, name[priority], value); - return this; - } - priority = ""; - } - function styleNull() { - this.style.removeProperty(name); - } - function styleString(b) { - return b == null ? styleNull : (b += "", function() { - var a = d3_window(this).getComputedStyle(this, null).getPropertyValue(name), i; - return a !== b && (i = d3_interpolate(a, b), function(t) { - this.style.setProperty(name, i(t), priority); - }); - }); - } - return d3_transition_tween(this, "style." + name, value, styleString); - }; - d3_transitionPrototype.styleTween = function(name, tween, priority) { - if (arguments.length < 3) priority = ""; - function styleTween(d, i) { - var f = tween.call(this, d, i, d3_window(this).getComputedStyle(this, null).getPropertyValue(name)); - return f && function(t) { - this.style.setProperty(name, f(t), priority); - }; - } - return this.tween("style." + name, styleTween); - }; - d3_transitionPrototype.text = function(value) { - return d3_transition_tween(this, "text", value, d3_transition_text); - }; - function d3_transition_text(b) { - if (b == null) b = ""; - return function() { - this.textContent = b; - }; - } - d3_transitionPrototype.remove = function() { - var ns = this.namespace; - return this.each("end.transition", function() { - var p; - if (this[ns].count < 2 && (p = this.parentNode)) p.removeChild(this); - }); - }; - d3_transitionPrototype.ease = function(value) { - var id = this.id, ns = this.namespace; - if (arguments.length < 1) return this.node()[ns][id].ease; - if (typeof value !== "function") value = d3.ease.apply(d3, arguments); - return d3_selection_each(this, function(node) { - node[ns][id].ease = value; - }); - }; - d3_transitionPrototype.delay = function(value) { - var id = this.id, ns = this.namespace; - if (arguments.length < 1) return this.node()[ns][id].delay; - return d3_selection_each(this, typeof value === "function" ? function(node, i, j) { - node[ns][id].delay = +value.call(node, node.__data__, i, j); - } : (value = +value, function(node) { - node[ns][id].delay = value; - })); - }; - d3_transitionPrototype.duration = function(value) { - var id = this.id, ns = this.namespace; - if (arguments.length < 1) return this.node()[ns][id].duration; - return d3_selection_each(this, typeof value === "function" ? function(node, i, j) { - node[ns][id].duration = Math.max(1, value.call(node, node.__data__, i, j)); - } : (value = Math.max(1, value), function(node) { - node[ns][id].duration = value; - })); - }; - d3_transitionPrototype.each = function(type, listener) { - var id = this.id, ns = this.namespace; - if (arguments.length < 2) { - var inherit = d3_transitionInherit, inheritId = d3_transitionInheritId; - try { - d3_transitionInheritId = id; - d3_selection_each(this, function(node, i, j) { - d3_transitionInherit = node[ns][id]; - type.call(node, node.__data__, i, j); - }); - } finally { - d3_transitionInherit = inherit; - d3_transitionInheritId = inheritId; - } - } else { - d3_selection_each(this, function(node) { - var transition = node[ns][id]; - (transition.event || (transition.event = d3.dispatch("start", "end", "interrupt"))).on(type, listener); - }); - } - return this; - }; - d3_transitionPrototype.transition = function() { - var id0 = this.id, id1 = ++d3_transitionId, ns = this.namespace, subgroups = [], subgroup, group, node, transition; - for (var j = 0, m = this.length; j < m; j++) { - subgroups.push(subgroup = []); - for (var group = this[j], i = 0, n = group.length; i < n; i++) { - if (node = group[i]) { - transition = node[ns][id0]; - d3_transitionNode(node, i, ns, id1, { - time: transition.time, - ease: transition.ease, - delay: transition.delay + transition.duration, - duration: transition.duration - }); - } - subgroup.push(node); - } - } - return d3_transition(subgroups, ns, id1); - }; - function d3_transitionNamespace(name) { - return name == null ? "__transition__" : "__transition_" + name + "__"; - } - function d3_transitionNode(node, i, ns, id, inherit) { - var lock = node[ns] || (node[ns] = { - active: 0, - count: 0 - }), transition = lock[id]; - if (!transition) { - var time = inherit.time; - transition = lock[id] = { - tween: new d3_Map(), - time: time, - delay: inherit.delay, - duration: inherit.duration, - ease: inherit.ease, - index: i - }; - inherit = null; - ++lock.count; - d3.timer(function(elapsed) { - var delay = transition.delay, duration, ease, timer = d3_timer_active, tweened = []; - timer.t = delay + time; - if (delay <= elapsed) return start(elapsed - delay); - timer.c = start; - function start(elapsed) { - if (lock.active > id) return stop(); - var active = lock[lock.active]; - if (active) { - --lock.count; - delete lock[lock.active]; - active.event && active.event.interrupt.call(node, node.__data__, active.index); - } - lock.active = id; - transition.event && transition.event.start.call(node, node.__data__, i); - transition.tween.forEach(function(key, value) { - if (value = value.call(node, node.__data__, i)) { - tweened.push(value); - } - }); - ease = transition.ease; - duration = transition.duration; - d3.timer(function() { - timer.c = tick(elapsed || 1) ? d3_true : tick; - return 1; - }, 0, time); - } - function tick(elapsed) { - if (lock.active !== id) return 1; - var t = elapsed / duration, e = ease(t), n = tweened.length; - while (n > 0) { - tweened[--n].call(node, e); - } - if (t >= 1) { - transition.event && transition.event.end.call(node, node.__data__, i); - return stop(); - } - } - function stop() { - if (--lock.count) delete lock[id]; else delete node[ns]; - return 1; - } - }, 0, time); - } - } - d3.svg.axis = function() { - var scale = d3.scale.linear(), orient = d3_svg_axisDefaultOrient, innerTickSize = 6, outerTickSize = 6, tickPadding = 3, tickArguments_ = [ 10 ], tickValues = null, tickFormat_; - function axis(g) { - g.each(function() { - var g = d3.select(this); - var scale0 = this.__chart__ || scale, scale1 = this.__chart__ = scale.copy(); - var ticks = tickValues == null ? scale1.ticks ? scale1.ticks.apply(scale1, tickArguments_) : scale1.domain() : tickValues, tickFormat = tickFormat_ == null ? scale1.tickFormat ? scale1.tickFormat.apply(scale1, tickArguments_) : d3_identity : tickFormat_, tick = g.selectAll(".tick").data(ticks, scale1), tickEnter = tick.enter().insert("g", ".domain").attr("class", "tick").style("opacity", ε), tickExit = d3.transition(tick.exit()).style("opacity", ε).remove(), tickUpdate = d3.transition(tick.order()).style("opacity", 1), tickSpacing = Math.max(innerTickSize, 0) + tickPadding, tickTransform; - var range = d3_scaleRange(scale1), path = g.selectAll(".domain").data([ 0 ]), pathUpdate = (path.enter().append("path").attr("class", "domain"), - d3.transition(path)); - tickEnter.append("line"); - tickEnter.append("text"); - var lineEnter = tickEnter.select("line"), lineUpdate = tickUpdate.select("line"), text = tick.select("text").text(tickFormat), textEnter = tickEnter.select("text"), textUpdate = tickUpdate.select("text"), sign = orient === "top" || orient === "left" ? -1 : 1, x1, x2, y1, y2; - if (orient === "bottom" || orient === "top") { - tickTransform = d3_svg_axisX, x1 = "x", y1 = "y", x2 = "x2", y2 = "y2"; - text.attr("dy", sign < 0 ? "0em" : ".71em").style("text-anchor", "middle"); - pathUpdate.attr("d", "M" + range[0] + "," + sign * outerTickSize + "V0H" + range[1] + "V" + sign * outerTickSize); - } else { - tickTransform = d3_svg_axisY, x1 = "y", y1 = "x", x2 = "y2", y2 = "x2"; - text.attr("dy", ".32em").style("text-anchor", sign < 0 ? "end" : "start"); - pathUpdate.attr("d", "M" + sign * outerTickSize + "," + range[0] + "H0V" + range[1] + "H" + sign * outerTickSize); - } - lineEnter.attr(y2, sign * innerTickSize); - textEnter.attr(y1, sign * tickSpacing); - lineUpdate.attr(x2, 0).attr(y2, sign * innerTickSize); - textUpdate.attr(x1, 0).attr(y1, sign * tickSpacing); - if (scale1.rangeBand) { - var x = scale1, dx = x.rangeBand() / 2; - scale0 = scale1 = function(d) { - return x(d) + dx; - }; - } else if (scale0.rangeBand) { - scale0 = scale1; - } else { - tickExit.call(tickTransform, scale1, scale0); - } - tickEnter.call(tickTransform, scale0, scale1); - tickUpdate.call(tickTransform, scale1, scale1); - }); - } - axis.scale = function(x) { - if (!arguments.length) return scale; - scale = x; - return axis; - }; - axis.orient = function(x) { - if (!arguments.length) return orient; - orient = x in d3_svg_axisOrients ? x + "" : d3_svg_axisDefaultOrient; - return axis; - }; - axis.ticks = function() { - if (!arguments.length) return tickArguments_; - tickArguments_ = arguments; - return axis; - }; - axis.tickValues = function(x) { - if (!arguments.length) return tickValues; - tickValues = x; - return axis; - }; - axis.tickFormat = function(x) { - if (!arguments.length) return tickFormat_; - tickFormat_ = x; - return axis; - }; - axis.tickSize = function(x) { - var n = arguments.length; - if (!n) return innerTickSize; - innerTickSize = +x; - outerTickSize = +arguments[n - 1]; - return axis; - }; - axis.innerTickSize = function(x) { - if (!arguments.length) return innerTickSize; - innerTickSize = +x; - return axis; - }; - axis.outerTickSize = function(x) { - if (!arguments.length) return outerTickSize; - outerTickSize = +x; - return axis; - }; - axis.tickPadding = function(x) { - if (!arguments.length) return tickPadding; - tickPadding = +x; - return axis; - }; - axis.tickSubdivide = function() { - return arguments.length && axis; - }; - return axis; - }; - var d3_svg_axisDefaultOrient = "bottom", d3_svg_axisOrients = { - top: 1, - right: 1, - bottom: 1, - left: 1 - }; - function d3_svg_axisX(selection, x0, x1) { - selection.attr("transform", function(d) { - var v0 = x0(d); - return "translate(" + (isFinite(v0) ? v0 : x1(d)) + ",0)"; - }); - } - function d3_svg_axisY(selection, y0, y1) { - selection.attr("transform", function(d) { - var v0 = y0(d); - return "translate(0," + (isFinite(v0) ? v0 : y1(d)) + ")"; - }); - } - d3.svg.brush = function() { - var event = d3_eventDispatch(brush, "brushstart", "brush", "brushend"), x = null, y = null, xExtent = [ 0, 0 ], yExtent = [ 0, 0 ], xExtentDomain, yExtentDomain, xClamp = true, yClamp = true, resizes = d3_svg_brushResizes[0]; - function brush(g) { - g.each(function() { - var g = d3.select(this).style("pointer-events", "all").style("-webkit-tap-highlight-color", "rgba(0,0,0,0)").on("mousedown.brush", brushstart).on("touchstart.brush", brushstart); - var background = g.selectAll(".background").data([ 0 ]); - background.enter().append("rect").attr("class", "background").style("visibility", "hidden").style("cursor", "crosshair"); - g.selectAll(".extent").data([ 0 ]).enter().append("rect").attr("class", "extent").style("cursor", "move"); - var resize = g.selectAll(".resize").data(resizes, d3_identity); - resize.exit().remove(); - resize.enter().append("g").attr("class", function(d) { - return "resize " + d; - }).style("cursor", function(d) { - return d3_svg_brushCursor[d]; - }).append("rect").attr("x", function(d) { - return /[ew]$/.test(d) ? -3 : null; - }).attr("y", function(d) { - return /^[ns]/.test(d) ? -3 : null; - }).attr("width", 6).attr("height", 6).style("visibility", "hidden"); - resize.style("display", brush.empty() ? "none" : null); - var gUpdate = d3.transition(g), backgroundUpdate = d3.transition(background), range; - if (x) { - range = d3_scaleRange(x); - backgroundUpdate.attr("x", range[0]).attr("width", range[1] - range[0]); - redrawX(gUpdate); - } - if (y) { - range = d3_scaleRange(y); - backgroundUpdate.attr("y", range[0]).attr("height", range[1] - range[0]); - redrawY(gUpdate); - } - redraw(gUpdate); - }); - } - brush.event = function(g) { - g.each(function() { - var event_ = event.of(this, arguments), extent1 = { - x: xExtent, - y: yExtent, - i: xExtentDomain, - j: yExtentDomain - }, extent0 = this.__chart__ || extent1; - this.__chart__ = extent1; - if (d3_transitionInheritId) { - d3.select(this).transition().each("start.brush", function() { - xExtentDomain = extent0.i; - yExtentDomain = extent0.j; - xExtent = extent0.x; - yExtent = extent0.y; - event_({ - type: "brushstart" - }); - }).tween("brush:brush", function() { - var xi = d3_interpolateArray(xExtent, extent1.x), yi = d3_interpolateArray(yExtent, extent1.y); - xExtentDomain = yExtentDomain = null; - return function(t) { - xExtent = extent1.x = xi(t); - yExtent = extent1.y = yi(t); - event_({ - type: "brush", - mode: "resize" - }); - }; - }).each("end.brush", function() { - xExtentDomain = extent1.i; - yExtentDomain = extent1.j; - event_({ - type: "brush", - mode: "resize" - }); - event_({ - type: "brushend" - }); - }); - } else { - event_({ - type: "brushstart" - }); - event_({ - type: "brush", - mode: "resize" - }); - event_({ - type: "brushend" - }); - } - }); - }; - function redraw(g) { - g.selectAll(".resize").attr("transform", function(d) { - return "translate(" + xExtent[+/e$/.test(d)] + "," + yExtent[+/^s/.test(d)] + ")"; - }); - } - function redrawX(g) { - g.select(".extent").attr("x", xExtent[0]); - g.selectAll(".extent,.n>rect,.s>rect").attr("width", xExtent[1] - xExtent[0]); - } - function redrawY(g) { - g.select(".extent").attr("y", yExtent[0]); - g.selectAll(".extent,.e>rect,.w>rect").attr("height", yExtent[1] - yExtent[0]); - } - function brushstart() { - var target = this, eventTarget = d3.select(d3.event.target), event_ = event.of(target, arguments), g = d3.select(target), resizing = eventTarget.datum(), resizingX = !/^(n|s)$/.test(resizing) && x, resizingY = !/^(e|w)$/.test(resizing) && y, dragging = eventTarget.classed("extent"), dragRestore = d3_event_dragSuppress(target), center, origin = d3.mouse(target), offset; - var w = d3.select(d3_window(target)).on("keydown.brush", keydown).on("keyup.brush", keyup); - if (d3.event.changedTouches) { - w.on("touchmove.brush", brushmove).on("touchend.brush", brushend); - } else { - w.on("mousemove.brush", brushmove).on("mouseup.brush", brushend); - } - g.interrupt().selectAll("*").interrupt(); - if (dragging) { - origin[0] = xExtent[0] - origin[0]; - origin[1] = yExtent[0] - origin[1]; - } else if (resizing) { - var ex = +/w$/.test(resizing), ey = +/^n/.test(resizing); - offset = [ xExtent[1 - ex] - origin[0], yExtent[1 - ey] - origin[1] ]; - origin[0] = xExtent[ex]; - origin[1] = yExtent[ey]; - } else if (d3.event.altKey) center = origin.slice(); - g.style("pointer-events", "none").selectAll(".resize").style("display", null); - d3.select("body").style("cursor", eventTarget.style("cursor")); - event_({ - type: "brushstart" - }); - brushmove(); - function keydown() { - if (d3.event.keyCode == 32) { - if (!dragging) { - center = null; - origin[0] -= xExtent[1]; - origin[1] -= yExtent[1]; - dragging = 2; - } - d3_eventPreventDefault(); - } - } - function keyup() { - if (d3.event.keyCode == 32 && dragging == 2) { - origin[0] += xExtent[1]; - origin[1] += yExtent[1]; - dragging = 0; - d3_eventPreventDefault(); - } - } - function brushmove() { - var point = d3.mouse(target), moved = false; - if (offset) { - point[0] += offset[0]; - point[1] += offset[1]; - } - if (!dragging) { - if (d3.event.altKey) { - if (!center) center = [ (xExtent[0] + xExtent[1]) / 2, (yExtent[0] + yExtent[1]) / 2 ]; - origin[0] = xExtent[+(point[0] < center[0])]; - origin[1] = yExtent[+(point[1] < center[1])]; - } else center = null; - } - if (resizingX && move1(point, x, 0)) { - redrawX(g); - moved = true; - } - if (resizingY && move1(point, y, 1)) { - redrawY(g); - moved = true; - } - if (moved) { - redraw(g); - event_({ - type: "brush", - mode: dragging ? "move" : "resize" - }); - } - } - function move1(point, scale, i) { - var range = d3_scaleRange(scale), r0 = range[0], r1 = range[1], position = origin[i], extent = i ? yExtent : xExtent, size = extent[1] - extent[0], min, max; - if (dragging) { - r0 -= position; - r1 -= size + position; - } - min = (i ? yClamp : xClamp) ? Math.max(r0, Math.min(r1, point[i])) : point[i]; - if (dragging) { - max = (min += position) + size; - } else { - if (center) position = Math.max(r0, Math.min(r1, 2 * center[i] - min)); - if (position < min) { - max = min; - min = position; - } else { - max = position; - } - } - if (extent[0] != min || extent[1] != max) { - if (i) yExtentDomain = null; else xExtentDomain = null; - extent[0] = min; - extent[1] = max; - return true; - } - } - function brushend() { - brushmove(); - g.style("pointer-events", "all").selectAll(".resize").style("display", brush.empty() ? "none" : null); - d3.select("body").style("cursor", null); - w.on("mousemove.brush", null).on("mouseup.brush", null).on("touchmove.brush", null).on("touchend.brush", null).on("keydown.brush", null).on("keyup.brush", null); - dragRestore(); - event_({ - type: "brushend" - }); - } - } - brush.x = function(z) { - if (!arguments.length) return x; - x = z; - resizes = d3_svg_brushResizes[!x << 1 | !y]; - return brush; - }; - brush.y = function(z) { - if (!arguments.length) return y; - y = z; - resizes = d3_svg_brushResizes[!x << 1 | !y]; - return brush; - }; - brush.clamp = function(z) { - if (!arguments.length) return x && y ? [ xClamp, yClamp ] : x ? xClamp : y ? yClamp : null; - if (x && y) xClamp = !!z[0], yClamp = !!z[1]; else if (x) xClamp = !!z; else if (y) yClamp = !!z; - return brush; - }; - brush.extent = function(z) { - var x0, x1, y0, y1, t; - if (!arguments.length) { - if (x) { - if (xExtentDomain) { - x0 = xExtentDomain[0], x1 = xExtentDomain[1]; - } else { - x0 = xExtent[0], x1 = xExtent[1]; - if (x.invert) x0 = x.invert(x0), x1 = x.invert(x1); - if (x1 < x0) t = x0, x0 = x1, x1 = t; - } - } - if (y) { - if (yExtentDomain) { - y0 = yExtentDomain[0], y1 = yExtentDomain[1]; - } else { - y0 = yExtent[0], y1 = yExtent[1]; - if (y.invert) y0 = y.invert(y0), y1 = y.invert(y1); - if (y1 < y0) t = y0, y0 = y1, y1 = t; - } - } - return x && y ? [ [ x0, y0 ], [ x1, y1 ] ] : x ? [ x0, x1 ] : y && [ y0, y1 ]; - } - if (x) { - x0 = z[0], x1 = z[1]; - if (y) x0 = x0[0], x1 = x1[0]; - xExtentDomain = [ x0, x1 ]; - if (x.invert) x0 = x(x0), x1 = x(x1); - if (x1 < x0) t = x0, x0 = x1, x1 = t; - if (x0 != xExtent[0] || x1 != xExtent[1]) xExtent = [ x0, x1 ]; - } - if (y) { - y0 = z[0], y1 = z[1]; - if (x) y0 = y0[1], y1 = y1[1]; - yExtentDomain = [ y0, y1 ]; - if (y.invert) y0 = y(y0), y1 = y(y1); - if (y1 < y0) t = y0, y0 = y1, y1 = t; - if (y0 != yExtent[0] || y1 != yExtent[1]) yExtent = [ y0, y1 ]; - } - return brush; - }; - brush.clear = function() { - if (!brush.empty()) { - xExtent = [ 0, 0 ], yExtent = [ 0, 0 ]; - xExtentDomain = yExtentDomain = null; - } - return brush; - }; - brush.empty = function() { - return !!x && xExtent[0] == xExtent[1] || !!y && yExtent[0] == yExtent[1]; - }; - return d3.rebind(brush, event, "on"); - }; - var d3_svg_brushCursor = { - n: "ns-resize", - e: "ew-resize", - s: "ns-resize", - w: "ew-resize", - nw: "nwse-resize", - ne: "nesw-resize", - se: "nwse-resize", - sw: "nesw-resize" - }; - var d3_svg_brushResizes = [ [ "n", "e", "s", "w", "nw", "ne", "se", "sw" ], [ "e", "w" ], [ "n", "s" ], [] ]; - var d3_time_format = d3_time.format = d3_locale_enUS.timeFormat; - var d3_time_formatUtc = d3_time_format.utc; - var d3_time_formatIso = d3_time_formatUtc("%Y-%m-%dT%H:%M:%S.%LZ"); - d3_time_format.iso = Date.prototype.toISOString && +new Date("2000-01-01T00:00:00.000Z") ? d3_time_formatIsoNative : d3_time_formatIso; - function d3_time_formatIsoNative(date) { - return date.toISOString(); - } - d3_time_formatIsoNative.parse = function(string) { - var date = new Date(string); - return isNaN(date) ? null : date; - }; - d3_time_formatIsoNative.toString = d3_time_formatIso.toString; - d3_time.second = d3_time_interval(function(date) { - return new d3_date(Math.floor(date / 1e3) * 1e3); - }, function(date, offset) { - date.setTime(date.getTime() + Math.floor(offset) * 1e3); - }, function(date) { - return date.getSeconds(); - }); - d3_time.seconds = d3_time.second.range; - d3_time.seconds.utc = d3_time.second.utc.range; - d3_time.minute = d3_time_interval(function(date) { - return new d3_date(Math.floor(date / 6e4) * 6e4); - }, function(date, offset) { - date.setTime(date.getTime() + Math.floor(offset) * 6e4); - }, function(date) { - return date.getMinutes(); - }); - d3_time.minutes = d3_time.minute.range; - d3_time.minutes.utc = d3_time.minute.utc.range; - d3_time.hour = d3_time_interval(function(date) { - var timezone = date.getTimezoneOffset() / 60; - return new d3_date((Math.floor(date / 36e5 - timezone) + timezone) * 36e5); - }, function(date, offset) { - date.setTime(date.getTime() + Math.floor(offset) * 36e5); - }, function(date) { - return date.getHours(); - }); - d3_time.hours = d3_time.hour.range; - d3_time.hours.utc = d3_time.hour.utc.range; - d3_time.month = d3_time_interval(function(date) { - date = d3_time.day(date); - date.setDate(1); - return date; - }, function(date, offset) { - date.setMonth(date.getMonth() + offset); - }, function(date) { - return date.getMonth(); - }); - d3_time.months = d3_time.month.range; - d3_time.months.utc = d3_time.month.utc.range; - function d3_time_scale(linear, methods, format) { - function scale(x) { - return linear(x); - } - scale.invert = function(x) { - return d3_time_scaleDate(linear.invert(x)); - }; - scale.domain = function(x) { - if (!arguments.length) return linear.domain().map(d3_time_scaleDate); - linear.domain(x); - return scale; - }; - function tickMethod(extent, count) { - var span = extent[1] - extent[0], target = span / count, i = d3.bisect(d3_time_scaleSteps, target); - return i == d3_time_scaleSteps.length ? [ methods.year, d3_scale_linearTickRange(extent.map(function(d) { - return d / 31536e6; - }), count)[2] ] : !i ? [ d3_time_scaleMilliseconds, d3_scale_linearTickRange(extent, count)[2] ] : methods[target / d3_time_scaleSteps[i - 1] < d3_time_scaleSteps[i] / target ? i - 1 : i]; - } - scale.nice = function(interval, skip) { - var domain = scale.domain(), extent = d3_scaleExtent(domain), method = interval == null ? tickMethod(extent, 10) : typeof interval === "number" && tickMethod(extent, interval); - if (method) interval = method[0], skip = method[1]; - function skipped(date) { - return !isNaN(date) && !interval.range(date, d3_time_scaleDate(+date + 1), skip).length; - } - return scale.domain(d3_scale_nice(domain, skip > 1 ? { - floor: function(date) { - while (skipped(date = interval.floor(date))) date = d3_time_scaleDate(date - 1); - return date; - }, - ceil: function(date) { - while (skipped(date = interval.ceil(date))) date = d3_time_scaleDate(+date + 1); - return date; - } - } : interval)); - }; - scale.ticks = function(interval, skip) { - var extent = d3_scaleExtent(scale.domain()), method = interval == null ? tickMethod(extent, 10) : typeof interval === "number" ? tickMethod(extent, interval) : !interval.range && [ { - range: interval - }, skip ]; - if (method) interval = method[0], skip = method[1]; - return interval.range(extent[0], d3_time_scaleDate(+extent[1] + 1), skip < 1 ? 1 : skip); - }; - scale.tickFormat = function() { - return format; - }; - scale.copy = function() { - return d3_time_scale(linear.copy(), methods, format); - }; - return d3_scale_linearRebind(scale, linear); - } - function d3_time_scaleDate(t) { - return new Date(t); - } - var d3_time_scaleSteps = [ 1e3, 5e3, 15e3, 3e4, 6e4, 3e5, 9e5, 18e5, 36e5, 108e5, 216e5, 432e5, 864e5, 1728e5, 6048e5, 2592e6, 7776e6, 31536e6 ]; - var d3_time_scaleLocalMethods = [ [ d3_time.second, 1 ], [ d3_time.second, 5 ], [ d3_time.second, 15 ], [ d3_time.second, 30 ], [ d3_time.minute, 1 ], [ d3_time.minute, 5 ], [ d3_time.minute, 15 ], [ d3_time.minute, 30 ], [ d3_time.hour, 1 ], [ d3_time.hour, 3 ], [ d3_time.hour, 6 ], [ d3_time.hour, 12 ], [ d3_time.day, 1 ], [ d3_time.day, 2 ], [ d3_time.week, 1 ], [ d3_time.month, 1 ], [ d3_time.month, 3 ], [ d3_time.year, 1 ] ]; - var d3_time_scaleLocalFormat = d3_time_format.multi([ [ ".%L", function(d) { - return d.getMilliseconds(); - } ], [ ":%S", function(d) { - return d.getSeconds(); - } ], [ "%I:%M", function(d) { - return d.getMinutes(); - } ], [ "%I %p", function(d) { - return d.getHours(); - } ], [ "%a %d", function(d) { - return d.getDay() && d.getDate() != 1; - } ], [ "%b %d", function(d) { - return d.getDate() != 1; - } ], [ "%B", function(d) { - return d.getMonth(); - } ], [ "%Y", d3_true ] ]); - var d3_time_scaleMilliseconds = { - range: function(start, stop, step) { - return d3.range(Math.ceil(start / step) * step, +stop, step).map(d3_time_scaleDate); - }, - floor: d3_identity, - ceil: d3_identity - }; - d3_time_scaleLocalMethods.year = d3_time.year; - d3_time.scale = function() { - return d3_time_scale(d3.scale.linear(), d3_time_scaleLocalMethods, d3_time_scaleLocalFormat); - }; - var d3_time_scaleUtcMethods = d3_time_scaleLocalMethods.map(function(m) { - return [ m[0].utc, m[1] ]; - }); - var d3_time_scaleUtcFormat = d3_time_formatUtc.multi([ [ ".%L", function(d) { - return d.getUTCMilliseconds(); - } ], [ ":%S", function(d) { - return d.getUTCSeconds(); - } ], [ "%I:%M", function(d) { - return d.getUTCMinutes(); - } ], [ "%I %p", function(d) { - return d.getUTCHours(); - } ], [ "%a %d", function(d) { - return d.getUTCDay() && d.getUTCDate() != 1; - } ], [ "%b %d", function(d) { - return d.getUTCDate() != 1; - } ], [ "%B", function(d) { - return d.getUTCMonth(); - } ], [ "%Y", d3_true ] ]); - d3_time_scaleUtcMethods.year = d3_time.year.utc; - d3_time.scale.utc = function() { - return d3_time_scale(d3.scale.linear(), d3_time_scaleUtcMethods, d3_time_scaleUtcFormat); - }; - d3.text = d3_xhrType(function(request) { - return request.responseText; - }); - d3.json = function(url, callback) { - return d3_xhr(url, "application/json", d3_json, callback); - }; - function d3_json(request) { - return JSON.parse(request.responseText); - } - d3.html = function(url, callback) { - return d3_xhr(url, "text/html", d3_html, callback); - }; - function d3_html(request) { - var range = d3_document.createRange(); - range.selectNode(d3_document.body); - return range.createContextualFragment(request.responseText); - } - d3.xml = d3_xhrType(function(request) { - return request.responseXML; - }); - if (typeof define === "function" && define.amd) define(d3); else if (typeof module === "object" && module.exports) module.exports = d3; - this.d3 = d3; -}(); -},{}],3:[function(require,module,exports){ -/** - * @license - * Copyright (c) 2012-2013 Chris Pettitt - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -module.exports = { - graphlib: require("./lib/graphlib"), - dagre: require("./lib/dagre"), - intersect: require("./lib/intersect"), - render: require("./lib/render"), - util: require("./lib/util"), - version: require("./lib/version") -}; - -},{"./lib/dagre":10,"./lib/graphlib":11,"./lib/intersect":12,"./lib/render":27,"./lib/util":29,"./lib/version":30}],4:[function(require,module,exports){ -var util = require("./util"); - -module.exports = { - "default": normal, - "normal": normal, - "vee": vee, - "undirected": undirected -}; - -function normal(parent, id, edge, type) { - var marker = parent.append("marker") - .attr("id", id) - .attr("viewBox", "0 0 10 10") - .attr("refX", 9) - .attr("refY", 5) - .attr("markerUnits", "strokeWidth") - .attr("markerWidth", 8) - .attr("markerHeight", 6) - .attr("orient", "auto"); - - var path = marker.append("path") - .attr("d", "M 0 0 L 10 5 L 0 10 z") - .style("stroke-width", 1) - .style("stroke-dasharray", "1,0"); - util.applyStyle(path, edge[type + "Style"]); -} - -function vee(parent, id, edge, type) { - var marker = parent.append("marker") - .attr("id", id) - .attr("viewBox", "0 0 10 10") - .attr("refX", 9) - .attr("refY", 5) - .attr("markerUnits", "strokeWidth") - .attr("markerWidth", 8) - .attr("markerHeight", 6) - .attr("orient", "auto"); - - var path = marker.append("path") - .attr("d", "M 0 0 L 10 5 L 0 10 L 4 5 z") - .style("stroke-width", 1) - .style("stroke-dasharray", "1,0"); - util.applyStyle(path, edge[type + "Style"]); -} - -function undirected(parent, id, edge, type) { - var marker = parent.append("marker") - .attr("id", id) - .attr("viewBox", "0 0 10 10") - .attr("refX", 9) - .attr("refY", 5) - .attr("markerUnits", "strokeWidth") - .attr("markerWidth", 8) - .attr("markerHeight", 6) - .attr("orient", "auto"); - - var path = marker.append("path") - .attr("d", "M 0 5 L 10 5") - .style("stroke-width", 1) - .style("stroke-dasharray", "1,0"); - util.applyStyle(path, edge[type + "Style"]); -} - -},{"./util":29}],5:[function(require,module,exports){ -var util = require("./util"), - addLabel = require("./label/add-label"); - -module.exports = createClusters; - -function createClusters(selection, g) { - var clusters = g.nodes().filter(function(v) { return util.isSubgraph(g, v); }), - svgClusters = selection.selectAll("g.cluster") - .data(clusters, function(v) { return v; }); - - svgClusters.selectAll("*").remove(); - svgClusters.enter() - .append("g") - .attr("class", "cluster") - .attr("id",function(v){ - var node = g.node(v); - return node.id; - }) - .style("opacity", 0); - - util.applyTransition(svgClusters, g) - .style("opacity", 1); - - svgClusters.each(function(v) { - var node = g.node(v), - thisGroup = d3.select(this); - d3.select(this).append("rect"); - var labelGroup = thisGroup.append("g").attr("class", "label"); - addLabel(labelGroup, node, node.clusterLabelPos); - }); - - svgClusters.selectAll("rect").each(function(c) { - var node = g.node(c); - var domCluster = d3.select(this); - util.applyStyle(domCluster, node.style); - }); - - util.applyTransition(svgClusters.exit(), g) - .style("opacity", 0) - .remove(); - - return svgClusters; -} - -},{"./label/add-label":20,"./util":29}],6:[function(require,module,exports){ -"use strict"; - -var _ = require("./lodash"), - addLabel = require("./label/add-label"), - util = require("./util"), - d3 = require("./d3"); - -module.exports = createEdgeLabels; - -function createEdgeLabels(selection, g) { - var svgEdgeLabels = selection.selectAll("g.edgeLabel") - .data(g.edges(), function(e) { return util.edgeToId(e); }) - .classed("update", true); - - svgEdgeLabels.selectAll("*").remove(); - svgEdgeLabels.enter() - .append("g") - .classed("edgeLabel", true) - .style("opacity", 0); - svgEdgeLabels.each(function(e) { - var edge = g.edge(e), - label = addLabel(d3.select(this), g.edge(e), 0, 0).classed("label", true), - bbox = label.node().getBBox(); - - if (edge.labelId) { label.attr("id", edge.labelId); } - if (!_.has(edge, "width")) { edge.width = bbox.width; } - if (!_.has(edge, "height")) { edge.height = bbox.height; } - }); - - util.applyTransition(svgEdgeLabels.exit(), g) - .style("opacity", 0) - .remove(); - - return svgEdgeLabels; -} - -},{"./d3":9,"./label/add-label":20,"./lodash":23,"./util":29}],7:[function(require,module,exports){ -"use strict"; - -var _ = require("./lodash"), - intersectNode = require("./intersect/intersect-node"), - util = require("./util"), - d3 = require("./d3"); - -module.exports = createEdgePaths; - -function createEdgePaths(selection, g, arrows) { - var svgPaths = selection.selectAll("g.edgePath") - .data(g.edges(), function(e) { return util.edgeToId(e); }) - .classed("update", true); - - enter(svgPaths, g); - exit(svgPaths, g); - - util.applyTransition(svgPaths, g) - .style("opacity", 1); - - // Save DOM element in the path group, and set ID and class - svgPaths.each(function(e) { - var domEdge = d3.select(this); - var edge = g.edge(e); - edge.elem = this; - - if (edge.id) { - domEdge.attr("id", edge.id); - } - - util.applyClass(domEdge, edge["class"], - (domEdge.classed("update") ? "update " : "") + "edgePath"); - }); - - svgPaths.selectAll("path.path") - .each(function(e) { - var edge = g.edge(e); - edge.arrowheadId = _.uniqueId("arrowhead"); - - var domEdge = d3.select(this) - .attr("marker-end", function() { - return "url(#" + edge.arrowheadId + ")"; - }) - .style("fill", "none"); - - util.applyTransition(domEdge, g) - .attr("d", function(e) { return calcPoints(g, e); }); - - util.applyStyle(domEdge, edge.style); - }); - - svgPaths.selectAll("defs *").remove(); - svgPaths.selectAll("defs") - .each(function(e) { - var edge = g.edge(e), - arrowhead = arrows[edge.arrowhead]; - arrowhead(d3.select(this), edge.arrowheadId, edge, "arrowhead"); - }); - - return svgPaths; -} - -function calcPoints(g, e) { - var edge = g.edge(e), - tail = g.node(e.v), - head = g.node(e.w), - points = edge.points.slice(1, edge.points.length - 1); - points.unshift(intersectNode(tail, points[0])); - points.push(intersectNode(head, points[points.length - 1])); - - return createLine(edge, points); -} - -function createLine(edge, points) { - var line = d3.svg.line() - .x(function(d) { return d.x; }) - .y(function(d) { return d.y; }); - - if (_.has(edge, "lineInterpolate")) { - line.interpolate(edge.lineInterpolate); - } - - if (_.has(edge, "lineTension")) { - line.tension(Number(edge.lineTension)); - } - - return line(points); -} - -function getCoords(elem) { - var bbox = elem.getBBox(), - matrix = elem.getTransformToElement(elem.ownerSVGElement) - .translate(bbox.width / 2, bbox.height / 2); - return { x: matrix.e, y: matrix.f }; -} - -function enter(svgPaths, g) { - var svgPathsEnter = svgPaths.enter() - .append("g") - .attr("class", "edgePath") - .style("opacity", 0); - svgPathsEnter.append("path") - .attr("class", "path") - .attr("d", function(e) { - var edge = g.edge(e), - sourceElem = g.node(e.v).elem, - points = _.range(edge.points.length).map(function() { return getCoords(sourceElem); }); - return createLine(edge, points); - }); - svgPathsEnter.append("defs"); -} - -function exit(svgPaths, g) { - var svgPathExit = svgPaths.exit(); - util.applyTransition(svgPathExit, g) - .style("opacity", 0) - .remove(); - - util.applyTransition(svgPathExit.select("path.path"), g) - .attr("d", function(e) { - var source = g.node(e.v); - - if (source) { - var points = _.range(this.pathSegList.length).map(function() { return source; }); - return createLine({}, points); - } else { - return d3.select(this).attr("d"); - } - }); -} - -},{"./d3":9,"./intersect/intersect-node":16,"./lodash":23,"./util":29}],8:[function(require,module,exports){ -"use strict"; - -var _ = require("./lodash"), - addLabel = require("./label/add-label"), - util = require("./util"), - d3 = require("./d3"); - -module.exports = createNodes; - -function createNodes(selection, g, shapes) { - var simpleNodes = g.nodes().filter(function(v) { return !util.isSubgraph(g, v); }); - var svgNodes = selection.selectAll("g.node") - .data(simpleNodes, function(v) { return v; }) - .classed("update", true); - - svgNodes.selectAll("*").remove(); - svgNodes.enter() - .append("g") - .attr("class", "node") - .style("opacity", 0); - svgNodes.each(function(v) { - var node = g.node(v), - thisGroup = d3.select(this), - labelGroup = thisGroup.append("g").attr("class", "label"), - labelDom = addLabel(labelGroup, node), - shape = shapes[node.shape], - bbox = _.pick(labelDom.node().getBBox(), "width", "height"); - - node.elem = this; - - if (node.id) { thisGroup.attr("id", node.id); } - if (node.labelId) { labelGroup.attr("id", node.labelId); } - util.applyClass(thisGroup, node["class"], - (thisGroup.classed("update") ? "update " : "") + "node"); - - if (_.has(node, "width")) { bbox.width = node.width; } - if (_.has(node, "height")) { bbox.height = node.height; } - - bbox.width += node.paddingLeft + node.paddingRight; - bbox.height += node.paddingTop + node.paddingBottom; - labelGroup.attr("transform", "translate(" + - ((node.paddingLeft - node.paddingRight) / 2) + "," + - ((node.paddingTop - node.paddingBottom) / 2) + ")"); - - var shapeSvg = shape(d3.select(this), bbox, node); - util.applyStyle(shapeSvg, node.style); - - var shapeBBox = shapeSvg.node().getBBox(); - node.width = shapeBBox.width; - node.height = shapeBBox.height; - }); - - util.applyTransition(svgNodes.exit(), g) - .style("opacity", 0) - .remove(); - - return svgNodes; -} - -},{"./d3":9,"./label/add-label":20,"./lodash":23,"./util":29}],9:[function(require,module,exports){ -// Stub to get D3 either via NPM or from the global object -module.exports = window.d3; - -},{}],10:[function(require,module,exports){ -/* global window */ - -var dagre; - -if (require) { - try { - dagre = require("dagre"); - } catch (e) {} -} - -if (!dagre) { - dagre = window.dagre; -} - -module.exports = dagre; - -},{"dagre":52}],11:[function(require,module,exports){ -/* global window */ - -var graphlib; - -if (require) { - try { - graphlib = require("graphlib"); - } catch (e) {} -} - -if (!graphlib) { - graphlib = window.graphlib; -} - -module.exports = graphlib; - -},{"graphlib":31}],12:[function(require,module,exports){ -module.exports = { - node: require("./intersect-node"), - circle: require("./intersect-circle"), - ellipse: require("./intersect-ellipse"), - polygon: require("./intersect-polygon"), - rect: require("./intersect-rect") -}; - -},{"./intersect-circle":13,"./intersect-ellipse":14,"./intersect-node":16,"./intersect-polygon":17,"./intersect-rect":18}],13:[function(require,module,exports){ -var intersectEllipse = require("./intersect-ellipse"); - -module.exports = intersectCircle; - -function intersectCircle(node, rx, point) { - return intersectEllipse(node, rx, rx, point); -} - -},{"./intersect-ellipse":14}],14:[function(require,module,exports){ -module.exports = intersectEllipse; - -function intersectEllipse(node, rx, ry, point) { - // Formulae from: http://mathworld.wolfram.com/Ellipse-LineIntersection.html - - var cx = node.x; - var cy = node.y; - - var px = cx - point.x; - var py = cy - point.y; - - var det = Math.sqrt(rx * rx * py * py + ry * ry * px * px); - - var dx = Math.abs(rx * ry * px / det); - if (point.x < cx) { - dx = -dx; - } - var dy = Math.abs(rx * ry * py / det); - if (point.y < cy) { - dy = -dy; - } - - return {x: cx + dx, y: cy + dy}; -} - - -},{}],15:[function(require,module,exports){ -module.exports = intersectLine; - -/* - * Returns the point at which two lines, p and q, intersect or returns - * undefined if they do not intersect. - */ -function intersectLine(p1, p2, q1, q2) { - // Algorithm from J. Avro, (ed.) Graphics Gems, No 2, Morgan Kaufmann, 1994, - // p7 and p473. - - var a1, a2, b1, b2, c1, c2; - var r1, r2 , r3, r4; - var denom, offset, num; - var x, y; - - // Compute a1, b1, c1, where line joining points 1 and 2 is F(x,y) = a1 x + - // b1 y + c1 = 0. - a1 = p2.y - p1.y; - b1 = p1.x - p2.x; - c1 = (p2.x * p1.y) - (p1.x * p2.y); - - // Compute r3 and r4. - r3 = ((a1 * q1.x) + (b1 * q1.y) + c1); - r4 = ((a1 * q2.x) + (b1 * q2.y) + c1); - - // Check signs of r3 and r4. If both point 3 and point 4 lie on - // same side of line 1, the line segments do not intersect. - if ((r3 !== 0) && (r4 !== 0) && sameSign(r3, r4)) { - return /*DONT_INTERSECT*/; - } - - // Compute a2, b2, c2 where line joining points 3 and 4 is G(x,y) = a2 x + b2 y + c2 = 0 - a2 = q2.y - q1.y; - b2 = q1.x - q2.x; - c2 = (q2.x * q1.y) - (q1.x * q2.y); - - // Compute r1 and r2 - r1 = (a2 * p1.x) + (b2 * p1.yy) + c2; - r2 = (a2 * p2.x) + (b2 * p2.y) + c2; - - // Check signs of r1 and r2. If both point 1 and point 2 lie - // on same side of second line segment, the line segments do - // not intersect. - if ((r1 !== 0) && (r2 !== 0) && (sameSign(r1, r2))) { - return /*DONT_INTERSECT*/; - } - - // Line segments intersect: compute intersection point. - denom = (a1 * b2) - (a2 * b1); - if (denom === 0) { - return /*COLLINEAR*/; - } - - offset = Math.abs(denom / 2); - - // The denom/2 is to get rounding instead of truncating. It - // is added or subtracted to the numerator, depending upon the - // sign of the numerator. - num = (b1 * c2) - (b2 * c1); - x = (num < 0) ? ((num - offset) / denom) : ((num + offset) / denom); - - num = (a2 * c1) - (a1 * c2); - y = (num < 0) ? ((num - offset) / denom) : ((num + offset) / denom); - - return { x: x, y: y }; -} - -function sameSign(r1, r2) { - return r1 * r2 > 0; -} - -},{}],16:[function(require,module,exports){ -module.exports = intersectNode; - -function intersectNode(node, point) { - return node.intersect(point); -} - -},{}],17:[function(require,module,exports){ -var intersectLine = require("./intersect-line"); - -module.exports = intersectPolygon; - -/* - * Returns the point ({x, y}) at which the point argument intersects with the - * node argument assuming that it has the shape specified by polygon. - */ -function intersectPolygon(node, polyPoints, point) { - var x1 = node.x; - var y1 = node.y; - - var intersections = []; - - var minX = Number.POSITIVE_INFINITY, - minY = Number.POSITIVE_INFINITY; - polyPoints.forEach(function(entry) { - minX = Math.min(minX, entry.x); - minY = Math.min(minY, entry.y); - }); - - var left = x1 - node.width / 2 - minX; - var top = y1 - node.height / 2 - minY; - - for (var i = 0; i < polyPoints.length; i++) { - var p1 = polyPoints[i]; - var p2 = polyPoints[i < polyPoints.length - 1 ? i + 1 : 0]; - var intersect = intersectLine(node, point, - {x: left + p1.x, y: top + p1.y}, {x: left + p2.x, y: top + p2.y}); - if (intersect) { - intersections.push(intersect); - } - } - - if (!intersections.length) { - console.log("NO INTERSECTION FOUND, RETURN NODE CENTER", node); - return node; - } - - if (intersections.length > 1) { - // More intersections, find the one nearest to edge end point - intersections.sort(function(p, q) { - var pdx = p.x - point.x, - pdy = p.y - point.y, - distp = Math.sqrt(pdx * pdx + pdy * pdy), - - qdx = q.x - point.x, - qdy = q.y - point.y, - distq = Math.sqrt(qdx * qdx + qdy * qdy); - - return (distp < distq) ? -1 : (distp === distq ? 0 : 1); - }); - } - return intersections[0]; -} - -},{"./intersect-line":15}],18:[function(require,module,exports){ -module.exports = intersectRect; - -function intersectRect(node, point) { - var x = node.x; - var y = node.y; - - // Rectangle intersection algorithm from: - // http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes - var dx = point.x - x; - var dy = point.y - y; - var w = node.width / 2; - var h = node.height / 2; - - var sx, sy; - if (Math.abs(dy) * w > Math.abs(dx) * h) { - // Intersection is top or bottom of rect. - if (dy < 0) { - h = -h; - } - sx = dy === 0 ? 0 : h * dx / dy; - sy = h; - } else { - // Intersection is left or right of rect. - if (dx < 0) { - w = -w; - } - sx = w; - sy = dx === 0 ? 0 : w * dy / dx; - } - - return {x: x + sx, y: y + sy}; -} - -},{}],19:[function(require,module,exports){ -var util = require("../util"); - -module.exports = addHtmlLabel; - -function addHtmlLabel(root, node) { - var fo = root - .append("foreignObject") - .attr("width", "100000"); - - var div = fo - .append("xhtml:div"); - - var label = node.label; - switch(typeof label) { - case "function": - div.insert(label); - break; - case "object": - // Currently we assume this is a DOM object. - div.insert(function() { return label; }); - break; - default: div.html(label); - } - - util.applyStyle(div, node.labelStyle); - div.style("display", "inline-block"); - // Fix for firefox - div.style("white-space", "nowrap"); - - // TODO find a better way to get dimensions for foreignObjects... - var w, h; - div - .each(function() { - w = this.clientWidth; - h = this.clientHeight; - }); - - fo - .attr("width", w) - .attr("height", h); - - return fo; -} - -},{"../util":29}],20:[function(require,module,exports){ -var addTextLabel = require("./add-text-label"), - addHtmlLabel = require("./add-html-label"), - addSVGLabel = require("./add-svg-label"); - -module.exports = addLabel; - -function addLabel(root, node, location) { - var label = node.label; - var labelSvg = root.append("g"); - - // Allow the label to be a string, a function that returns a DOM element, or - // a DOM element itself. - if (node.labelType === "svg") { - addSVGLabel(labelSvg, node); - } else if (typeof label !== "string" || node.labelType === "html") { - addHtmlLabel(labelSvg, node); - } else { - addTextLabel(labelSvg, node); - } - - var labelBBox = labelSvg.node().getBBox(); - var y; - switch(location) { - case "top": - y = (-node.height / 2); - break; - case "bottom": - y = (node.height / 2) - labelBBox.height; - break; - default: - y = (-labelBBox.height / 2); - } - labelSvg.attr("transform", - "translate(" + (-labelBBox.width / 2) + "," + y + ")"); - - return labelSvg; -} - -},{"./add-html-label":19,"./add-svg-label":21,"./add-text-label":22}],21:[function(require,module,exports){ -var util = require("../util"); - -module.exports = addSVGLabel; - -function addSVGLabel(root, node) { - var domNode = root; - - domNode.node().appendChild(node.label); - - util.applyStyle(domNode, node.labelStyle); - - return domNode; -} - -},{"../util":29}],22:[function(require,module,exports){ -var util = require("../util"); - -module.exports = addTextLabel; - -/* - * Attaches a text label to the specified root. Handles escape sequences. - */ -function addTextLabel(root, node) { - var domNode = root.append("text"); - - var lines = processEscapeSequences(node.label).split("\n"); - for (var i = 0; i < lines.length; i++) { - domNode - .append("tspan") - .attr("xml:space", "preserve") - .attr("dy", "1em") - .attr("x", "1") - .text(lines[i]); - } - - util.applyStyle(domNode, node.labelStyle); - - return domNode; -} - -function processEscapeSequences(text) { - var newText = "", - escaped = false, - ch; - for (var i = 0; i < text.length; ++i) { - ch = text[i]; - if (escaped) { - switch(ch) { - case "n": newText += "\n"; break; - default: newText += ch; - } - escaped = false; - } else if (ch === "\\") { - escaped = true; - } else { - newText += ch; - } - } - return newText; -} - -},{"../util":29}],23:[function(require,module,exports){ -/* global window */ - -var lodash; - -if (require) { - try { - lodash = require("lodash"); - } catch (e) {} -} - -if (!lodash) { - lodash = window._; -} - -module.exports = lodash; - -},{"lodash":51}],24:[function(require,module,exports){ -"use strict"; - -var util = require("./util"), - d3 = require("./d3"); - -module.exports = positionClusters; - -function positionClusters(selection, g) { - var created = selection.filter(function() { return !d3.select(this).classed("update"); }); - - function translate(v) { - var node = g.node(v); - return "translate(" + node.x + "," + node.y + ")"; - } - - created.attr("transform", translate); - - util.applyTransition(selection, g) - .style("opacity", 1) - .attr("transform", translate); - - util.applyTransition(created.selectAll("rect"), g) - .attr("width", function(v) { return g.node(v).width; }) - .attr("height", function(v) { return g.node(v).height; }) - .attr("x", function(v) { - var node = g.node(v); - return -node.width / 2; - }) - .attr("y", function(v) { - var node = g.node(v); - return -node.height / 2; - }); - -} - -},{"./d3":9,"./util":29}],25:[function(require,module,exports){ -"use strict"; - -var util = require("./util"), - d3 = require("./d3"), - _ = require("./lodash"); - -module.exports = positionEdgeLabels; - -function positionEdgeLabels(selection, g) { - var created = selection.filter(function() { return !d3.select(this).classed("update"); }); - - function translate(e) { - var edge = g.edge(e); - return _.has(edge, "x") ? "translate(" + edge.x + "," + edge.y + ")" : ""; - } - - created.attr("transform", translate); - - util.applyTransition(selection, g) - .style("opacity", 1) - .attr("transform", translate); -} - -},{"./d3":9,"./lodash":23,"./util":29}],26:[function(require,module,exports){ -"use strict"; - -var util = require("./util"), - d3 = require("./d3"); - -module.exports = positionNodes; - -function positionNodes(selection, g) { - var created = selection.filter(function() { return !d3.select(this).classed("update"); }); - - function translate(v) { - var node = g.node(v); - return "translate(" + node.x + "," + node.y + ")"; - } - - created.attr("transform", translate); - - util.applyTransition(selection, g) - .style("opacity", 1) - .attr("transform", translate); -} - -},{"./d3":9,"./util":29}],27:[function(require,module,exports){ -var _ = require("./lodash"), - layout = require("./dagre").layout; - -module.exports = render; - -// This design is based on http://bost.ocks.org/mike/chart/. -function render() { - var createNodes = require("./create-nodes"), - createClusters = require("./create-clusters"), - createEdgeLabels = require("./create-edge-labels"), - createEdgePaths = require("./create-edge-paths"), - positionNodes = require("./position-nodes"), - positionEdgeLabels = require("./position-edge-labels"), - positionClusters = require("./position-clusters"), - shapes = require("./shapes"), - arrows = require("./arrows"); - - var fn = function(svg, g) { - preProcessGraph(g); - - var outputGroup = createOrSelectGroup(svg, "output"), - clustersGroup = createOrSelectGroup(outputGroup, "clusters"), - edgePathsGroup = createOrSelectGroup(outputGroup, "edgePaths"), - edgeLabels = createEdgeLabels(createOrSelectGroup(outputGroup, "edgeLabels"), g), - nodes = createNodes(createOrSelectGroup(outputGroup, "nodes"), g, shapes); - - layout(g); - - positionNodes(nodes, g); - positionEdgeLabels(edgeLabels, g); - createEdgePaths(edgePathsGroup, g, arrows); - - var clusters = createClusters(clustersGroup, g); - positionClusters(clusters, g); - - postProcessGraph(g); - }; - - fn.createNodes = function(value) { - if (!arguments.length) return createNodes; - createNodes = value; - return fn; - }; - - fn.createClusters = function(value) { - if (!arguments.length) return createClusters; - createClusters = value; - return fn; - }; - - fn.createEdgeLabels = function(value) { - if (!arguments.length) return createEdgeLabels; - createEdgeLabels = value; - return fn; - }; - - fn.createEdgePaths = function(value) { - if (!arguments.length) return createEdgePaths; - createEdgePaths = value; - return fn; - }; - - fn.shapes = function(value) { - if (!arguments.length) return shapes; - shapes = value; - return fn; - }; - - fn.arrows = function(value) { - if (!arguments.length) return arrows; - arrows = value; - return fn; - }; - - return fn; -} - -var NODE_DEFAULT_ATTRS = { - paddingLeft: 10, - paddingRight: 10, - paddingTop: 10, - paddingBottom: 10, - rx: 0, - ry: 0, - shape: "rect" -}; - -var EDGE_DEFAULT_ATTRS = { - arrowhead: "normal", - lineInterpolate: "linear" -}; - -function preProcessGraph(g) { - g.nodes().forEach(function(v) { - var node = g.node(v); - if (!_.has(node, "label") && !g.children(v).length) { node.label = v; } - - if (_.has(node, "paddingX")) { - _.defaults(node, { - paddingLeft: node.paddingX, - paddingRight: node.paddingX - }); - } - - if (_.has(node, "paddingY")) { - _.defaults(node, { - paddingTop: node.paddingY, - paddingBottom: node.paddingY - }); - } - - if (_.has(node, "padding")) { - _.defaults(node, { - paddingLeft: node.padding, - paddingRight: node.padding, - paddingTop: node.padding, - paddingBottom: node.padding - }); - } - - _.defaults(node, NODE_DEFAULT_ATTRS); - - _.each(["paddingLeft", "paddingRight", "paddingTop", "paddingBottom"], function(k) { - node[k] = Number(node[k]); - }); - - // Save dimensions for restore during post-processing - if (_.has(node, "width")) { node._prevWidth = node.width; } - if (_.has(node, "height")) { node._prevHeight = node.height; } - }); - - g.edges().forEach(function(e) { - var edge = g.edge(e); - if (!_.has(edge, "label")) { edge.label = ""; } - _.defaults(edge, EDGE_DEFAULT_ATTRS); - }); -} - -function postProcessGraph(g) { - _.each(g.nodes(), function(v) { - var node = g.node(v); - - // Restore original dimensions - if (_.has(node, "_prevWidth")) { - node.width = node._prevWidth; - } else { - delete node.width; - } - - if (_.has(node, "_prevHeight")) { - node.height = node._prevHeight; - } else { - delete node.height; - } - - delete node._prevWidth; - delete node._prevHeight; - }); -} - -function createOrSelectGroup(root, name) { - var selection = root.select("g." + name); - if (selection.empty()) { - selection = root.append("g").attr("class", name); - } - return selection; -} - -},{"./arrows":4,"./create-clusters":5,"./create-edge-labels":6,"./create-edge-paths":7,"./create-nodes":8,"./dagre":10,"./lodash":23,"./position-clusters":24,"./position-edge-labels":25,"./position-nodes":26,"./shapes":28}],28:[function(require,module,exports){ -"use strict"; - -var intersectRect = require("./intersect/intersect-rect"), - intersectEllipse = require("./intersect/intersect-ellipse"), - intersectCircle = require("./intersect/intersect-circle"), - intersectPolygon = require("./intersect/intersect-polygon"); - -module.exports = { - rect: rect, - ellipse: ellipse, - circle: circle, - diamond: diamond -}; - -function rect(parent, bbox, node) { - var shapeSvg = parent.insert("rect", ":first-child") - .attr("rx", node.rx) - .attr("ry", node.ry) - .attr("x", -bbox.width / 2) - .attr("y", -bbox.height / 2) - .attr("width", bbox.width) - .attr("height", bbox.height); - - node.intersect = function(point) { - return intersectRect(node, point); - }; - - return shapeSvg; -} - -function ellipse(parent, bbox, node) { - var rx = bbox.width / 2, - ry = bbox.height / 2, - shapeSvg = parent.insert("ellipse", ":first-child") - .attr("x", -bbox.width / 2) - .attr("y", -bbox.height / 2) - .attr("rx", rx) - .attr("ry", ry); - - node.intersect = function(point) { - return intersectEllipse(node, rx, ry, point); - }; - - return shapeSvg; -} - -function circle(parent, bbox, node) { - var r = Math.max(bbox.width, bbox.height) / 2, - shapeSvg = parent.insert("circle", ":first-child") - .attr("x", -bbox.width / 2) - .attr("y", -bbox.height / 2) - .attr("r", r); - - node.intersect = function(point) { - return intersectCircle(node, r, point); - }; - - return shapeSvg; -} - -// Circumscribe an ellipse for the bounding box with a diamond shape. I derived -// the function to calculate the diamond shape from: -// http://mathforum.org/kb/message.jspa?messageID=3750236 -function diamond(parent, bbox, node) { - var w = (bbox.width * Math.SQRT2) / 2, - h = (bbox.height * Math.SQRT2) / 2, - points = [ - { x: 0, y: -h }, - { x: -w, y: 0 }, - { x: 0, y: h }, - { x: w, y: 0 } - ], - shapeSvg = parent.insert("polygon", ":first-child") - .attr("points", points.map(function(p) { return p.x + "," + p.y; }).join(" ")); - - node.intersect = function(p) { - return intersectPolygon(node, points, p); - }; - - return shapeSvg; -} - -},{"./intersect/intersect-circle":13,"./intersect/intersect-ellipse":14,"./intersect/intersect-polygon":17,"./intersect/intersect-rect":18}],29:[function(require,module,exports){ -var _ = require("./lodash"); - -// Public utility functions -module.exports = { - isSubgraph: isSubgraph, - edgeToId: edgeToId, - applyStyle: applyStyle, - applyClass: applyClass, - applyTransition: applyTransition -}; - -/* - * Returns true if the specified node in the graph is a subgraph node. A - * subgraph node is one that contains other nodes. - */ -function isSubgraph(g, v) { - return !!g.children(v).length; -} - -function edgeToId(e) { - return escapeId(e.v) + ":" + escapeId(e.w) + ":" + escapeId(e.name); -} - -var ID_DELIM = /:/g; -function escapeId(str) { - return str ? String(str).replace(ID_DELIM, "\\:") : ""; -} - -function applyStyle(dom, styleFn) { - if (styleFn) { - dom.attr("style", styleFn); - } -} - -function applyClass(dom, classFn, otherClasses) { - if (classFn) { - dom - .attr("class", classFn) - .attr("class", otherClasses + " " + dom.attr("class")); - } -} - -function applyTransition(selection, g) { - var graph = g.graph(); - - if (_.isPlainObject(graph)) { - var transition = graph.transition; - if (_.isFunction(transition)) { - return transition(selection); - } - } - - return selection; -} - -},{"./lodash":23}],30:[function(require,module,exports){ -module.exports = "0.4.10"; - -},{}],31:[function(require,module,exports){ -/** - * Copyright (c) 2014, Chris Pettitt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors - * may be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -var lib = require("./lib"); - -module.exports = { - Graph: lib.Graph, - json: require("./lib/json"), - alg: require("./lib/alg"), - version: lib.version -}; - -},{"./lib":47,"./lib/alg":38,"./lib/json":48}],32:[function(require,module,exports){ -var _ = require("../lodash"); - -module.exports = components; - -function components(g) { - var visited = {}, - cmpts = [], - cmpt; - - function dfs(v) { - if (_.has(visited, v)) return; - visited[v] = true; - cmpt.push(v); - _.each(g.successors(v), dfs); - _.each(g.predecessors(v), dfs); - } - - _.each(g.nodes(), function(v) { - cmpt = []; - dfs(v); - if (cmpt.length) { - cmpts.push(cmpt); - } - }); - - return cmpts; -} - -},{"../lodash":49}],33:[function(require,module,exports){ -var _ = require("../lodash"); - -module.exports = dfs; - -/* - * A helper that preforms a pre- or post-order traversal on the input graph - * and returns the nodes in the order they were visited. This algorithm treats - * the input as undirected. - * - * Order must be one of "pre" or "post". - */ -function dfs(g, vs, order) { - if (!_.isArray(vs)) { - vs = [vs]; - } - - var acc = [], - visited = {}; - _.each(vs, function(v) { - if (!g.hasNode(v)) { - throw new Error("Graph does not have node: " + v); - } - - doDfs(g, v, order === "post", visited, acc); - }); - return acc; -} - -function doDfs(g, v, postorder, visited, acc) { - if (!_.has(visited, v)) { - visited[v] = true; - - if (!postorder) { acc.push(v); } - _.each(g.neighbors(v), function(w) { - doDfs(g, w, postorder, visited, acc); - }); - if (postorder) { acc.push(v); } - } -} - -},{"../lodash":49}],34:[function(require,module,exports){ -var dijkstra = require("./dijkstra"), - _ = require("../lodash"); - -module.exports = dijkstraAll; - -function dijkstraAll(g, weightFunc, edgeFunc) { - return _.transform(g.nodes(), function(acc, v) { - acc[v] = dijkstra(g, v, weightFunc, edgeFunc); - }, {}); -} - -},{"../lodash":49,"./dijkstra":35}],35:[function(require,module,exports){ -var _ = require("../lodash"), - PriorityQueue = require("../data/priority-queue"); - -module.exports = dijkstra; - -var DEFAULT_WEIGHT_FUNC = _.constant(1); - -function dijkstra(g, source, weightFn, edgeFn) { - return runDijkstra(g, String(source), - weightFn || DEFAULT_WEIGHT_FUNC, - edgeFn || function(v) { return g.outEdges(v); }); -} - -function runDijkstra(g, source, weightFn, edgeFn) { - var results = {}, - pq = new PriorityQueue(), - v, vEntry; - - var updateNeighbors = function(edge) { - var w = edge.v !== v ? edge.v : edge.w, - wEntry = results[w], - weight = weightFn(edge), - distance = vEntry.distance + weight; - - if (weight < 0) { - throw new Error("dijkstra does not allow negative edge weights. " + - "Bad edge: " + edge + " Weight: " + weight); - } - - if (distance < wEntry.distance) { - wEntry.distance = distance; - wEntry.predecessor = v; - pq.decrease(w, distance); - } - }; - - g.nodes().forEach(function(v) { - var distance = v === source ? 0 : Number.POSITIVE_INFINITY; - results[v] = { distance: distance }; - pq.add(v, distance); - }); - - while (pq.size() > 0) { - v = pq.removeMin(); - vEntry = results[v]; - if (vEntry.distance === Number.POSITIVE_INFINITY) { - break; - } - - edgeFn(v).forEach(updateNeighbors); - } - - return results; -} - -},{"../data/priority-queue":45,"../lodash":49}],36:[function(require,module,exports){ -var _ = require("../lodash"), - tarjan = require("./tarjan"); - -module.exports = findCycles; - -function findCycles(g) { - return _.filter(tarjan(g), function(cmpt) { - return cmpt.length > 1 || (cmpt.length === 1 && g.hasEdge(cmpt[0], cmpt[0])); - }); -} - -},{"../lodash":49,"./tarjan":43}],37:[function(require,module,exports){ -var _ = require("../lodash"); - -module.exports = floydWarshall; - -var DEFAULT_WEIGHT_FUNC = _.constant(1); - -function floydWarshall(g, weightFn, edgeFn) { - return runFloydWarshall(g, - weightFn || DEFAULT_WEIGHT_FUNC, - edgeFn || function(v) { return g.outEdges(v); }); -} - -function runFloydWarshall(g, weightFn, edgeFn) { - var results = {}, - nodes = g.nodes(); - - nodes.forEach(function(v) { - results[v] = {}; - results[v][v] = { distance: 0 }; - nodes.forEach(function(w) { - if (v !== w) { - results[v][w] = { distance: Number.POSITIVE_INFINITY }; - } - }); - edgeFn(v).forEach(function(edge) { - var w = edge.v === v ? edge.w : edge.v, - d = weightFn(edge); - results[v][w] = { distance: d, predecessor: v }; - }); - }); - - nodes.forEach(function(k) { - var rowK = results[k]; - nodes.forEach(function(i) { - var rowI = results[i]; - nodes.forEach(function(j) { - var ik = rowI[k]; - var kj = rowK[j]; - var ij = rowI[j]; - var altDistance = ik.distance + kj.distance; - if (altDistance < ij.distance) { - ij.distance = altDistance; - ij.predecessor = kj.predecessor; - } - }); - }); - }); - - return results; -} - -},{"../lodash":49}],38:[function(require,module,exports){ -module.exports = { - components: require("./components"), - dijkstra: require("./dijkstra"), - dijkstraAll: require("./dijkstra-all"), - findCycles: require("./find-cycles"), - floydWarshall: require("./floyd-warshall"), - isAcyclic: require("./is-acyclic"), - postorder: require("./postorder"), - preorder: require("./preorder"), - prim: require("./prim"), - tarjan: require("./tarjan"), - topsort: require("./topsort") -}; - -},{"./components":32,"./dijkstra":35,"./dijkstra-all":34,"./find-cycles":36,"./floyd-warshall":37,"./is-acyclic":39,"./postorder":40,"./preorder":41,"./prim":42,"./tarjan":43,"./topsort":44}],39:[function(require,module,exports){ -var topsort = require("./topsort"); - -module.exports = isAcyclic; - -function isAcyclic(g) { - try { - topsort(g); - } catch (e) { - if (e instanceof topsort.CycleException) { - return false; - } - throw e; - } - return true; -} - -},{"./topsort":44}],40:[function(require,module,exports){ -var dfs = require("./dfs"); - -module.exports = postorder; - -function postorder(g, vs) { - return dfs(g, vs, "post"); -} - -},{"./dfs":33}],41:[function(require,module,exports){ -var dfs = require("./dfs"); - -module.exports = preorder; - -function preorder(g, vs) { - return dfs(g, vs, "pre"); -} - -},{"./dfs":33}],42:[function(require,module,exports){ -var _ = require("../lodash"), - Graph = require("../graph"), - PriorityQueue = require("../data/priority-queue"); - -module.exports = prim; - -function prim(g, weightFunc) { - var result = new Graph(), - parents = {}, - pq = new PriorityQueue(), - v; - - function updateNeighbors(edge) { - var w = edge.v === v ? edge.w : edge.v, - pri = pq.priority(w); - if (pri !== undefined) { - var edgeWeight = weightFunc(edge); - if (edgeWeight < pri) { - parents[w] = v; - pq.decrease(w, edgeWeight); - } - } - } - - if (g.nodeCount() === 0) { - return result; - } - - _.each(g.nodes(), function(v) { - pq.add(v, Number.POSITIVE_INFINITY); - result.setNode(v); - }); - - // Start from an arbitrary node - pq.decrease(g.nodes()[0], 0); - - var init = false; - while (pq.size() > 0) { - v = pq.removeMin(); - if (_.has(parents, v)) { - result.setEdge(v, parents[v]); - } else if (init) { - throw new Error("Input graph is not connected: " + g); - } else { - init = true; - } - - g.nodeEdges(v).forEach(updateNeighbors); - } - - return result; -} - -},{"../data/priority-queue":45,"../graph":46,"../lodash":49}],43:[function(require,module,exports){ -var _ = require("../lodash"); - -module.exports = tarjan; - -function tarjan(g) { - var index = 0, - stack = [], - visited = {}, // node id -> { onStack, lowlink, index } - results = []; - - function dfs(v) { - var entry = visited[v] = { - onStack: true, - lowlink: index, - index: index++ - }; - stack.push(v); - - g.successors(v).forEach(function(w) { - if (!_.has(visited, w)) { - dfs(w); - entry.lowlink = Math.min(entry.lowlink, visited[w].lowlink); - } else if (visited[w].onStack) { - entry.lowlink = Math.min(entry.lowlink, visited[w].index); - } - }); - - if (entry.lowlink === entry.index) { - var cmpt = [], - w; - do { - w = stack.pop(); - visited[w].onStack = false; - cmpt.push(w); - } while (v !== w); - results.push(cmpt); - } - } - - g.nodes().forEach(function(v) { - if (!_.has(visited, v)) { - dfs(v); - } - }); - - return results; -} - -},{"../lodash":49}],44:[function(require,module,exports){ -var _ = require("../lodash"); - -module.exports = topsort; -topsort.CycleException = CycleException; - -function topsort(g) { - var visited = {}, - stack = {}, - results = []; - - function visit(node) { - if (_.has(stack, node)) { - throw new CycleException(); - } - - if (!_.has(visited, node)) { - stack[node] = true; - visited[node] = true; - _.each(g.predecessors(node), visit); - delete stack[node]; - results.push(node); - } - } - - _.each(g.sinks(), visit); - - if (_.size(visited) !== g.nodeCount()) { - throw new CycleException(); - } - - return results; -} - -function CycleException() {} - -},{"../lodash":49}],45:[function(require,module,exports){ -var _ = require("../lodash"); - -module.exports = PriorityQueue; - -/** - * A min-priority queue data structure. This algorithm is derived from Cormen, - * et al., "Introduction to Algorithms". The basic idea of a min-priority - * queue is that you can efficiently (in O(1) time) get the smallest key in - * the queue. Adding and removing elements takes O(log n) time. A key can - * have its priority decreased in O(log n) time. - */ -function PriorityQueue() { - this._arr = []; - this._keyIndices = {}; -} - -/** - * Returns the number of elements in the queue. Takes `O(1)` time. - */ -PriorityQueue.prototype.size = function() { - return this._arr.length; -}; - -/** - * Returns the keys that are in the queue. Takes `O(n)` time. - */ -PriorityQueue.prototype.keys = function() { - return this._arr.map(function(x) { return x.key; }); -}; - -/** - * Returns `true` if **key** is in the queue and `false` if not. - */ -PriorityQueue.prototype.has = function(key) { - return _.has(this._keyIndices, key); -}; - -/** - * Returns the priority for **key**. If **key** is not present in the queue - * then this function returns `undefined`. Takes `O(1)` time. - * - * @param {Object} key - */ -PriorityQueue.prototype.priority = function(key) { - var index = this._keyIndices[key]; - if (index !== undefined) { - return this._arr[index].priority; - } -}; - -/** - * Returns the key for the minimum element in this queue. If the queue is - * empty this function throws an Error. Takes `O(1)` time. - */ -PriorityQueue.prototype.min = function() { - if (this.size() === 0) { - throw new Error("Queue underflow"); - } - return this._arr[0].key; -}; - -/** - * Inserts a new key into the priority queue. If the key already exists in - * the queue this function returns `false`; otherwise it will return `true`. - * Takes `O(n)` time. - * - * @param {Object} key the key to add - * @param {Number} priority the initial priority for the key - */ -PriorityQueue.prototype.add = function(key, priority) { - var keyIndices = this._keyIndices; - key = String(key); - if (!_.has(keyIndices, key)) { - var arr = this._arr; - var index = arr.length; - keyIndices[key] = index; - arr.push({key: key, priority: priority}); - this._decrease(index); - return true; - } - return false; -}; - -/** - * Removes and returns the smallest key in the queue. Takes `O(log n)` time. - */ -PriorityQueue.prototype.removeMin = function() { - this._swap(0, this._arr.length - 1); - var min = this._arr.pop(); - delete this._keyIndices[min.key]; - this._heapify(0); - return min.key; -}; - -/** - * Decreases the priority for **key** to **priority**. If the new priority is - * greater than the previous priority, this function will throw an Error. - * - * @param {Object} key the key for which to raise priority - * @param {Number} priority the new priority for the key - */ -PriorityQueue.prototype.decrease = function(key, priority) { - var index = this._keyIndices[key]; - if (priority > this._arr[index].priority) { - throw new Error("New priority is greater than current priority. " + - "Key: " + key + " Old: " + this._arr[index].priority + " New: " + priority); - } - this._arr[index].priority = priority; - this._decrease(index); -}; - -PriorityQueue.prototype._heapify = function(i) { - var arr = this._arr; - var l = 2 * i, - r = l + 1, - largest = i; - if (l < arr.length) { - largest = arr[l].priority < arr[largest].priority ? l : largest; - if (r < arr.length) { - largest = arr[r].priority < arr[largest].priority ? r : largest; - } - if (largest !== i) { - this._swap(i, largest); - this._heapify(largest); - } - } -}; - -PriorityQueue.prototype._decrease = function(index) { - var arr = this._arr; - var priority = arr[index].priority; - var parent; - while (index !== 0) { - parent = index >> 1; - if (arr[parent].priority < priority) { - break; - } - this._swap(index, parent); - index = parent; - } -}; - -PriorityQueue.prototype._swap = function(i, j) { - var arr = this._arr; - var keyIndices = this._keyIndices; - var origArrI = arr[i]; - var origArrJ = arr[j]; - arr[i] = origArrJ; - arr[j] = origArrI; - keyIndices[origArrJ.key] = i; - keyIndices[origArrI.key] = j; -}; - -},{"../lodash":49}],46:[function(require,module,exports){ -"use strict"; - -var _ = require("./lodash"); - -module.exports = Graph; - -var DEFAULT_EDGE_NAME = "\x00", - GRAPH_NODE = "\x00", - EDGE_KEY_DELIM = "\x01"; - -// Implementation notes: -// -// * Node id query functions should return string ids for the nodes -// * Edge id query functions should return an "edgeObj", edge object, that is -// composed of enough information to uniquely identify an edge: {v, w, name}. -// * Internally we use an "edgeId", a stringified form of the edgeObj, to -// reference edges. This is because we need a performant way to look these -// edges up and, object properties, which have string keys, are the closest -// we're going to get to a performant hashtable in JavaScript. - -function Graph(opts) { - this._isDirected = _.has(opts, "directed") ? opts.directed : true; - this._isMultigraph = _.has(opts, "multigraph") ? opts.multigraph : false; - this._isCompound = _.has(opts, "compound") ? opts.compound : false; - - // Label for the graph itself - this._label = undefined; - - // Defaults to be set when creating a new node - this._defaultNodeLabelFn = _.constant(undefined); - - // Defaults to be set when creating a new edge - this._defaultEdgeLabelFn = _.constant(undefined); - - // v -> label - this._nodes = {}; - - if (this._isCompound) { - // v -> parent - this._parent = {}; - - // v -> children - this._children = {}; - this._children[GRAPH_NODE] = {}; - } - - // v -> edgeObj - this._in = {}; - - // u -> v -> Number - this._preds = {}; - - // v -> edgeObj - this._out = {}; - - // v -> w -> Number - this._sucs = {}; - - // e -> edgeObj - this._edgeObjs = {}; - - // e -> label - this._edgeLabels = {}; -} - -/* Number of nodes in the graph. Should only be changed by the implementation. */ -Graph.prototype._nodeCount = 0; - -/* Number of edges in the graph. Should only be changed by the implementation. */ -Graph.prototype._edgeCount = 0; - - -/* === Graph functions ========= */ - -Graph.prototype.isDirected = function() { - return this._isDirected; -}; - -Graph.prototype.isMultigraph = function() { - return this._isMultigraph; -}; - -Graph.prototype.isCompound = function() { - return this._isCompound; -}; - -Graph.prototype.setGraph = function(label) { - this._label = label; - return this; -}; - -Graph.prototype.graph = function() { - return this._label; -}; - - -/* === Node functions ========== */ - -Graph.prototype.setDefaultNodeLabel = function(newDefault) { - if (!_.isFunction(newDefault)) { - newDefault = _.constant(newDefault); - } - this._defaultNodeLabelFn = newDefault; - return this; -}; - -Graph.prototype.nodeCount = function() { - return this._nodeCount; -}; - -Graph.prototype.nodes = function() { - return _.keys(this._nodes); -}; - -Graph.prototype.sources = function() { - return _.filter(this.nodes(), function(v) { - return _.isEmpty(this._in[v]); - }, this); -}; - -Graph.prototype.sinks = function() { - return _.filter(this.nodes(), function(v) { - return _.isEmpty(this._out[v]); - }, this); -}; - -Graph.prototype.setNodes = function(vs, value) { - var args = arguments; - _.each(vs, function(v) { - if (args.length > 1) { - this.setNode(v, value); - } else { - this.setNode(v); - } - }, this); - return this; -}; - -Graph.prototype.setNode = function(v, value) { - if (_.has(this._nodes, v)) { - if (arguments.length > 1) { - this._nodes[v] = value; - } - return this; - } - - this._nodes[v] = arguments.length > 1 ? value : this._defaultNodeLabelFn(v); - if (this._isCompound) { - this._parent[v] = GRAPH_NODE; - this._children[v] = {}; - this._children[GRAPH_NODE][v] = true; - } - this._in[v] = {}; - this._preds[v] = {}; - this._out[v] = {}; - this._sucs[v] = {}; - ++this._nodeCount; - return this; -}; - -Graph.prototype.node = function(v) { - return this._nodes[v]; -}; - -Graph.prototype.hasNode = function(v) { - return _.has(this._nodes, v); -}; - -Graph.prototype.removeNode = function(v) { - var self = this; - if (_.has(this._nodes, v)) { - var removeEdge = function(e) { self.removeEdge(self._edgeObjs[e]); }; - delete this._nodes[v]; - if (this._isCompound) { - this._removeFromParentsChildList(v); - delete this._parent[v]; - _.each(this.children(v), function(child) { - this.setParent(child); - }, this); - delete this._children[v]; - } - _.each(_.keys(this._in[v]), removeEdge); - delete this._in[v]; - delete this._preds[v]; - _.each(_.keys(this._out[v]), removeEdge); - delete this._out[v]; - delete this._sucs[v]; - --this._nodeCount; - } - return this; -}; - -Graph.prototype.setParent = function(v, parent) { - if (!this._isCompound) { - throw new Error("Cannot set parent in a non-compound graph"); - } - - if (_.isUndefined(parent)) { - parent = GRAPH_NODE; - } else { - // Coerce parent to string - parent += ""; - for (var ancestor = parent; - !_.isUndefined(ancestor); - ancestor = this.parent(ancestor)) { - if (ancestor === v) { - throw new Error("Setting " + parent+ " as parent of " + v + - " would create create a cycle"); - } - } - - this.setNode(parent); - } - - this.setNode(v); - this._removeFromParentsChildList(v); - this._parent[v] = parent; - this._children[parent][v] = true; - return this; -}; - -Graph.prototype._removeFromParentsChildList = function(v) { - delete this._children[this._parent[v]][v]; -}; - -Graph.prototype.parent = function(v) { - if (this._isCompound) { - var parent = this._parent[v]; - if (parent !== GRAPH_NODE) { - return parent; - } - } -}; - -Graph.prototype.children = function(v) { - if (_.isUndefined(v)) { - v = GRAPH_NODE; - } - - if (this._isCompound) { - var children = this._children[v]; - if (children) { - return _.keys(children); - } - } else if (v === GRAPH_NODE) { - return this.nodes(); - } else if (this.hasNode(v)) { - return []; - } -}; - -Graph.prototype.predecessors = function(v) { - var predsV = this._preds[v]; - if (predsV) { - return _.keys(predsV); - } -}; - -Graph.prototype.successors = function(v) { - var sucsV = this._sucs[v]; - if (sucsV) { - return _.keys(sucsV); - } -}; - -Graph.prototype.neighbors = function(v) { - var preds = this.predecessors(v); - if (preds) { - return _.union(preds, this.successors(v)); - } -}; - -Graph.prototype.filterNodes = function(filter) { - var copy = new this.constructor({ - directed: this._isDirected, - multigraph: this._isMultigraph, - compound: this._isCompound - }); - - copy.setGraph(this.graph()); - - _.each(this._nodes, function(value, v) { - if (filter(v)) { - copy.setNode(v, value); - } - }, this); - - _.each(this._edgeObjs, function(e) { - if (copy.hasNode(e.v) && copy.hasNode(e.w)) { - copy.setEdge(e, this.edge(e)); - } - }, this); - - var self = this; - var parents = {}; - function findParent(v) { - var parent = self.parent(v); - if (parent === undefined || copy.hasNode(parent)) { - parents[v] = parent; - return parent; - } else if (parent in parents) { - return parents[parent]; - } else { - return findParent(parent); - } - } - - if (this._isCompound) { - _.each(copy.nodes(), function(v) { - copy.setParent(v, findParent(v)); - }); - } - - return copy; -}; - -/* === Edge functions ========== */ - -Graph.prototype.setDefaultEdgeLabel = function(newDefault) { - if (!_.isFunction(newDefault)) { - newDefault = _.constant(newDefault); - } - this._defaultEdgeLabelFn = newDefault; - return this; -}; - -Graph.prototype.edgeCount = function() { - return this._edgeCount; -}; - -Graph.prototype.edges = function() { - return _.values(this._edgeObjs); -}; - -Graph.prototype.setPath = function(vs, value) { - var self = this, - args = arguments; - _.reduce(vs, function(v, w) { - if (args.length > 1) { - self.setEdge(v, w, value); - } else { - self.setEdge(v, w); - } - return w; - }); - return this; -}; - -/* - * setEdge(v, w, [value, [name]]) - * setEdge({ v, w, [name] }, [value]) - */ -Graph.prototype.setEdge = function() { - var v, w, name, value, - valueSpecified = false, - arg0 = arguments[0]; - - if (typeof arg0 === "object" && arg0 !== null && "v" in arg0) { - v = arg0.v; - w = arg0.w; - name = arg0.name; - if (arguments.length === 2) { - value = arguments[1]; - valueSpecified = true; - } - } else { - v = arg0; - w = arguments[1]; - name = arguments[3]; - if (arguments.length > 2) { - value = arguments[2]; - valueSpecified = true; - } - } - - v = "" + v; - w = "" + w; - if (!_.isUndefined(name)) { - name = "" + name; - } - - var e = edgeArgsToId(this._isDirected, v, w, name); - if (_.has(this._edgeLabels, e)) { - if (valueSpecified) { - this._edgeLabels[e] = value; - } - return this; - } - - if (!_.isUndefined(name) && !this._isMultigraph) { - throw new Error("Cannot set a named edge when isMultigraph = false"); - } - - // It didn't exist, so we need to create it. - // First ensure the nodes exist. - this.setNode(v); - this.setNode(w); - - this._edgeLabels[e] = valueSpecified ? value : this._defaultEdgeLabelFn(v, w, name); - - var edgeObj = edgeArgsToObj(this._isDirected, v, w, name); - // Ensure we add undirected edges in a consistent way. - v = edgeObj.v; - w = edgeObj.w; - - Object.freeze(edgeObj); - this._edgeObjs[e] = edgeObj; - incrementOrInitEntry(this._preds[w], v); - incrementOrInitEntry(this._sucs[v], w); - this._in[w][e] = edgeObj; - this._out[v][e] = edgeObj; - this._edgeCount++; - return this; -}; - -Graph.prototype.edge = function(v, w, name) { - var e = (arguments.length === 1 - ? edgeObjToId(this._isDirected, arguments[0]) - : edgeArgsToId(this._isDirected, v, w, name)); - return this._edgeLabels[e]; -}; - -Graph.prototype.hasEdge = function(v, w, name) { - var e = (arguments.length === 1 - ? edgeObjToId(this._isDirected, arguments[0]) - : edgeArgsToId(this._isDirected, v, w, name)); - return _.has(this._edgeLabels, e); -}; - -Graph.prototype.removeEdge = function(v, w, name) { - var e = (arguments.length === 1 - ? edgeObjToId(this._isDirected, arguments[0]) - : edgeArgsToId(this._isDirected, v, w, name)), - edge = this._edgeObjs[e]; - if (edge) { - v = edge.v; - w = edge.w; - delete this._edgeLabels[e]; - delete this._edgeObjs[e]; - decrementOrRemoveEntry(this._preds[w], v); - decrementOrRemoveEntry(this._sucs[v], w); - delete this._in[w][e]; - delete this._out[v][e]; - this._edgeCount--; - } - return this; -}; - -Graph.prototype.inEdges = function(v, u) { - var inV = this._in[v]; - if (inV) { - var edges = _.values(inV); - if (!u) { - return edges; - } - return _.filter(edges, function(edge) { return edge.v === u; }); - } -}; - -Graph.prototype.outEdges = function(v, w) { - var outV = this._out[v]; - if (outV) { - var edges = _.values(outV); - if (!w) { - return edges; - } - return _.filter(edges, function(edge) { return edge.w === w; }); - } -}; - -Graph.prototype.nodeEdges = function(v, w) { - var inEdges = this.inEdges(v, w); - if (inEdges) { - return inEdges.concat(this.outEdges(v, w)); - } -}; - -function incrementOrInitEntry(map, k) { - if (map[k]) { - map[k]++; - } else { - map[k] = 1; - } -} - -function decrementOrRemoveEntry(map, k) { - if (!--map[k]) { delete map[k]; } -} - -function edgeArgsToId(isDirected, v_, w_, name) { - var v = "" + v_; - var w = "" + w_; - if (!isDirected && v > w) { - var tmp = v; - v = w; - w = tmp; - } - return v + EDGE_KEY_DELIM + w + EDGE_KEY_DELIM + - (_.isUndefined(name) ? DEFAULT_EDGE_NAME : name); -} - -function edgeArgsToObj(isDirected, v_, w_, name) { - var v = "" + v_; - var w = "" + w_; - if (!isDirected && v > w) { - var tmp = v; - v = w; - w = tmp; - } - var edgeObj = { v: v, w: w }; - if (name) { - edgeObj.name = name; - } - return edgeObj; -} - -function edgeObjToId(isDirected, edgeObj) { - return edgeArgsToId(isDirected, edgeObj.v, edgeObj.w, edgeObj.name); -} - -},{"./lodash":49}],47:[function(require,module,exports){ -// Includes only the "core" of graphlib -module.exports = { - Graph: require("./graph"), - version: require("./version") -}; - -},{"./graph":46,"./version":50}],48:[function(require,module,exports){ -var _ = require("./lodash"), - Graph = require("./graph"); - -module.exports = { - write: write, - read: read -}; - -function write(g) { - var json = { - options: { - directed: g.isDirected(), - multigraph: g.isMultigraph(), - compound: g.isCompound() - }, - nodes: writeNodes(g), - edges: writeEdges(g) - }; - if (!_.isUndefined(g.graph())) { - json.value = _.clone(g.graph()); - } - return json; -} - -function writeNodes(g) { - return _.map(g.nodes(), function(v) { - var nodeValue = g.node(v), - parent = g.parent(v), - node = { v: v }; - if (!_.isUndefined(nodeValue)) { - node.value = nodeValue; - } - if (!_.isUndefined(parent)) { - node.parent = parent; - } - return node; - }); -} - -function writeEdges(g) { - return _.map(g.edges(), function(e) { - var edgeValue = g.edge(e), - edge = { v: e.v, w: e.w }; - if (!_.isUndefined(e.name)) { - edge.name = e.name; - } - if (!_.isUndefined(edgeValue)) { - edge.value = edgeValue; - } - return edge; - }); -} - -function read(json) { - var g = new Graph(json.options).setGraph(json.value); - _.each(json.nodes, function(entry) { - g.setNode(entry.v, entry.value); - if (entry.parent) { - g.setParent(entry.v, entry.parent); - } - }); - _.each(json.edges, function(entry) { - g.setEdge({ v: entry.v, w: entry.w, name: entry.name }, entry.value); - }); - return g; -} - -},{"./graph":46,"./lodash":49}],49:[function(require,module,exports){ -/* global window */ - -var lodash; - -if (typeof require === "function") { - try { - lodash = require("lodash"); - } catch (e) {} -} - -if (!lodash) { - lodash = window._; -} - -module.exports = lodash; - -},{"lodash":51}],50:[function(require,module,exports){ -module.exports = '1.0.7'; - -},{}],51:[function(require,module,exports){ -(function (global){ -/** - * @license - * lodash 3.10.1 (Custom Build) - * Build: `lodash modern -d -o ./index.js` - * Copyright 2012-2015 The Dojo Foundation - * Based on Underscore.js 1.8.3 - * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -;(function() { - - /** Used as a safe reference for `undefined` in pre-ES5 environments. */ - var undefined; - - /** Used as the semantic version number. */ - var VERSION = '3.10.1'; - - /** Used to compose bitmasks for wrapper metadata. */ - var BIND_FLAG = 1, - BIND_KEY_FLAG = 2, - CURRY_BOUND_FLAG = 4, - CURRY_FLAG = 8, - CURRY_RIGHT_FLAG = 16, - PARTIAL_FLAG = 32, - PARTIAL_RIGHT_FLAG = 64, - ARY_FLAG = 128, - REARG_FLAG = 256; - - /** Used as default options for `_.trunc`. */ - var DEFAULT_TRUNC_LENGTH = 30, - DEFAULT_TRUNC_OMISSION = '...'; - - /** Used to detect when a function becomes hot. */ - var HOT_COUNT = 150, - HOT_SPAN = 16; - - /** Used as the size to enable large array optimizations. */ - var LARGE_ARRAY_SIZE = 200; - - /** Used to indicate the type of lazy iteratees. */ - var LAZY_FILTER_FLAG = 1, - LAZY_MAP_FLAG = 2; - - /** Used as the `TypeError` message for "Functions" methods. */ - var FUNC_ERROR_TEXT = 'Expected a function'; - - /** Used as the internal argument placeholder. */ - var PLACEHOLDER = '__lodash_placeholder__'; - - /** `Object#toString` result references. */ - var argsTag = '[object Arguments]', - arrayTag = '[object Array]', - boolTag = '[object Boolean]', - dateTag = '[object Date]', - errorTag = '[object Error]', - funcTag = '[object Function]', - mapTag = '[object Map]', - numberTag = '[object Number]', - objectTag = '[object Object]', - regexpTag = '[object RegExp]', - setTag = '[object Set]', - stringTag = '[object String]', - weakMapTag = '[object WeakMap]'; - - var arrayBufferTag = '[object ArrayBuffer]', - float32Tag = '[object Float32Array]', - float64Tag = '[object Float64Array]', - int8Tag = '[object Int8Array]', - int16Tag = '[object Int16Array]', - int32Tag = '[object Int32Array]', - uint8Tag = '[object Uint8Array]', - uint8ClampedTag = '[object Uint8ClampedArray]', - uint16Tag = '[object Uint16Array]', - uint32Tag = '[object Uint32Array]'; - - /** Used to match empty string literals in compiled template source. */ - var reEmptyStringLeading = /\b__p \+= '';/g, - reEmptyStringMiddle = /\b(__p \+=) '' \+/g, - reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; - - /** Used to match HTML entities and HTML characters. */ - var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g, - reUnescapedHtml = /[&<>"'`]/g, - reHasEscapedHtml = RegExp(reEscapedHtml.source), - reHasUnescapedHtml = RegExp(reUnescapedHtml.source); - - /** Used to match template delimiters. */ - var reEscape = /<%-([\s\S]+?)%>/g, - reEvaluate = /<%([\s\S]+?)%>/g, - reInterpolate = /<%=([\s\S]+?)%>/g; - - /** Used to match property names within property paths. */ - var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/, - reIsPlainProp = /^\w*$/, - rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g; - - /** - * Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns) - * and those outlined by [`EscapeRegExpPattern`](http://ecma-international.org/ecma-262/6.0/#sec-escaperegexppattern). - */ - var reRegExpChars = /^[:!,]|[\\^$.*+?()[\]{}|\/]|(^[0-9a-fA-Fnrtuvx])|([\n\r\u2028\u2029])/g, - reHasRegExpChars = RegExp(reRegExpChars.source); - - /** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). */ - var reComboMark = /[\u0300-\u036f\ufe20-\ufe23]/g; - - /** Used to match backslashes in property paths. */ - var reEscapeChar = /\\(\\)?/g; - - /** Used to match [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). */ - var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; - - /** Used to match `RegExp` flags from their coerced string values. */ - var reFlags = /\w*$/; - - /** Used to detect hexadecimal string values. */ - var reHasHexPrefix = /^0[xX]/; - - /** Used to detect host constructors (Safari > 5). */ - var reIsHostCtor = /^\[object .+?Constructor\]$/; - - /** Used to detect unsigned integer values. */ - var reIsUint = /^\d+$/; - - /** Used to match latin-1 supplementary letters (excluding mathematical operators). */ - var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g; - - /** Used to ensure capturing order of template delimiters. */ - var reNoMatch = /($^)/; - - /** Used to match unescaped characters in compiled string literals. */ - var reUnescapedString = /['\n\r\u2028\u2029\\]/g; - - /** Used to match words to create compound words. */ - var reWords = (function() { - var upper = '[A-Z\\xc0-\\xd6\\xd8-\\xde]', - lower = '[a-z\\xdf-\\xf6\\xf8-\\xff]+'; - - return RegExp(upper + '+(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|[0-9]+', 'g'); - }()); - - /** Used to assign default `context` object properties. */ - var contextProps = [ - 'Array', 'ArrayBuffer', 'Date', 'Error', 'Float32Array', 'Float64Array', - 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Math', 'Number', - 'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'isFinite', - 'parseFloat', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array', - 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap' - ]; - - /** Used to make template sourceURLs easier to identify. */ - var templateCounter = -1; - - /** Used to identify `toStringTag` values of typed arrays. */ - var typedArrayTags = {}; - typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = - typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = - typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = - typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = - typedArrayTags[uint32Tag] = true; - typedArrayTags[argsTag] = typedArrayTags[arrayTag] = - typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = - typedArrayTags[dateTag] = typedArrayTags[errorTag] = - typedArrayTags[funcTag] = typedArrayTags[mapTag] = - typedArrayTags[numberTag] = typedArrayTags[objectTag] = - typedArrayTags[regexpTag] = typedArrayTags[setTag] = - typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; - - /** Used to identify `toStringTag` values supported by `_.clone`. */ - var cloneableTags = {}; - cloneableTags[argsTag] = cloneableTags[arrayTag] = - cloneableTags[arrayBufferTag] = cloneableTags[boolTag] = - cloneableTags[dateTag] = cloneableTags[float32Tag] = - cloneableTags[float64Tag] = cloneableTags[int8Tag] = - cloneableTags[int16Tag] = cloneableTags[int32Tag] = - cloneableTags[numberTag] = cloneableTags[objectTag] = - cloneableTags[regexpTag] = cloneableTags[stringTag] = - cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = - cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; - cloneableTags[errorTag] = cloneableTags[funcTag] = - cloneableTags[mapTag] = cloneableTags[setTag] = - cloneableTags[weakMapTag] = false; - - /** Used to map latin-1 supplementary letters to basic latin letters. */ - var deburredLetters = { - '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', - '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', - '\xc7': 'C', '\xe7': 'c', - '\xd0': 'D', '\xf0': 'd', - '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', - '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', - '\xcC': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', - '\xeC': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', - '\xd1': 'N', '\xf1': 'n', - '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', - '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', - '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', - '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', - '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', - '\xc6': 'Ae', '\xe6': 'ae', - '\xde': 'Th', '\xfe': 'th', - '\xdf': 'ss' - }; - - /** Used to map characters to HTML entities. */ - var htmlEscapes = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - '`': '`' - }; - - /** Used to map HTML entities to characters. */ - var htmlUnescapes = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - ''': "'", - '`': '`' - }; - - /** Used to determine if values are of the language type `Object`. */ - var objectTypes = { - 'function': true, - 'object': true - }; - - /** Used to escape characters for inclusion in compiled regexes. */ - var regexpEscapes = { - '0': 'x30', '1': 'x31', '2': 'x32', '3': 'x33', '4': 'x34', - '5': 'x35', '6': 'x36', '7': 'x37', '8': 'x38', '9': 'x39', - 'A': 'x41', 'B': 'x42', 'C': 'x43', 'D': 'x44', 'E': 'x45', 'F': 'x46', - 'a': 'x61', 'b': 'x62', 'c': 'x63', 'd': 'x64', 'e': 'x65', 'f': 'x66', - 'n': 'x6e', 'r': 'x72', 't': 'x74', 'u': 'x75', 'v': 'x76', 'x': 'x78' - }; - - /** Used to escape characters for inclusion in compiled string literals. */ - var stringEscapes = { - '\\': '\\', - "'": "'", - '\n': 'n', - '\r': 'r', - '\u2028': 'u2028', - '\u2029': 'u2029' - }; - - /** Detect free variable `exports`. */ - var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; - - /** Detect free variable `module`. */ - var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; - - /** Detect free variable `global` from Node.js. */ - var freeGlobal = freeExports && freeModule && typeof global == 'object' && global && global.Object && global; - - /** Detect free variable `self`. */ - var freeSelf = objectTypes[typeof self] && self && self.Object && self; - - /** Detect free variable `window`. */ - var freeWindow = objectTypes[typeof window] && window && window.Object && window; - - /** Detect the popular CommonJS extension `module.exports`. */ - var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; - - /** - * Used as a reference to the global object. - * - * The `this` value is used if it's the global object to avoid Greasemonkey's - * restricted `window` object, otherwise the `window` object is used. - */ - var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this; - - /*--------------------------------------------------------------------------*/ - - /** - * The base implementation of `compareAscending` which compares values and - * sorts them in ascending order without guaranteeing a stable sort. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {number} Returns the sort order indicator for `value`. - */ - function baseCompareAscending(value, other) { - if (value !== other) { - var valIsNull = value === null, - valIsUndef = value === undefined, - valIsReflexive = value === value; - - var othIsNull = other === null, - othIsUndef = other === undefined, - othIsReflexive = other === other; - - if ((value > other && !othIsNull) || !valIsReflexive || - (valIsNull && !othIsUndef && othIsReflexive) || - (valIsUndef && othIsReflexive)) { - return 1; - } - if ((value < other && !valIsNull) || !othIsReflexive || - (othIsNull && !valIsUndef && valIsReflexive) || - (othIsUndef && valIsReflexive)) { - return -1; - } - } - return 0; - } - - /** - * The base implementation of `_.findIndex` and `_.findLastIndex` without - * support for callback shorthands and `this` binding. - * - * @private - * @param {Array} array The array to search. - * @param {Function} predicate The function invoked per iteration. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function baseFindIndex(array, predicate, fromRight) { - var length = array.length, - index = fromRight ? length : -1; - - while ((fromRight ? index-- : ++index < length)) { - if (predicate(array[index], index, array)) { - return index; - } - } - return -1; - } - - /** - * The base implementation of `_.indexOf` without support for binary searches. - * - * @private - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function baseIndexOf(array, value, fromIndex) { - if (value !== value) { - return indexOfNaN(array, fromIndex); - } - var index = fromIndex - 1, - length = array.length; - - while (++index < length) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * The base implementation of `_.isFunction` without support for environments - * with incorrect `typeof` results. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - */ - function baseIsFunction(value) { - // Avoid a Chakra JIT bug in compatibility modes of IE 11. - // See https://github.com/jashkenas/underscore/issues/1621 for more details. - return typeof value == 'function' || false; - } - - /** - * Converts `value` to a string if it's not one. An empty string is returned - * for `null` or `undefined` values. - * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. - */ - function baseToString(value) { - return value == null ? '' : (value + ''); - } - - /** - * Used by `_.trim` and `_.trimLeft` to get the index of the first character - * of `string` that is not found in `chars`. - * - * @private - * @param {string} string The string to inspect. - * @param {string} chars The characters to find. - * @returns {number} Returns the index of the first character not found in `chars`. - */ - function charsLeftIndex(string, chars) { - var index = -1, - length = string.length; - - while (++index < length && chars.indexOf(string.charAt(index)) > -1) {} - return index; - } - - /** - * Used by `_.trim` and `_.trimRight` to get the index of the last character - * of `string` that is not found in `chars`. - * - * @private - * @param {string} string The string to inspect. - * @param {string} chars The characters to find. - * @returns {number} Returns the index of the last character not found in `chars`. - */ - function charsRightIndex(string, chars) { - var index = string.length; - - while (index-- && chars.indexOf(string.charAt(index)) > -1) {} - return index; - } - - /** - * Used by `_.sortBy` to compare transformed elements of a collection and stable - * sort them in ascending order. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @returns {number} Returns the sort order indicator for `object`. - */ - function compareAscending(object, other) { - return baseCompareAscending(object.criteria, other.criteria) || (object.index - other.index); - } - - /** - * Used by `_.sortByOrder` to compare multiple properties of a value to another - * and stable sort them. - * - * If `orders` is unspecified, all valuess are sorted in ascending order. Otherwise, - * a value is sorted in ascending order if its corresponding order is "asc", and - * descending if "desc". - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {boolean[]} orders The order to sort by for each property. - * @returns {number} Returns the sort order indicator for `object`. - */ - function compareMultiple(object, other, orders) { - var index = -1, - objCriteria = object.criteria, - othCriteria = other.criteria, - length = objCriteria.length, - ordersLength = orders.length; - - while (++index < length) { - var result = baseCompareAscending(objCriteria[index], othCriteria[index]); - if (result) { - if (index >= ordersLength) { - return result; - } - var order = orders[index]; - return result * ((order === 'asc' || order === true) ? 1 : -1); - } - } - // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications - // that causes it, under certain circumstances, to provide the same value for - // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 - // for more details. - // - // This also ensures a stable sort in V8 and other engines. - // See https://code.google.com/p/v8/issues/detail?id=90 for more details. - return object.index - other.index; - } - - /** - * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters. - * - * @private - * @param {string} letter The matched letter to deburr. - * @returns {string} Returns the deburred letter. - */ - function deburrLetter(letter) { - return deburredLetters[letter]; - } - - /** - * Used by `_.escape` to convert characters to HTML entities. - * - * @private - * @param {string} chr The matched character to escape. - * @returns {string} Returns the escaped character. - */ - function escapeHtmlChar(chr) { - return htmlEscapes[chr]; - } - - /** - * Used by `_.escapeRegExp` to escape characters for inclusion in compiled regexes. - * - * @private - * @param {string} chr The matched character to escape. - * @param {string} leadingChar The capture group for a leading character. - * @param {string} whitespaceChar The capture group for a whitespace character. - * @returns {string} Returns the escaped character. - */ - function escapeRegExpChar(chr, leadingChar, whitespaceChar) { - if (leadingChar) { - chr = regexpEscapes[chr]; - } else if (whitespaceChar) { - chr = stringEscapes[chr]; - } - return '\\' + chr; - } - - /** - * Used by `_.template` to escape characters for inclusion in compiled string literals. - * - * @private - * @param {string} chr The matched character to escape. - * @returns {string} Returns the escaped character. - */ - function escapeStringChar(chr) { - return '\\' + stringEscapes[chr]; - } - - /** - * Gets the index at which the first occurrence of `NaN` is found in `array`. - * - * @private - * @param {Array} array The array to search. - * @param {number} fromIndex The index to search from. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {number} Returns the index of the matched `NaN`, else `-1`. - */ - function indexOfNaN(array, fromIndex, fromRight) { - var length = array.length, - index = fromIndex + (fromRight ? 0 : -1); - - while ((fromRight ? index-- : ++index < length)) { - var other = array[index]; - if (other !== other) { - return index; - } - } - return -1; - } - - /** - * Checks if `value` is object-like. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - */ - function isObjectLike(value) { - return !!value && typeof value == 'object'; - } - - /** - * Used by `trimmedLeftIndex` and `trimmedRightIndex` to determine if a - * character code is whitespace. - * - * @private - * @param {number} charCode The character code to inspect. - * @returns {boolean} Returns `true` if `charCode` is whitespace, else `false`. - */ - function isSpace(charCode) { - return ((charCode <= 160 && (charCode >= 9 && charCode <= 13) || charCode == 32 || charCode == 160) || charCode == 5760 || charCode == 6158 || - (charCode >= 8192 && (charCode <= 8202 || charCode == 8232 || charCode == 8233 || charCode == 8239 || charCode == 8287 || charCode == 12288 || charCode == 65279))); - } - - /** - * Replaces all `placeholder` elements in `array` with an internal placeholder - * and returns an array of their indexes. - * - * @private - * @param {Array} array The array to modify. - * @param {*} placeholder The placeholder to replace. - * @returns {Array} Returns the new array of placeholder indexes. - */ - function replaceHolders(array, placeholder) { - var index = -1, - length = array.length, - resIndex = -1, - result = []; - - while (++index < length) { - if (array[index] === placeholder) { - array[index] = PLACEHOLDER; - result[++resIndex] = index; - } - } - return result; - } - - /** - * An implementation of `_.uniq` optimized for sorted arrays without support - * for callback shorthands and `this` binding. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} [iteratee] The function invoked per iteration. - * @returns {Array} Returns the new duplicate-value-free array. - */ - function sortedUniq(array, iteratee) { - var seen, - index = -1, - length = array.length, - resIndex = -1, - result = []; - - while (++index < length) { - var value = array[index], - computed = iteratee ? iteratee(value, index, array) : value; - - if (!index || seen !== computed) { - seen = computed; - result[++resIndex] = value; - } - } - return result; - } - - /** - * Used by `_.trim` and `_.trimLeft` to get the index of the first non-whitespace - * character of `string`. - * - * @private - * @param {string} string The string to inspect. - * @returns {number} Returns the index of the first non-whitespace character. - */ - function trimmedLeftIndex(string) { - var index = -1, - length = string.length; - - while (++index < length && isSpace(string.charCodeAt(index))) {} - return index; - } - - /** - * Used by `_.trim` and `_.trimRight` to get the index of the last non-whitespace - * character of `string`. - * - * @private - * @param {string} string The string to inspect. - * @returns {number} Returns the index of the last non-whitespace character. - */ - function trimmedRightIndex(string) { - var index = string.length; - - while (index-- && isSpace(string.charCodeAt(index))) {} - return index; - } - - /** - * Used by `_.unescape` to convert HTML entities to characters. - * - * @private - * @param {string} chr The matched character to unescape. - * @returns {string} Returns the unescaped character. - */ - function unescapeHtmlChar(chr) { - return htmlUnescapes[chr]; - } - - /*--------------------------------------------------------------------------*/ - - /** - * Create a new pristine `lodash` function using the given `context` object. - * - * @static - * @memberOf _ - * @category Utility - * @param {Object} [context=root] The context object. - * @returns {Function} Returns a new `lodash` function. - * @example - * - * _.mixin({ 'foo': _.constant('foo') }); - * - * var lodash = _.runInContext(); - * lodash.mixin({ 'bar': lodash.constant('bar') }); - * - * _.isFunction(_.foo); - * // => true - * _.isFunction(_.bar); - * // => false - * - * lodash.isFunction(lodash.foo); - * // => false - * lodash.isFunction(lodash.bar); - * // => true - * - * // using `context` to mock `Date#getTime` use in `_.now` - * var mock = _.runInContext({ - * 'Date': function() { - * return { 'getTime': getTimeMock }; - * } - * }); - * - * // or creating a suped-up `defer` in Node.js - * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; - */ - function runInContext(context) { - // Avoid issues with some ES3 environments that attempt to use values, named - // after built-in constructors like `Object`, for the creation of literals. - // ES5 clears this up by stating that literals must use built-in constructors. - // See https://es5.github.io/#x11.1.5 for more details. - context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; - - /** Native constructor references. */ - var Array = context.Array, - Date = context.Date, - Error = context.Error, - Function = context.Function, - Math = context.Math, - Number = context.Number, - Object = context.Object, - RegExp = context.RegExp, - String = context.String, - TypeError = context.TypeError; - - /** Used for native method references. */ - var arrayProto = Array.prototype, - objectProto = Object.prototype, - stringProto = String.prototype; - - /** Used to resolve the decompiled source of functions. */ - var fnToString = Function.prototype.toString; - - /** Used to check objects for own properties. */ - var hasOwnProperty = objectProto.hasOwnProperty; - - /** Used to generate unique IDs. */ - var idCounter = 0; - - /** - * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) - * of values. - */ - var objToString = objectProto.toString; - - /** Used to restore the original `_` reference in `_.noConflict`. */ - var oldDash = root._; - - /** Used to detect if a method is native. */ - var reIsNative = RegExp('^' + - fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' - ); - - /** Native method references. */ - var ArrayBuffer = context.ArrayBuffer, - clearTimeout = context.clearTimeout, - parseFloat = context.parseFloat, - pow = Math.pow, - propertyIsEnumerable = objectProto.propertyIsEnumerable, - Set = getNative(context, 'Set'), - setTimeout = context.setTimeout, - splice = arrayProto.splice, - Uint8Array = context.Uint8Array, - WeakMap = getNative(context, 'WeakMap'); - - /* Native method references for those with the same name as other `lodash` methods. */ - var nativeCeil = Math.ceil, - nativeCreate = getNative(Object, 'create'), - nativeFloor = Math.floor, - nativeIsArray = getNative(Array, 'isArray'), - nativeIsFinite = context.isFinite, - nativeKeys = getNative(Object, 'keys'), - nativeMax = Math.max, - nativeMin = Math.min, - nativeNow = getNative(Date, 'now'), - nativeParseInt = context.parseInt, - nativeRandom = Math.random; - - /** Used as references for `-Infinity` and `Infinity`. */ - var NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY, - POSITIVE_INFINITY = Number.POSITIVE_INFINITY; - - /** Used as references for the maximum length and index of an array. */ - var MAX_ARRAY_LENGTH = 4294967295, - MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, - HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; - - /** - * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) - * of an array-like value. - */ - var MAX_SAFE_INTEGER = 9007199254740991; - - /** Used to store function metadata. */ - var metaMap = WeakMap && new WeakMap; - - /** Used to lookup unminified function names. */ - var realNames = {}; - - /*------------------------------------------------------------------------*/ - - /** - * Creates a `lodash` object which wraps `value` to enable implicit chaining. - * Methods that operate on and return arrays, collections, and functions can - * be chained together. Methods that retrieve a single value or may return a - * primitive value will automatically end the chain returning the unwrapped - * value. Explicit chaining may be enabled using `_.chain`. The execution of - * chained methods is lazy, that is, execution is deferred until `_#value` - * is implicitly or explicitly called. - * - * Lazy evaluation allows several methods to support shortcut fusion. Shortcut - * fusion is an optimization strategy which merge iteratee calls; this can help - * to avoid the creation of intermediate data structures and greatly reduce the - * number of iteratee executions. - * - * Chaining is supported in custom builds as long as the `_#value` method is - * directly or indirectly included in the build. - * - * In addition to lodash methods, wrappers have `Array` and `String` methods. - * - * The wrapper `Array` methods are: - * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, - * `splice`, and `unshift` - * - * The wrapper `String` methods are: - * `replace` and `split` - * - * The wrapper methods that support shortcut fusion are: - * `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`, - * `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`, - * `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`, - * and `where` - * - * The chainable wrapper methods are: - * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`, - * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`, - * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defaultsDeep`, - * `defer`, `delay`, `difference`, `drop`, `dropRight`, `dropRightWhile`, - * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`, - * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, - * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, - * `invoke`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, - * `matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`, - * `modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`, - * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`, - * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`, - * `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`, - * `sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`, - * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`, - * `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`, - * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWith` - * - * The wrapper methods that are **not** chainable by default are: - * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`, - * `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, - * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, - * `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`, - * `inRange`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, - * `isEmpty`, `isEqual`, `isError`, `isFinite` `isFunction`, `isMatch`, - * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`, - * `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`, - * `last`, `lastIndexOf`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`, - * `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`, - * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`, - * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`, - * `startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`, - * `unescape`, `uniqueId`, `value`, and `words` - * - * The wrapper method `sample` will return a wrapped value when `n` is provided, - * otherwise an unwrapped value is returned. - * - * @name _ - * @constructor - * @category Chain - * @param {*} value The value to wrap in a `lodash` instance. - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var wrapped = _([1, 2, 3]); - * - * // returns an unwrapped value - * wrapped.reduce(function(total, n) { - * return total + n; - * }); - * // => 6 - * - * // returns a wrapped value - * var squares = wrapped.map(function(n) { - * return n * n; - * }); - * - * _.isArray(squares); - * // => false - * - * _.isArray(squares.value()); - * // => true - */ - function lodash(value) { - if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { - if (value instanceof LodashWrapper) { - return value; - } - if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) { - return wrapperClone(value); - } - } - return new LodashWrapper(value); - } - - /** - * The function whose prototype all chaining wrappers inherit from. - * - * @private - */ - function baseLodash() { - // No operation performed. - } - - /** - * The base constructor for creating `lodash` wrapper objects. - * - * @private - * @param {*} value The value to wrap. - * @param {boolean} [chainAll] Enable chaining for all wrapper methods. - * @param {Array} [actions=[]] Actions to peform to resolve the unwrapped value. - */ - function LodashWrapper(value, chainAll, actions) { - this.__wrapped__ = value; - this.__actions__ = actions || []; - this.__chain__ = !!chainAll; - } - - /** - * An object environment feature flags. - * - * @static - * @memberOf _ - * @type Object - */ - var support = lodash.support = {}; - - /** - * By default, the template delimiters used by lodash are like those in - * embedded Ruby (ERB). Change the following template settings to use - * alternative delimiters. - * - * @static - * @memberOf _ - * @type Object - */ - lodash.templateSettings = { - - /** - * Used to detect `data` property values to be HTML-escaped. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'escape': reEscape, - - /** - * Used to detect code to be evaluated. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'evaluate': reEvaluate, - - /** - * Used to detect `data` property values to inject. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'interpolate': reInterpolate, - - /** - * Used to reference the data object in the template text. - * - * @memberOf _.templateSettings - * @type string - */ - 'variable': '', - - /** - * Used to import variables into the compiled template. - * - * @memberOf _.templateSettings - * @type Object - */ - 'imports': { - - /** - * A reference to the `lodash` function. - * - * @memberOf _.templateSettings.imports - * @type Function - */ - '_': lodash - } - }; - - /*------------------------------------------------------------------------*/ - - /** - * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. - * - * @private - * @param {*} value The value to wrap. - */ - function LazyWrapper(value) { - this.__wrapped__ = value; - this.__actions__ = []; - this.__dir__ = 1; - this.__filtered__ = false; - this.__iteratees__ = []; - this.__takeCount__ = POSITIVE_INFINITY; - this.__views__ = []; - } - - /** - * Creates a clone of the lazy wrapper object. - * - * @private - * @name clone - * @memberOf LazyWrapper - * @returns {Object} Returns the cloned `LazyWrapper` object. - */ - function lazyClone() { - var result = new LazyWrapper(this.__wrapped__); - result.__actions__ = arrayCopy(this.__actions__); - result.__dir__ = this.__dir__; - result.__filtered__ = this.__filtered__; - result.__iteratees__ = arrayCopy(this.__iteratees__); - result.__takeCount__ = this.__takeCount__; - result.__views__ = arrayCopy(this.__views__); - return result; - } - - /** - * Reverses the direction of lazy iteration. - * - * @private - * @name reverse - * @memberOf LazyWrapper - * @returns {Object} Returns the new reversed `LazyWrapper` object. - */ - function lazyReverse() { - if (this.__filtered__) { - var result = new LazyWrapper(this); - result.__dir__ = -1; - result.__filtered__ = true; - } else { - result = this.clone(); - result.__dir__ *= -1; - } - return result; - } - - /** - * Extracts the unwrapped value from its lazy wrapper. - * - * @private - * @name value - * @memberOf LazyWrapper - * @returns {*} Returns the unwrapped value. - */ - function lazyValue() { - var array = this.__wrapped__.value(), - dir = this.__dir__, - isArr = isArray(array), - isRight = dir < 0, - arrLength = isArr ? array.length : 0, - view = getView(0, arrLength, this.__views__), - start = view.start, - end = view.end, - length = end - start, - index = isRight ? end : (start - 1), - iteratees = this.__iteratees__, - iterLength = iteratees.length, - resIndex = 0, - takeCount = nativeMin(length, this.__takeCount__); - - if (!isArr || arrLength < LARGE_ARRAY_SIZE || (arrLength == length && takeCount == length)) { - return baseWrapperValue((isRight && isArr) ? array.reverse() : array, this.__actions__); - } - var result = []; - - outer: - while (length-- && resIndex < takeCount) { - index += dir; - - var iterIndex = -1, - value = array[index]; - - while (++iterIndex < iterLength) { - var data = iteratees[iterIndex], - iteratee = data.iteratee, - type = data.type, - computed = iteratee(value); - - if (type == LAZY_MAP_FLAG) { - value = computed; - } else if (!computed) { - if (type == LAZY_FILTER_FLAG) { - continue outer; - } else { - break outer; - } - } - } - result[resIndex++] = value; - } - return result; - } - - /*------------------------------------------------------------------------*/ - - /** - * Creates a cache object to store key/value pairs. - * - * @private - * @static - * @name Cache - * @memberOf _.memoize - */ - function MapCache() { - this.__data__ = {}; - } - - /** - * Removes `key` and its value from the cache. - * - * @private - * @name delete - * @memberOf _.memoize.Cache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed successfully, else `false`. - */ - function mapDelete(key) { - return this.has(key) && delete this.__data__[key]; - } - - /** - * Gets the cached value for `key`. - * - * @private - * @name get - * @memberOf _.memoize.Cache - * @param {string} key The key of the value to get. - * @returns {*} Returns the cached value. - */ - function mapGet(key) { - return key == '__proto__' ? undefined : this.__data__[key]; - } - - /** - * Checks if a cached value for `key` exists. - * - * @private - * @name has - * @memberOf _.memoize.Cache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function mapHas(key) { - return key != '__proto__' && hasOwnProperty.call(this.__data__, key); - } - - /** - * Sets `value` to `key` of the cache. - * - * @private - * @name set - * @memberOf _.memoize.Cache - * @param {string} key The key of the value to cache. - * @param {*} value The value to cache. - * @returns {Object} Returns the cache object. - */ - function mapSet(key, value) { - if (key != '__proto__') { - this.__data__[key] = value; - } - return this; - } - - /*------------------------------------------------------------------------*/ - - /** - * - * Creates a cache object to store unique values. - * - * @private - * @param {Array} [values] The values to cache. - */ - function SetCache(values) { - var length = values ? values.length : 0; - - this.data = { 'hash': nativeCreate(null), 'set': new Set }; - while (length--) { - this.push(values[length]); - } - } - - /** - * Checks if `value` is in `cache` mimicking the return signature of - * `_.indexOf` by returning `0` if the value is found, else `-1`. - * - * @private - * @param {Object} cache The cache to search. - * @param {*} value The value to search for. - * @returns {number} Returns `0` if `value` is found, else `-1`. - */ - function cacheIndexOf(cache, value) { - var data = cache.data, - result = (typeof value == 'string' || isObject(value)) ? data.set.has(value) : data.hash[value]; - - return result ? 0 : -1; - } - - /** - * Adds `value` to the cache. - * - * @private - * @name push - * @memberOf SetCache - * @param {*} value The value to cache. - */ - function cachePush(value) { - var data = this.data; - if (typeof value == 'string' || isObject(value)) { - data.set.add(value); - } else { - data.hash[value] = true; - } - } - - /*------------------------------------------------------------------------*/ - - /** - * Creates a new array joining `array` with `other`. - * - * @private - * @param {Array} array The array to join. - * @param {Array} other The other array to join. - * @returns {Array} Returns the new concatenated array. - */ - function arrayConcat(array, other) { - var index = -1, - length = array.length, - othIndex = -1, - othLength = other.length, - result = Array(length + othLength); - - while (++index < length) { - result[index] = array[index]; - } - while (++othIndex < othLength) { - result[index++] = other[othIndex]; - } - return result; - } - - /** - * Copies the values of `source` to `array`. - * - * @private - * @param {Array} source The array to copy values from. - * @param {Array} [array=[]] The array to copy values to. - * @returns {Array} Returns `array`. - */ - function arrayCopy(source, array) { - var index = -1, - length = source.length; - - array || (array = Array(length)); - while (++index < length) { - array[index] = source[index]; - } - return array; - } - - /** - * A specialized version of `_.forEach` for arrays without support for callback - * shorthands and `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns `array`. - */ - function arrayEach(array, iteratee) { - var index = -1, - length = array.length; - - while (++index < length) { - if (iteratee(array[index], index, array) === false) { - break; - } - } - return array; - } - - /** - * A specialized version of `_.forEachRight` for arrays without support for - * callback shorthands and `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns `array`. - */ - function arrayEachRight(array, iteratee) { - var length = array.length; - - while (length--) { - if (iteratee(array[length], length, array) === false) { - break; - } - } - return array; - } - - /** - * A specialized version of `_.every` for arrays without support for callback - * shorthands and `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if all elements pass the predicate check, - * else `false`. - */ - function arrayEvery(array, predicate) { - var index = -1, - length = array.length; - - while (++index < length) { - if (!predicate(array[index], index, array)) { - return false; - } - } - return true; - } - - /** - * A specialized version of `baseExtremum` for arrays which invokes `iteratee` - * with one argument: (value). - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {Function} comparator The function used to compare values. - * @param {*} exValue The initial extremum value. - * @returns {*} Returns the extremum value. - */ - function arrayExtremum(array, iteratee, comparator, exValue) { - var index = -1, - length = array.length, - computed = exValue, - result = computed; - - while (++index < length) { - var value = array[index], - current = +iteratee(value); - - if (comparator(current, computed)) { - computed = current; - result = value; - } - } - return result; - } - - /** - * A specialized version of `_.filter` for arrays without support for callback - * shorthands and `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - */ - function arrayFilter(array, predicate) { - var index = -1, - length = array.length, - resIndex = -1, - result = []; - - while (++index < length) { - var value = array[index]; - if (predicate(value, index, array)) { - result[++resIndex] = value; - } - } - return result; - } - - /** - * A specialized version of `_.map` for arrays without support for callback - * shorthands and `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ - function arrayMap(array, iteratee) { - var index = -1, - length = array.length, - result = Array(length); - - while (++index < length) { - result[index] = iteratee(array[index], index, array); - } - return result; - } - - /** - * Appends the elements of `values` to `array`. - * - * @private - * @param {Array} array The array to modify. - * @param {Array} values The values to append. - * @returns {Array} Returns `array`. - */ - function arrayPush(array, values) { - var index = -1, - length = values.length, - offset = array.length; - - while (++index < length) { - array[offset + index] = values[index]; - } - return array; - } - - /** - * A specialized version of `_.reduce` for arrays without support for callback - * shorthands and `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @param {boolean} [initFromArray] Specify using the first element of `array` - * as the initial value. - * @returns {*} Returns the accumulated value. - */ - function arrayReduce(array, iteratee, accumulator, initFromArray) { - var index = -1, - length = array.length; - - if (initFromArray && length) { - accumulator = array[++index]; - } - while (++index < length) { - accumulator = iteratee(accumulator, array[index], index, array); - } - return accumulator; - } - - /** - * A specialized version of `_.reduceRight` for arrays without support for - * callback shorthands and `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @param {boolean} [initFromArray] Specify using the last element of `array` - * as the initial value. - * @returns {*} Returns the accumulated value. - */ - function arrayReduceRight(array, iteratee, accumulator, initFromArray) { - var length = array.length; - if (initFromArray && length) { - accumulator = array[--length]; - } - while (length--) { - accumulator = iteratee(accumulator, array[length], length, array); - } - return accumulator; - } - - /** - * A specialized version of `_.some` for arrays without support for callback - * shorthands and `this` binding. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. - */ - function arraySome(array, predicate) { - var index = -1, - length = array.length; - - while (++index < length) { - if (predicate(array[index], index, array)) { - return true; - } - } - return false; - } - - /** - * A specialized version of `_.sum` for arrays without support for callback - * shorthands and `this` binding.. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {number} Returns the sum. - */ - function arraySum(array, iteratee) { - var length = array.length, - result = 0; - - while (length--) { - result += +iteratee(array[length]) || 0; - } - return result; - } - - /** - * Used by `_.defaults` to customize its `_.assign` use. - * - * @private - * @param {*} objectValue The destination object property value. - * @param {*} sourceValue The source object property value. - * @returns {*} Returns the value to assign to the destination object. - */ - function assignDefaults(objectValue, sourceValue) { - return objectValue === undefined ? sourceValue : objectValue; - } - - /** - * Used by `_.template` to customize its `_.assign` use. - * - * **Note:** This function is like `assignDefaults` except that it ignores - * inherited property values when checking if a property is `undefined`. - * - * @private - * @param {*} objectValue The destination object property value. - * @param {*} sourceValue The source object property value. - * @param {string} key The key associated with the object and source values. - * @param {Object} object The destination object. - * @returns {*} Returns the value to assign to the destination object. - */ - function assignOwnDefaults(objectValue, sourceValue, key, object) { - return (objectValue === undefined || !hasOwnProperty.call(object, key)) - ? sourceValue - : objectValue; - } - - /** - * A specialized version of `_.assign` for customizing assigned values without - * support for argument juggling, multiple sources, and `this` binding `customizer` - * functions. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {Function} customizer The function to customize assigned values. - * @returns {Object} Returns `object`. - */ - function assignWith(object, source, customizer) { - var index = -1, - props = keys(source), - length = props.length; - - while (++index < length) { - var key = props[index], - value = object[key], - result = customizer(value, source[key], key, object, source); - - if ((result === result ? (result !== value) : (value === value)) || - (value === undefined && !(key in object))) { - object[key] = result; - } - } - return object; - } - - /** - * The base implementation of `_.assign` without support for argument juggling, - * multiple sources, and `customizer` functions. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @returns {Object} Returns `object`. - */ - function baseAssign(object, source) { - return source == null - ? object - : baseCopy(source, keys(source), object); - } - - /** - * The base implementation of `_.at` without support for string collections - * and individual key arguments. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {number[]|string[]} props The property names or indexes of elements to pick. - * @returns {Array} Returns the new array of picked elements. - */ - function baseAt(collection, props) { - var index = -1, - isNil = collection == null, - isArr = !isNil && isArrayLike(collection), - length = isArr ? collection.length : 0, - propsLength = props.length, - result = Array(propsLength); - - while(++index < propsLength) { - var key = props[index]; - if (isArr) { - result[index] = isIndex(key, length) ? collection[key] : undefined; - } else { - result[index] = isNil ? undefined : collection[key]; - } - } - return result; - } - - /** - * Copies properties of `source` to `object`. - * - * @private - * @param {Object} source The object to copy properties from. - * @param {Array} props The property names to copy. - * @param {Object} [object={}] The object to copy properties to. - * @returns {Object} Returns `object`. - */ - function baseCopy(source, props, object) { - object || (object = {}); - - var index = -1, - length = props.length; - - while (++index < length) { - var key = props[index]; - object[key] = source[key]; - } - return object; - } - - /** - * The base implementation of `_.callback` which supports specifying the - * number of arguments to provide to `func`. - * - * @private - * @param {*} [func=_.identity] The value to convert to a callback. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {number} [argCount] The number of arguments to provide to `func`. - * @returns {Function} Returns the callback. - */ - function baseCallback(func, thisArg, argCount) { - var type = typeof func; - if (type == 'function') { - return thisArg === undefined - ? func - : bindCallback(func, thisArg, argCount); - } - if (func == null) { - return identity; - } - if (type == 'object') { - return baseMatches(func); - } - return thisArg === undefined - ? property(func) - : baseMatchesProperty(func, thisArg); - } - - /** - * The base implementation of `_.clone` without support for argument juggling - * and `this` binding `customizer` functions. - * - * @private - * @param {*} value The value to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @param {Function} [customizer] The function to customize cloning values. - * @param {string} [key] The key of `value`. - * @param {Object} [object] The object `value` belongs to. - * @param {Array} [stackA=[]] Tracks traversed source objects. - * @param {Array} [stackB=[]] Associates clones with source counterparts. - * @returns {*} Returns the cloned value. - */ - function baseClone(value, isDeep, customizer, key, object, stackA, stackB) { - var result; - if (customizer) { - result = object ? customizer(value, key, object) : customizer(value); - } - if (result !== undefined) { - return result; - } - if (!isObject(value)) { - return value; - } - var isArr = isArray(value); - if (isArr) { - result = initCloneArray(value); - if (!isDeep) { - return arrayCopy(value, result); - } - } else { - var tag = objToString.call(value), - isFunc = tag == funcTag; - - if (tag == objectTag || tag == argsTag || (isFunc && !object)) { - result = initCloneObject(isFunc ? {} : value); - if (!isDeep) { - return baseAssign(result, value); - } - } else { - return cloneableTags[tag] - ? initCloneByTag(value, tag, isDeep) - : (object ? value : {}); - } - } - // Check for circular references and return its corresponding clone. - stackA || (stackA = []); - stackB || (stackB = []); - - var length = stackA.length; - while (length--) { - if (stackA[length] == value) { - return stackB[length]; - } - } - // Add the source value to the stack of traversed objects and associate it with its clone. - stackA.push(value); - stackB.push(result); - - // Recursively populate clone (susceptible to call stack limits). - (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) { - result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB); - }); - return result; - } - - /** - * The base implementation of `_.create` without support for assigning - * properties to the created object. - * - * @private - * @param {Object} prototype The object to inherit from. - * @returns {Object} Returns the new object. - */ - var baseCreate = (function() { - function object() {} - return function(prototype) { - if (isObject(prototype)) { - object.prototype = prototype; - var result = new object; - object.prototype = undefined; - } - return result || {}; - }; - }()); - - /** - * The base implementation of `_.delay` and `_.defer` which accepts an index - * of where to slice the arguments to provide to `func`. - * - * @private - * @param {Function} func The function to delay. - * @param {number} wait The number of milliseconds to delay invocation. - * @param {Object} args The arguments provide to `func`. - * @returns {number} Returns the timer id. - */ - function baseDelay(func, wait, args) { - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - return setTimeout(function() { func.apply(undefined, args); }, wait); - } - - /** - * The base implementation of `_.difference` which accepts a single array - * of values to exclude. - * - * @private - * @param {Array} array The array to inspect. - * @param {Array} values The values to exclude. - * @returns {Array} Returns the new array of filtered values. - */ - function baseDifference(array, values) { - var length = array ? array.length : 0, - result = []; - - if (!length) { - return result; - } - var index = -1, - indexOf = getIndexOf(), - isCommon = indexOf == baseIndexOf, - cache = (isCommon && values.length >= LARGE_ARRAY_SIZE) ? createCache(values) : null, - valuesLength = values.length; - - if (cache) { - indexOf = cacheIndexOf; - isCommon = false; - values = cache; - } - outer: - while (++index < length) { - var value = array[index]; - - if (isCommon && value === value) { - var valuesIndex = valuesLength; - while (valuesIndex--) { - if (values[valuesIndex] === value) { - continue outer; - } - } - result.push(value); - } - else if (indexOf(values, value, 0) < 0) { - result.push(value); - } - } - return result; - } - - /** - * The base implementation of `_.forEach` without support for callback - * shorthands and `this` binding. - * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array|Object|string} Returns `collection`. - */ - var baseEach = createBaseEach(baseForOwn); - - /** - * The base implementation of `_.forEachRight` without support for callback - * shorthands and `this` binding. - * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array|Object|string} Returns `collection`. - */ - var baseEachRight = createBaseEach(baseForOwnRight, true); - - /** - * The base implementation of `_.every` without support for callback - * shorthands and `this` binding. - * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if all elements pass the predicate check, - * else `false` - */ - function baseEvery(collection, predicate) { - var result = true; - baseEach(collection, function(value, index, collection) { - result = !!predicate(value, index, collection); - return result; - }); - return result; - } - - /** - * Gets the extremum value of `collection` invoking `iteratee` for each value - * in `collection` to generate the criterion by which the value is ranked. - * The `iteratee` is invoked with three arguments: (value, index|key, collection). - * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {Function} comparator The function used to compare values. - * @param {*} exValue The initial extremum value. - * @returns {*} Returns the extremum value. - */ - function baseExtremum(collection, iteratee, comparator, exValue) { - var computed = exValue, - result = computed; - - baseEach(collection, function(value, index, collection) { - var current = +iteratee(value, index, collection); - if (comparator(current, computed) || (current === exValue && current === result)) { - computed = current; - result = value; - } - }); - return result; - } - - /** - * The base implementation of `_.fill` without an iteratee call guard. - * - * @private - * @param {Array} array The array to fill. - * @param {*} value The value to fill `array` with. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns `array`. - */ - function baseFill(array, value, start, end) { - var length = array.length; - - start = start == null ? 0 : (+start || 0); - if (start < 0) { - start = -start > length ? 0 : (length + start); - } - end = (end === undefined || end > length) ? length : (+end || 0); - if (end < 0) { - end += length; - } - length = start > end ? 0 : (end >>> 0); - start >>>= 0; - - while (start < length) { - array[start++] = value; - } - return array; - } - - /** - * The base implementation of `_.filter` without support for callback - * shorthands and `this` binding. - * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - */ - function baseFilter(collection, predicate) { - var result = []; - baseEach(collection, function(value, index, collection) { - if (predicate(value, index, collection)) { - result.push(value); - } - }); - return result; - } - - /** - * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.findLastKey`, - * without support for callback shorthands and `this` binding, which iterates - * over `collection` using the provided `eachFunc`. - * - * @private - * @param {Array|Object|string} collection The collection to search. - * @param {Function} predicate The function invoked per iteration. - * @param {Function} eachFunc The function to iterate over `collection`. - * @param {boolean} [retKey] Specify returning the key of the found element - * instead of the element itself. - * @returns {*} Returns the found element or its key, else `undefined`. - */ - function baseFind(collection, predicate, eachFunc, retKey) { - var result; - eachFunc(collection, function(value, key, collection) { - if (predicate(value, key, collection)) { - result = retKey ? key : value; - return false; - } - }); - return result; - } - - /** - * The base implementation of `_.flatten` with added support for restricting - * flattening and specifying the start index. - * - * @private - * @param {Array} array The array to flatten. - * @param {boolean} [isDeep] Specify a deep flatten. - * @param {boolean} [isStrict] Restrict flattening to arrays-like objects. - * @param {Array} [result=[]] The initial result value. - * @returns {Array} Returns the new flattened array. - */ - function baseFlatten(array, isDeep, isStrict, result) { - result || (result = []); - - var index = -1, - length = array.length; - - while (++index < length) { - var value = array[index]; - if (isObjectLike(value) && isArrayLike(value) && - (isStrict || isArray(value) || isArguments(value))) { - if (isDeep) { - // Recursively flatten arrays (susceptible to call stack limits). - baseFlatten(value, isDeep, isStrict, result); - } else { - arrayPush(result, value); - } - } else if (!isStrict) { - result[result.length] = value; - } - } - return result; - } - - /** - * The base implementation of `baseForIn` and `baseForOwn` which iterates - * over `object` properties returned by `keysFunc` invoking `iteratee` for - * each property. Iteratee functions may exit iteration early by explicitly - * returning `false`. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {Function} keysFunc The function to get the keys of `object`. - * @returns {Object} Returns `object`. - */ - var baseFor = createBaseFor(); - - /** - * This function is like `baseFor` except that it iterates over properties - * in the opposite order. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {Function} keysFunc The function to get the keys of `object`. - * @returns {Object} Returns `object`. - */ - var baseForRight = createBaseFor(true); - - /** - * The base implementation of `_.forIn` without support for callback - * shorthands and `this` binding. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Object} Returns `object`. - */ - function baseForIn(object, iteratee) { - return baseFor(object, iteratee, keysIn); - } - - /** - * The base implementation of `_.forOwn` without support for callback - * shorthands and `this` binding. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Object} Returns `object`. - */ - function baseForOwn(object, iteratee) { - return baseFor(object, iteratee, keys); - } - - /** - * The base implementation of `_.forOwnRight` without support for callback - * shorthands and `this` binding. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Object} Returns `object`. - */ - function baseForOwnRight(object, iteratee) { - return baseForRight(object, iteratee, keys); - } - - /** - * The base implementation of `_.functions` which creates an array of - * `object` function property names filtered from those provided. - * - * @private - * @param {Object} object The object to inspect. - * @param {Array} props The property names to filter. - * @returns {Array} Returns the new array of filtered property names. - */ - function baseFunctions(object, props) { - var index = -1, - length = props.length, - resIndex = -1, - result = []; - - while (++index < length) { - var key = props[index]; - if (isFunction(object[key])) { - result[++resIndex] = key; - } - } - return result; - } - - /** - * The base implementation of `get` without support for string paths - * and default values. - * - * @private - * @param {Object} object The object to query. - * @param {Array} path The path of the property to get. - * @param {string} [pathKey] The key representation of path. - * @returns {*} Returns the resolved value. - */ - function baseGet(object, path, pathKey) { - if (object == null) { - return; - } - if (pathKey !== undefined && pathKey in toObject(object)) { - path = [pathKey]; - } - var index = 0, - length = path.length; - - while (object != null && index < length) { - object = object[path[index++]]; - } - return (index && index == length) ? object : undefined; - } - - /** - * The base implementation of `_.isEqual` without support for `this` binding - * `customizer` functions. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @param {Function} [customizer] The function to customize comparing values. - * @param {boolean} [isLoose] Specify performing partial comparisons. - * @param {Array} [stackA] Tracks traversed `value` objects. - * @param {Array} [stackB] Tracks traversed `other` objects. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - */ - function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) { - if (value === other) { - return true; - } - if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) { - return value !== value && other !== other; - } - return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB); - } - - /** - * A specialized version of `baseIsEqual` for arrays and objects which performs - * deep comparisons and tracks traversed objects enabling objects with circular - * references to be compared. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Function} [customizer] The function to customize comparing objects. - * @param {boolean} [isLoose] Specify performing partial comparisons. - * @param {Array} [stackA=[]] Tracks traversed `value` objects. - * @param {Array} [stackB=[]] Tracks traversed `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) { - var objIsArr = isArray(object), - othIsArr = isArray(other), - objTag = arrayTag, - othTag = arrayTag; - - if (!objIsArr) { - objTag = objToString.call(object); - if (objTag == argsTag) { - objTag = objectTag; - } else if (objTag != objectTag) { - objIsArr = isTypedArray(object); - } - } - if (!othIsArr) { - othTag = objToString.call(other); - if (othTag == argsTag) { - othTag = objectTag; - } else if (othTag != objectTag) { - othIsArr = isTypedArray(other); - } - } - var objIsObj = objTag == objectTag, - othIsObj = othTag == objectTag, - isSameTag = objTag == othTag; - - if (isSameTag && !(objIsArr || objIsObj)) { - return equalByTag(object, other, objTag); - } - if (!isLoose) { - var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), - othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); - - if (objIsWrapped || othIsWrapped) { - return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB); - } - } - if (!isSameTag) { - return false; - } - // Assume cyclic values are equal. - // For more information on detecting circular references see https://es5.github.io/#JO. - stackA || (stackA = []); - stackB || (stackB = []); - - var length = stackA.length; - while (length--) { - if (stackA[length] == object) { - return stackB[length] == other; - } - } - // Add `object` and `other` to the stack of traversed objects. - stackA.push(object); - stackB.push(other); - - var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB); - - stackA.pop(); - stackB.pop(); - - return result; - } - - /** - * The base implementation of `_.isMatch` without support for callback - * shorthands and `this` binding. - * - * @private - * @param {Object} object The object to inspect. - * @param {Array} matchData The propery names, values, and compare flags to match. - * @param {Function} [customizer] The function to customize comparing objects. - * @returns {boolean} Returns `true` if `object` is a match, else `false`. - */ - function baseIsMatch(object, matchData, customizer) { - var index = matchData.length, - length = index, - noCustomizer = !customizer; - - if (object == null) { - return !length; - } - object = toObject(object); - while (index--) { - var data = matchData[index]; - if ((noCustomizer && data[2]) - ? data[1] !== object[data[0]] - : !(data[0] in object) - ) { - return false; - } - } - while (++index < length) { - data = matchData[index]; - var key = data[0], - objValue = object[key], - srcValue = data[1]; - - if (noCustomizer && data[2]) { - if (objValue === undefined && !(key in object)) { - return false; - } - } else { - var result = customizer ? customizer(objValue, srcValue, key) : undefined; - if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) { - return false; - } - } - } - return true; - } - - /** - * The base implementation of `_.map` without support for callback shorthands - * and `this` binding. - * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ - function baseMap(collection, iteratee) { - var index = -1, - result = isArrayLike(collection) ? Array(collection.length) : []; - - baseEach(collection, function(value, key, collection) { - result[++index] = iteratee(value, key, collection); - }); - return result; - } - - /** - * The base implementation of `_.matches` which does not clone `source`. - * - * @private - * @param {Object} source The object of property values to match. - * @returns {Function} Returns the new function. - */ - function baseMatches(source) { - var matchData = getMatchData(source); - if (matchData.length == 1 && matchData[0][2]) { - var key = matchData[0][0], - value = matchData[0][1]; - - return function(object) { - if (object == null) { - return false; - } - return object[key] === value && (value !== undefined || (key in toObject(object))); - }; - } - return function(object) { - return baseIsMatch(object, matchData); - }; - } - - /** - * The base implementation of `_.matchesProperty` which does not clone `srcValue`. - * - * @private - * @param {string} path The path of the property to get. - * @param {*} srcValue The value to compare. - * @returns {Function} Returns the new function. - */ - function baseMatchesProperty(path, srcValue) { - var isArr = isArray(path), - isCommon = isKey(path) && isStrictComparable(srcValue), - pathKey = (path + ''); - - path = toPath(path); - return function(object) { - if (object == null) { - return false; - } - var key = pathKey; - object = toObject(object); - if ((isArr || !isCommon) && !(key in object)) { - object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); - if (object == null) { - return false; - } - key = last(path); - object = toObject(object); - } - return object[key] === srcValue - ? (srcValue !== undefined || (key in object)) - : baseIsEqual(srcValue, object[key], undefined, true); - }; - } - - /** - * The base implementation of `_.merge` without support for argument juggling, - * multiple sources, and `this` binding `customizer` functions. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {Function} [customizer] The function to customize merged values. - * @param {Array} [stackA=[]] Tracks traversed source objects. - * @param {Array} [stackB=[]] Associates values with source counterparts. - * @returns {Object} Returns `object`. - */ - function baseMerge(object, source, customizer, stackA, stackB) { - if (!isObject(object)) { - return object; - } - var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)), - props = isSrcArr ? undefined : keys(source); - - arrayEach(props || source, function(srcValue, key) { - if (props) { - key = srcValue; - srcValue = source[key]; - } - if (isObjectLike(srcValue)) { - stackA || (stackA = []); - stackB || (stackB = []); - baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB); - } - else { - var value = object[key], - result = customizer ? customizer(value, srcValue, key, object, source) : undefined, - isCommon = result === undefined; - - if (isCommon) { - result = srcValue; - } - if ((result !== undefined || (isSrcArr && !(key in object))) && - (isCommon || (result === result ? (result !== value) : (value === value)))) { - object[key] = result; - } - } - }); - return object; - } - - /** - * A specialized version of `baseMerge` for arrays and objects which performs - * deep merges and tracks traversed objects enabling objects with circular - * references to be merged. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {string} key The key of the value to merge. - * @param {Function} mergeFunc The function to merge values. - * @param {Function} [customizer] The function to customize merged values. - * @param {Array} [stackA=[]] Tracks traversed source objects. - * @param {Array} [stackB=[]] Associates values with source counterparts. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) { - var length = stackA.length, - srcValue = source[key]; - - while (length--) { - if (stackA[length] == srcValue) { - object[key] = stackB[length]; - return; - } - } - var value = object[key], - result = customizer ? customizer(value, srcValue, key, object, source) : undefined, - isCommon = result === undefined; - - if (isCommon) { - result = srcValue; - if (isArrayLike(srcValue) && (isArray(srcValue) || isTypedArray(srcValue))) { - result = isArray(value) - ? value - : (isArrayLike(value) ? arrayCopy(value) : []); - } - else if (isPlainObject(srcValue) || isArguments(srcValue)) { - result = isArguments(value) - ? toPlainObject(value) - : (isPlainObject(value) ? value : {}); - } - else { - isCommon = false; - } - } - // Add the source value to the stack of traversed objects and associate - // it with its merged value. - stackA.push(srcValue); - stackB.push(result); - - if (isCommon) { - // Recursively merge objects and arrays (susceptible to call stack limits). - object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB); - } else if (result === result ? (result !== value) : (value === value)) { - object[key] = result; - } - } - - /** - * The base implementation of `_.property` without support for deep paths. - * - * @private - * @param {string} key The key of the property to get. - * @returns {Function} Returns the new function. - */ - function baseProperty(key) { - return function(object) { - return object == null ? undefined : object[key]; - }; - } - - /** - * A specialized version of `baseProperty` which supports deep paths. - * - * @private - * @param {Array|string} path The path of the property to get. - * @returns {Function} Returns the new function. - */ - function basePropertyDeep(path) { - var pathKey = (path + ''); - path = toPath(path); - return function(object) { - return baseGet(object, path, pathKey); - }; - } - - /** - * The base implementation of `_.pullAt` without support for individual - * index arguments and capturing the removed elements. - * - * @private - * @param {Array} array The array to modify. - * @param {number[]} indexes The indexes of elements to remove. - * @returns {Array} Returns `array`. - */ - function basePullAt(array, indexes) { - var length = array ? indexes.length : 0; - while (length--) { - var index = indexes[length]; - if (index != previous && isIndex(index)) { - var previous = index; - splice.call(array, index, 1); - } - } - return array; - } - - /** - * The base implementation of `_.random` without support for argument juggling - * and returning floating-point numbers. - * - * @private - * @param {number} min The minimum possible value. - * @param {number} max The maximum possible value. - * @returns {number} Returns the random number. - */ - function baseRandom(min, max) { - return min + nativeFloor(nativeRandom() * (max - min + 1)); - } - - /** - * The base implementation of `_.reduce` and `_.reduceRight` without support - * for callback shorthands and `this` binding, which iterates over `collection` - * using the provided `eachFunc`. - * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} accumulator The initial value. - * @param {boolean} initFromCollection Specify using the first or last element - * of `collection` as the initial value. - * @param {Function} eachFunc The function to iterate over `collection`. - * @returns {*} Returns the accumulated value. - */ - function baseReduce(collection, iteratee, accumulator, initFromCollection, eachFunc) { - eachFunc(collection, function(value, index, collection) { - accumulator = initFromCollection - ? (initFromCollection = false, value) - : iteratee(accumulator, value, index, collection); - }); - return accumulator; - } - - /** - * The base implementation of `setData` without support for hot loop detection. - * - * @private - * @param {Function} func The function to associate metadata with. - * @param {*} data The metadata. - * @returns {Function} Returns `func`. - */ - var baseSetData = !metaMap ? identity : function(func, data) { - metaMap.set(func, data); - return func; - }; - - /** - * The base implementation of `_.slice` without an iteratee call guard. - * - * @private - * @param {Array} array The array to slice. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns the slice of `array`. - */ - function baseSlice(array, start, end) { - var index = -1, - length = array.length; - - start = start == null ? 0 : (+start || 0); - if (start < 0) { - start = -start > length ? 0 : (length + start); - } - end = (end === undefined || end > length) ? length : (+end || 0); - if (end < 0) { - end += length; - } - length = start > end ? 0 : ((end - start) >>> 0); - start >>>= 0; - - var result = Array(length); - while (++index < length) { - result[index] = array[index + start]; - } - return result; - } - - /** - * The base implementation of `_.some` without support for callback shorthands - * and `this` binding. - * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. - */ - function baseSome(collection, predicate) { - var result; - - baseEach(collection, function(value, index, collection) { - result = predicate(value, index, collection); - return !result; - }); - return !!result; - } - - /** - * The base implementation of `_.sortBy` which uses `comparer` to define - * the sort order of `array` and replaces criteria objects with their - * corresponding values. - * - * @private - * @param {Array} array The array to sort. - * @param {Function} comparer The function to define sort order. - * @returns {Array} Returns `array`. - */ - function baseSortBy(array, comparer) { - var length = array.length; - - array.sort(comparer); - while (length--) { - array[length] = array[length].value; - } - return array; - } - - /** - * The base implementation of `_.sortByOrder` without param guards. - * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. - * @param {boolean[]} orders The sort orders of `iteratees`. - * @returns {Array} Returns the new sorted array. - */ - function baseSortByOrder(collection, iteratees, orders) { - var callback = getCallback(), - index = -1; - - iteratees = arrayMap(iteratees, function(iteratee) { return callback(iteratee); }); - - var result = baseMap(collection, function(value) { - var criteria = arrayMap(iteratees, function(iteratee) { return iteratee(value); }); - return { 'criteria': criteria, 'index': ++index, 'value': value }; - }); - - return baseSortBy(result, function(object, other) { - return compareMultiple(object, other, orders); - }); - } - - /** - * The base implementation of `_.sum` without support for callback shorthands - * and `this` binding. - * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {number} Returns the sum. - */ - function baseSum(collection, iteratee) { - var result = 0; - baseEach(collection, function(value, index, collection) { - result += +iteratee(value, index, collection) || 0; - }); - return result; - } - - /** - * The base implementation of `_.uniq` without support for callback shorthands - * and `this` binding. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} [iteratee] The function invoked per iteration. - * @returns {Array} Returns the new duplicate-value-free array. - */ - function baseUniq(array, iteratee) { - var index = -1, - indexOf = getIndexOf(), - length = array.length, - isCommon = indexOf == baseIndexOf, - isLarge = isCommon && length >= LARGE_ARRAY_SIZE, - seen = isLarge ? createCache() : null, - result = []; - - if (seen) { - indexOf = cacheIndexOf; - isCommon = false; - } else { - isLarge = false; - seen = iteratee ? [] : result; - } - outer: - while (++index < length) { - var value = array[index], - computed = iteratee ? iteratee(value, index, array) : value; - - if (isCommon && value === value) { - var seenIndex = seen.length; - while (seenIndex--) { - if (seen[seenIndex] === computed) { - continue outer; - } - } - if (iteratee) { - seen.push(computed); - } - result.push(value); - } - else if (indexOf(seen, computed, 0) < 0) { - if (iteratee || isLarge) { - seen.push(computed); - } - result.push(value); - } - } - return result; - } - - /** - * The base implementation of `_.values` and `_.valuesIn` which creates an - * array of `object` property values corresponding to the property names - * of `props`. - * - * @private - * @param {Object} object The object to query. - * @param {Array} props The property names to get values for. - * @returns {Object} Returns the array of property values. - */ - function baseValues(object, props) { - var index = -1, - length = props.length, - result = Array(length); - - while (++index < length) { - result[index] = object[props[index]]; - } - return result; - } - - /** - * The base implementation of `_.dropRightWhile`, `_.dropWhile`, `_.takeRightWhile`, - * and `_.takeWhile` without support for callback shorthands and `this` binding. - * - * @private - * @param {Array} array The array to query. - * @param {Function} predicate The function invoked per iteration. - * @param {boolean} [isDrop] Specify dropping elements instead of taking them. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Array} Returns the slice of `array`. - */ - function baseWhile(array, predicate, isDrop, fromRight) { - var length = array.length, - index = fromRight ? length : -1; - - while ((fromRight ? index-- : ++index < length) && predicate(array[index], index, array)) {} - return isDrop - ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length)) - : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index)); - } - - /** - * The base implementation of `wrapperValue` which returns the result of - * performing a sequence of actions on the unwrapped `value`, where each - * successive action is supplied the return value of the previous. - * - * @private - * @param {*} value The unwrapped value. - * @param {Array} actions Actions to peform to resolve the unwrapped value. - * @returns {*} Returns the resolved value. - */ - function baseWrapperValue(value, actions) { - var result = value; - if (result instanceof LazyWrapper) { - result = result.value(); - } - var index = -1, - length = actions.length; - - while (++index < length) { - var action = actions[index]; - result = action.func.apply(action.thisArg, arrayPush([result], action.args)); - } - return result; - } - - /** - * Performs a binary search of `array` to determine the index at which `value` - * should be inserted into `array` in order to maintain its sort order. - * - * @private - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {boolean} [retHighest] Specify returning the highest qualified index. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - */ - function binaryIndex(array, value, retHighest) { - var low = 0, - high = array ? array.length : low; - - if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { - while (low < high) { - var mid = (low + high) >>> 1, - computed = array[mid]; - - if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) { - low = mid + 1; - } else { - high = mid; - } - } - return high; - } - return binaryIndexBy(array, value, identity, retHighest); - } - - /** - * This function is like `binaryIndex` except that it invokes `iteratee` for - * `value` and each element of `array` to compute their sort ranking. The - * iteratee is invoked with one argument; (value). - * - * @private - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {Function} iteratee The function invoked per iteration. - * @param {boolean} [retHighest] Specify returning the highest qualified index. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - */ - function binaryIndexBy(array, value, iteratee, retHighest) { - value = iteratee(value); - - var low = 0, - high = array ? array.length : 0, - valIsNaN = value !== value, - valIsNull = value === null, - valIsUndef = value === undefined; - - while (low < high) { - var mid = nativeFloor((low + high) / 2), - computed = iteratee(array[mid]), - isDef = computed !== undefined, - isReflexive = computed === computed; - - if (valIsNaN) { - var setLow = isReflexive || retHighest; - } else if (valIsNull) { - setLow = isReflexive && isDef && (retHighest || computed != null); - } else if (valIsUndef) { - setLow = isReflexive && (retHighest || isDef); - } else if (computed == null) { - setLow = false; - } else { - setLow = retHighest ? (computed <= value) : (computed < value); - } - if (setLow) { - low = mid + 1; - } else { - high = mid; - } - } - return nativeMin(high, MAX_ARRAY_INDEX); - } - - /** - * A specialized version of `baseCallback` which only supports `this` binding - * and specifying the number of arguments to provide to `func`. - * - * @private - * @param {Function} func The function to bind. - * @param {*} thisArg The `this` binding of `func`. - * @param {number} [argCount] The number of arguments to provide to `func`. - * @returns {Function} Returns the callback. - */ - function bindCallback(func, thisArg, argCount) { - if (typeof func != 'function') { - return identity; - } - if (thisArg === undefined) { - return func; - } - switch (argCount) { - case 1: return function(value) { - return func.call(thisArg, value); - }; - case 3: return function(value, index, collection) { - return func.call(thisArg, value, index, collection); - }; - case 4: return function(accumulator, value, index, collection) { - return func.call(thisArg, accumulator, value, index, collection); - }; - case 5: return function(value, other, key, object, source) { - return func.call(thisArg, value, other, key, object, source); - }; - } - return function() { - return func.apply(thisArg, arguments); - }; - } - - /** - * Creates a clone of the given array buffer. - * - * @private - * @param {ArrayBuffer} buffer The array buffer to clone. - * @returns {ArrayBuffer} Returns the cloned array buffer. - */ - function bufferClone(buffer) { - var result = new ArrayBuffer(buffer.byteLength), - view = new Uint8Array(result); - - view.set(new Uint8Array(buffer)); - return result; - } - - /** - * Creates an array that is the composition of partially applied arguments, - * placeholders, and provided arguments into a single array of arguments. - * - * @private - * @param {Array|Object} args The provided arguments. - * @param {Array} partials The arguments to prepend to those provided. - * @param {Array} holders The `partials` placeholder indexes. - * @returns {Array} Returns the new array of composed arguments. - */ - function composeArgs(args, partials, holders) { - var holdersLength = holders.length, - argsIndex = -1, - argsLength = nativeMax(args.length - holdersLength, 0), - leftIndex = -1, - leftLength = partials.length, - result = Array(leftLength + argsLength); - - while (++leftIndex < leftLength) { - result[leftIndex] = partials[leftIndex]; - } - while (++argsIndex < holdersLength) { - result[holders[argsIndex]] = args[argsIndex]; - } - while (argsLength--) { - result[leftIndex++] = args[argsIndex++]; - } - return result; - } - - /** - * This function is like `composeArgs` except that the arguments composition - * is tailored for `_.partialRight`. - * - * @private - * @param {Array|Object} args The provided arguments. - * @param {Array} partials The arguments to append to those provided. - * @param {Array} holders The `partials` placeholder indexes. - * @returns {Array} Returns the new array of composed arguments. - */ - function composeArgsRight(args, partials, holders) { - var holdersIndex = -1, - holdersLength = holders.length, - argsIndex = -1, - argsLength = nativeMax(args.length - holdersLength, 0), - rightIndex = -1, - rightLength = partials.length, - result = Array(argsLength + rightLength); - - while (++argsIndex < argsLength) { - result[argsIndex] = args[argsIndex]; - } - var offset = argsIndex; - while (++rightIndex < rightLength) { - result[offset + rightIndex] = partials[rightIndex]; - } - while (++holdersIndex < holdersLength) { - result[offset + holders[holdersIndex]] = args[argsIndex++]; - } - return result; - } - - /** - * Creates a `_.countBy`, `_.groupBy`, `_.indexBy`, or `_.partition` function. - * - * @private - * @param {Function} setter The function to set keys and values of the accumulator object. - * @param {Function} [initializer] The function to initialize the accumulator object. - * @returns {Function} Returns the new aggregator function. - */ - function createAggregator(setter, initializer) { - return function(collection, iteratee, thisArg) { - var result = initializer ? initializer() : {}; - iteratee = getCallback(iteratee, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - setter(result, value, iteratee(value, index, collection), collection); - } - } else { - baseEach(collection, function(value, key, collection) { - setter(result, value, iteratee(value, key, collection), collection); - }); - } - return result; - }; - } - - /** - * Creates a `_.assign`, `_.defaults`, or `_.merge` function. - * - * @private - * @param {Function} assigner The function to assign values. - * @returns {Function} Returns the new assigner function. - */ - function createAssigner(assigner) { - return restParam(function(object, sources) { - var index = -1, - length = object == null ? 0 : sources.length, - customizer = length > 2 ? sources[length - 2] : undefined, - guard = length > 2 ? sources[2] : undefined, - thisArg = length > 1 ? sources[length - 1] : undefined; - - if (typeof customizer == 'function') { - customizer = bindCallback(customizer, thisArg, 5); - length -= 2; - } else { - customizer = typeof thisArg == 'function' ? thisArg : undefined; - length -= (customizer ? 1 : 0); - } - if (guard && isIterateeCall(sources[0], sources[1], guard)) { - customizer = length < 3 ? undefined : customizer; - length = 1; - } - while (++index < length) { - var source = sources[index]; - if (source) { - assigner(object, source, customizer); - } - } - return object; - }); - } - - /** - * Creates a `baseEach` or `baseEachRight` function. - * - * @private - * @param {Function} eachFunc The function to iterate over a collection. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new base function. - */ - function createBaseEach(eachFunc, fromRight) { - return function(collection, iteratee) { - var length = collection ? getLength(collection) : 0; - if (!isLength(length)) { - return eachFunc(collection, iteratee); - } - var index = fromRight ? length : -1, - iterable = toObject(collection); - - while ((fromRight ? index-- : ++index < length)) { - if (iteratee(iterable[index], index, iterable) === false) { - break; - } - } - return collection; - }; - } - - /** - * Creates a base function for `_.forIn` or `_.forInRight`. - * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new base function. - */ - function createBaseFor(fromRight) { - return function(object, iteratee, keysFunc) { - var iterable = toObject(object), - props = keysFunc(object), - length = props.length, - index = fromRight ? length : -1; - - while ((fromRight ? index-- : ++index < length)) { - var key = props[index]; - if (iteratee(iterable[key], key, iterable) === false) { - break; - } - } - return object; - }; - } - - /** - * Creates a function that wraps `func` and invokes it with the `this` - * binding of `thisArg`. - * - * @private - * @param {Function} func The function to bind. - * @param {*} [thisArg] The `this` binding of `func`. - * @returns {Function} Returns the new bound function. - */ - function createBindWrapper(func, thisArg) { - var Ctor = createCtorWrapper(func); - - function wrapper() { - var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; - return fn.apply(thisArg, arguments); - } - return wrapper; - } - - /** - * Creates a `Set` cache object to optimize linear searches of large arrays. - * - * @private - * @param {Array} [values] The values to cache. - * @returns {null|Object} Returns the new cache object if `Set` is supported, else `null`. - */ - function createCache(values) { - return (nativeCreate && Set) ? new SetCache(values) : null; - } - - /** - * Creates a function that produces compound words out of the words in a - * given string. - * - * @private - * @param {Function} callback The function to combine each word. - * @returns {Function} Returns the new compounder function. - */ - function createCompounder(callback) { - return function(string) { - var index = -1, - array = words(deburr(string)), - length = array.length, - result = ''; - - while (++index < length) { - result = callback(result, array[index], index); - } - return result; - }; - } - - /** - * Creates a function that produces an instance of `Ctor` regardless of - * whether it was invoked as part of a `new` expression or by `call` or `apply`. - * - * @private - * @param {Function} Ctor The constructor to wrap. - * @returns {Function} Returns the new wrapped function. - */ - function createCtorWrapper(Ctor) { - return function() { - // Use a `switch` statement to work with class constructors. - // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist - // for more details. - var args = arguments; - switch (args.length) { - case 0: return new Ctor; - case 1: return new Ctor(args[0]); - case 2: return new Ctor(args[0], args[1]); - case 3: return new Ctor(args[0], args[1], args[2]); - case 4: return new Ctor(args[0], args[1], args[2], args[3]); - case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); - case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); - case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); - } - var thisBinding = baseCreate(Ctor.prototype), - result = Ctor.apply(thisBinding, args); - - // Mimic the constructor's `return` behavior. - // See https://es5.github.io/#x13.2.2 for more details. - return isObject(result) ? result : thisBinding; - }; - } - - /** - * Creates a `_.curry` or `_.curryRight` function. - * - * @private - * @param {boolean} flag The curry bit flag. - * @returns {Function} Returns the new curry function. - */ - function createCurry(flag) { - function curryFunc(func, arity, guard) { - if (guard && isIterateeCall(func, arity, guard)) { - arity = undefined; - } - var result = createWrapper(func, flag, undefined, undefined, undefined, undefined, undefined, arity); - result.placeholder = curryFunc.placeholder; - return result; - } - return curryFunc; - } - - /** - * Creates a `_.defaults` or `_.defaultsDeep` function. - * - * @private - * @param {Function} assigner The function to assign values. - * @param {Function} customizer The function to customize assigned values. - * @returns {Function} Returns the new defaults function. - */ - function createDefaults(assigner, customizer) { - return restParam(function(args) { - var object = args[0]; - if (object == null) { - return object; - } - args.push(customizer); - return assigner.apply(undefined, args); - }); - } - - /** - * Creates a `_.max` or `_.min` function. - * - * @private - * @param {Function} comparator The function used to compare values. - * @param {*} exValue The initial extremum value. - * @returns {Function} Returns the new extremum function. - */ - function createExtremum(comparator, exValue) { - return function(collection, iteratee, thisArg) { - if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { - iteratee = undefined; - } - iteratee = getCallback(iteratee, thisArg, 3); - if (iteratee.length == 1) { - collection = isArray(collection) ? collection : toIterable(collection); - var result = arrayExtremum(collection, iteratee, comparator, exValue); - if (!(collection.length && result === exValue)) { - return result; - } - } - return baseExtremum(collection, iteratee, comparator, exValue); - }; - } - - /** - * Creates a `_.find` or `_.findLast` function. - * - * @private - * @param {Function} eachFunc The function to iterate over a collection. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new find function. - */ - function createFind(eachFunc, fromRight) { - return function(collection, predicate, thisArg) { - predicate = getCallback(predicate, thisArg, 3); - if (isArray(collection)) { - var index = baseFindIndex(collection, predicate, fromRight); - return index > -1 ? collection[index] : undefined; - } - return baseFind(collection, predicate, eachFunc); - }; - } - - /** - * Creates a `_.findIndex` or `_.findLastIndex` function. - * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new find function. - */ - function createFindIndex(fromRight) { - return function(array, predicate, thisArg) { - if (!(array && array.length)) { - return -1; - } - predicate = getCallback(predicate, thisArg, 3); - return baseFindIndex(array, predicate, fromRight); - }; - } - - /** - * Creates a `_.findKey` or `_.findLastKey` function. - * - * @private - * @param {Function} objectFunc The function to iterate over an object. - * @returns {Function} Returns the new find function. - */ - function createFindKey(objectFunc) { - return function(object, predicate, thisArg) { - predicate = getCallback(predicate, thisArg, 3); - return baseFind(object, predicate, objectFunc, true); - }; - } - - /** - * Creates a `_.flow` or `_.flowRight` function. - * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new flow function. - */ - function createFlow(fromRight) { - return function() { - var wrapper, - length = arguments.length, - index = fromRight ? length : -1, - leftIndex = 0, - funcs = Array(length); - - while ((fromRight ? index-- : ++index < length)) { - var func = funcs[leftIndex++] = arguments[index]; - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - if (!wrapper && LodashWrapper.prototype.thru && getFuncName(func) == 'wrapper') { - wrapper = new LodashWrapper([], true); - } - } - index = wrapper ? -1 : length; - while (++index < length) { - func = funcs[index]; - - var funcName = getFuncName(func), - data = funcName == 'wrapper' ? getData(func) : undefined; - - if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) { - wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); - } else { - wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func); - } - } - return function() { - var args = arguments, - value = args[0]; - - if (wrapper && args.length == 1 && isArray(value) && value.length >= LARGE_ARRAY_SIZE) { - return wrapper.plant(value).value(); - } - var index = 0, - result = length ? funcs[index].apply(this, args) : value; - - while (++index < length) { - result = funcs[index].call(this, result); - } - return result; - }; - }; - } - - /** - * Creates a function for `_.forEach` or `_.forEachRight`. - * - * @private - * @param {Function} arrayFunc The function to iterate over an array. - * @param {Function} eachFunc The function to iterate over a collection. - * @returns {Function} Returns the new each function. - */ - function createForEach(arrayFunc, eachFunc) { - return function(collection, iteratee, thisArg) { - return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) - ? arrayFunc(collection, iteratee) - : eachFunc(collection, bindCallback(iteratee, thisArg, 3)); - }; - } - - /** - * Creates a function for `_.forIn` or `_.forInRight`. - * - * @private - * @param {Function} objectFunc The function to iterate over an object. - * @returns {Function} Returns the new each function. - */ - function createForIn(objectFunc) { - return function(object, iteratee, thisArg) { - if (typeof iteratee != 'function' || thisArg !== undefined) { - iteratee = bindCallback(iteratee, thisArg, 3); - } - return objectFunc(object, iteratee, keysIn); - }; - } - - /** - * Creates a function for `_.forOwn` or `_.forOwnRight`. - * - * @private - * @param {Function} objectFunc The function to iterate over an object. - * @returns {Function} Returns the new each function. - */ - function createForOwn(objectFunc) { - return function(object, iteratee, thisArg) { - if (typeof iteratee != 'function' || thisArg !== undefined) { - iteratee = bindCallback(iteratee, thisArg, 3); - } - return objectFunc(object, iteratee); - }; - } - - /** - * Creates a function for `_.mapKeys` or `_.mapValues`. - * - * @private - * @param {boolean} [isMapKeys] Specify mapping keys instead of values. - * @returns {Function} Returns the new map function. - */ - function createObjectMapper(isMapKeys) { - return function(object, iteratee, thisArg) { - var result = {}; - iteratee = getCallback(iteratee, thisArg, 3); - - baseForOwn(object, function(value, key, object) { - var mapped = iteratee(value, key, object); - key = isMapKeys ? mapped : key; - value = isMapKeys ? value : mapped; - result[key] = value; - }); - return result; - }; - } - - /** - * Creates a function for `_.padLeft` or `_.padRight`. - * - * @private - * @param {boolean} [fromRight] Specify padding from the right. - * @returns {Function} Returns the new pad function. - */ - function createPadDir(fromRight) { - return function(string, length, chars) { - string = baseToString(string); - return (fromRight ? string : '') + createPadding(string, length, chars) + (fromRight ? '' : string); - }; - } - - /** - * Creates a `_.partial` or `_.partialRight` function. - * - * @private - * @param {boolean} flag The partial bit flag. - * @returns {Function} Returns the new partial function. - */ - function createPartial(flag) { - var partialFunc = restParam(function(func, partials) { - var holders = replaceHolders(partials, partialFunc.placeholder); - return createWrapper(func, flag, undefined, partials, holders); - }); - return partialFunc; - } - - /** - * Creates a function for `_.reduce` or `_.reduceRight`. - * - * @private - * @param {Function} arrayFunc The function to iterate over an array. - * @param {Function} eachFunc The function to iterate over a collection. - * @returns {Function} Returns the new each function. - */ - function createReduce(arrayFunc, eachFunc) { - return function(collection, iteratee, accumulator, thisArg) { - var initFromArray = arguments.length < 3; - return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) - ? arrayFunc(collection, iteratee, accumulator, initFromArray) - : baseReduce(collection, getCallback(iteratee, thisArg, 4), accumulator, initFromArray, eachFunc); - }; - } - - /** - * Creates a function that wraps `func` and invokes it with optional `this` - * binding of, partial application, and currying. - * - * @private - * @param {Function|string} func The function or method name to reference. - * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {Array} [partials] The arguments to prepend to those provided to the new function. - * @param {Array} [holders] The `partials` placeholder indexes. - * @param {Array} [partialsRight] The arguments to append to those provided to the new function. - * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. - * @param {Array} [argPos] The argument positions of the new function. - * @param {number} [ary] The arity cap of `func`. - * @param {number} [arity] The arity of `func`. - * @returns {Function} Returns the new wrapped function. - */ - function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { - var isAry = bitmask & ARY_FLAG, - isBind = bitmask & BIND_FLAG, - isBindKey = bitmask & BIND_KEY_FLAG, - isCurry = bitmask & CURRY_FLAG, - isCurryBound = bitmask & CURRY_BOUND_FLAG, - isCurryRight = bitmask & CURRY_RIGHT_FLAG, - Ctor = isBindKey ? undefined : createCtorWrapper(func); - - function wrapper() { - // Avoid `arguments` object use disqualifying optimizations by - // converting it to an array before providing it to other functions. - var length = arguments.length, - index = length, - args = Array(length); - - while (index--) { - args[index] = arguments[index]; - } - if (partials) { - args = composeArgs(args, partials, holders); - } - if (partialsRight) { - args = composeArgsRight(args, partialsRight, holdersRight); - } - if (isCurry || isCurryRight) { - var placeholder = wrapper.placeholder, - argsHolders = replaceHolders(args, placeholder); - - length -= argsHolders.length; - if (length < arity) { - var newArgPos = argPos ? arrayCopy(argPos) : undefined, - newArity = nativeMax(arity - length, 0), - newsHolders = isCurry ? argsHolders : undefined, - newHoldersRight = isCurry ? undefined : argsHolders, - newPartials = isCurry ? args : undefined, - newPartialsRight = isCurry ? undefined : args; - - bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); - bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); - - if (!isCurryBound) { - bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); - } - var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity], - result = createHybridWrapper.apply(undefined, newData); - - if (isLaziable(func)) { - setData(result, newData); - } - result.placeholder = placeholder; - return result; - } - } - var thisBinding = isBind ? thisArg : this, - fn = isBindKey ? thisBinding[func] : func; - - if (argPos) { - args = reorder(args, argPos); - } - if (isAry && ary < args.length) { - args.length = ary; - } - if (this && this !== root && this instanceof wrapper) { - fn = Ctor || createCtorWrapper(func); - } - return fn.apply(thisBinding, args); - } - return wrapper; - } - - /** - * Creates the padding required for `string` based on the given `length`. - * The `chars` string is truncated if the number of characters exceeds `length`. - * - * @private - * @param {string} string The string to create padding for. - * @param {number} [length=0] The padding length. - * @param {string} [chars=' '] The string used as padding. - * @returns {string} Returns the pad for `string`. - */ - function createPadding(string, length, chars) { - var strLength = string.length; - length = +length; - - if (strLength >= length || !nativeIsFinite(length)) { - return ''; - } - var padLength = length - strLength; - chars = chars == null ? ' ' : (chars + ''); - return repeat(chars, nativeCeil(padLength / chars.length)).slice(0, padLength); - } - - /** - * Creates a function that wraps `func` and invokes it with the optional `this` - * binding of `thisArg` and the `partials` prepended to those provided to - * the wrapper. - * - * @private - * @param {Function} func The function to partially apply arguments to. - * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. - * @param {*} thisArg The `this` binding of `func`. - * @param {Array} partials The arguments to prepend to those provided to the new function. - * @returns {Function} Returns the new bound function. - */ - function createPartialWrapper(func, bitmask, thisArg, partials) { - var isBind = bitmask & BIND_FLAG, - Ctor = createCtorWrapper(func); - - function wrapper() { - // Avoid `arguments` object use disqualifying optimizations by - // converting it to an array before providing it `func`. - var argsIndex = -1, - argsLength = arguments.length, - leftIndex = -1, - leftLength = partials.length, - args = Array(leftLength + argsLength); - - while (++leftIndex < leftLength) { - args[leftIndex] = partials[leftIndex]; - } - while (argsLength--) { - args[leftIndex++] = arguments[++argsIndex]; - } - var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; - return fn.apply(isBind ? thisArg : this, args); - } - return wrapper; - } - - /** - * Creates a `_.ceil`, `_.floor`, or `_.round` function. - * - * @private - * @param {string} methodName The name of the `Math` method to use when rounding. - * @returns {Function} Returns the new round function. - */ - function createRound(methodName) { - var func = Math[methodName]; - return function(number, precision) { - precision = precision === undefined ? 0 : (+precision || 0); - if (precision) { - precision = pow(10, precision); - return func(number * precision) / precision; - } - return func(number); - }; - } - - /** - * Creates a `_.sortedIndex` or `_.sortedLastIndex` function. - * - * @private - * @param {boolean} [retHighest] Specify returning the highest qualified index. - * @returns {Function} Returns the new index function. - */ - function createSortedIndex(retHighest) { - return function(array, value, iteratee, thisArg) { - var callback = getCallback(iteratee); - return (iteratee == null && callback === baseCallback) - ? binaryIndex(array, value, retHighest) - : binaryIndexBy(array, value, callback(iteratee, thisArg, 1), retHighest); - }; - } - - /** - * Creates a function that either curries or invokes `func` with optional - * `this` binding and partially applied arguments. - * - * @private - * @param {Function|string} func The function or method name to reference. - * @param {number} bitmask The bitmask of flags. - * The bitmask may be composed of the following flags: - * 1 - `_.bind` - * 2 - `_.bindKey` - * 4 - `_.curry` or `_.curryRight` of a bound function - * 8 - `_.curry` - * 16 - `_.curryRight` - * 32 - `_.partial` - * 64 - `_.partialRight` - * 128 - `_.rearg` - * 256 - `_.ary` - * @param {*} [thisArg] The `this` binding of `func`. - * @param {Array} [partials] The arguments to be partially applied. - * @param {Array} [holders] The `partials` placeholder indexes. - * @param {Array} [argPos] The argument positions of the new function. - * @param {number} [ary] The arity cap of `func`. - * @param {number} [arity] The arity of `func`. - * @returns {Function} Returns the new wrapped function. - */ - function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { - var isBindKey = bitmask & BIND_KEY_FLAG; - if (!isBindKey && typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - var length = partials ? partials.length : 0; - if (!length) { - bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG); - partials = holders = undefined; - } - length -= (holders ? holders.length : 0); - if (bitmask & PARTIAL_RIGHT_FLAG) { - var partialsRight = partials, - holdersRight = holders; - - partials = holders = undefined; - } - var data = isBindKey ? undefined : getData(func), - newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity]; - - if (data) { - mergeData(newData, data); - bitmask = newData[1]; - arity = newData[9]; - } - newData[9] = arity == null - ? (isBindKey ? 0 : func.length) - : (nativeMax(arity - length, 0) || 0); - - if (bitmask == BIND_FLAG) { - var result = createBindWrapper(newData[0], newData[2]); - } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) { - result = createPartialWrapper.apply(undefined, newData); - } else { - result = createHybridWrapper.apply(undefined, newData); - } - var setter = data ? baseSetData : setData; - return setter(result, newData); - } - - /** - * A specialized version of `baseIsEqualDeep` for arrays with support for - * partial deep comparisons. - * - * @private - * @param {Array} array The array to compare. - * @param {Array} other The other array to compare. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Function} [customizer] The function to customize comparing arrays. - * @param {boolean} [isLoose] Specify performing partial comparisons. - * @param {Array} [stackA] Tracks traversed `value` objects. - * @param {Array} [stackB] Tracks traversed `other` objects. - * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. - */ - function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) { - var index = -1, - arrLength = array.length, - othLength = other.length; - - if (arrLength != othLength && !(isLoose && othLength > arrLength)) { - return false; - } - // Ignore non-index properties. - while (++index < arrLength) { - var arrValue = array[index], - othValue = other[index], - result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined; - - if (result !== undefined) { - if (result) { - continue; - } - return false; - } - // Recursively compare arrays (susceptible to call stack limits). - if (isLoose) { - if (!arraySome(other, function(othValue) { - return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB); - })) { - return false; - } - } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) { - return false; - } - } - return true; - } - - /** - * A specialized version of `baseIsEqualDeep` for comparing objects of - * the same `toStringTag`. - * - * **Note:** This function only supports comparing values with tags of - * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {string} tag The `toStringTag` of the objects to compare. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function equalByTag(object, other, tag) { - switch (tag) { - case boolTag: - case dateTag: - // Coerce dates and booleans to numbers, dates to milliseconds and booleans - // to `1` or `0` treating invalid dates coerced to `NaN` as not equal. - return +object == +other; - - case errorTag: - return object.name == other.name && object.message == other.message; - - case numberTag: - // Treat `NaN` vs. `NaN` as equal. - return (object != +object) - ? other != +other - : object == +other; - - case regexpTag: - case stringTag: - // Coerce regexes to strings and treat strings primitives and string - // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details. - return object == (other + ''); - } - return false; - } - - /** - * A specialized version of `baseIsEqualDeep` for objects with support for - * partial deep comparisons. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Function} [customizer] The function to customize comparing values. - * @param {boolean} [isLoose] Specify performing partial comparisons. - * @param {Array} [stackA] Tracks traversed `value` objects. - * @param {Array} [stackB] Tracks traversed `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) { - var objProps = keys(object), - objLength = objProps.length, - othProps = keys(other), - othLength = othProps.length; - - if (objLength != othLength && !isLoose) { - return false; - } - var index = objLength; - while (index--) { - var key = objProps[index]; - if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) { - return false; - } - } - var skipCtor = isLoose; - while (++index < objLength) { - key = objProps[index]; - var objValue = object[key], - othValue = other[key], - result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined; - - // Recursively compare objects (susceptible to call stack limits). - if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) { - return false; - } - skipCtor || (skipCtor = key == 'constructor'); - } - if (!skipCtor) { - var objCtor = object.constructor, - othCtor = other.constructor; - - // Non `Object` object instances with different constructors are not equal. - if (objCtor != othCtor && - ('constructor' in object && 'constructor' in other) && - !(typeof objCtor == 'function' && objCtor instanceof objCtor && - typeof othCtor == 'function' && othCtor instanceof othCtor)) { - return false; - } - } - return true; - } - - /** - * Gets the appropriate "callback" function. If the `_.callback` method is - * customized this function returns the custom method, otherwise it returns - * the `baseCallback` function. If arguments are provided the chosen function - * is invoked with them and its result is returned. - * - * @private - * @returns {Function} Returns the chosen function or its result. - */ - function getCallback(func, thisArg, argCount) { - var result = lodash.callback || callback; - result = result === callback ? baseCallback : result; - return argCount ? result(func, thisArg, argCount) : result; - } - - /** - * Gets metadata for `func`. - * - * @private - * @param {Function} func The function to query. - * @returns {*} Returns the metadata for `func`. - */ - var getData = !metaMap ? noop : function(func) { - return metaMap.get(func); - }; - - /** - * Gets the name of `func`. - * - * @private - * @param {Function} func The function to query. - * @returns {string} Returns the function name. - */ - function getFuncName(func) { - var result = func.name, - array = realNames[result], - length = array ? array.length : 0; - - while (length--) { - var data = array[length], - otherFunc = data.func; - if (otherFunc == null || otherFunc == func) { - return data.name; - } - } - return result; - } - - /** - * Gets the appropriate "indexOf" function. If the `_.indexOf` method is - * customized this function returns the custom method, otherwise it returns - * the `baseIndexOf` function. If arguments are provided the chosen function - * is invoked with them and its result is returned. - * - * @private - * @returns {Function|number} Returns the chosen function or its result. - */ - function getIndexOf(collection, target, fromIndex) { - var result = lodash.indexOf || indexOf; - result = result === indexOf ? baseIndexOf : result; - return collection ? result(collection, target, fromIndex) : result; - } - - /** - * Gets the "length" property value of `object`. - * - * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) - * that affects Safari on at least iOS 8.1-8.3 ARM64. - * - * @private - * @param {Object} object The object to query. - * @returns {*} Returns the "length" value. - */ - var getLength = baseProperty('length'); - - /** - * Gets the propery names, values, and compare flags of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the match data of `object`. - */ - function getMatchData(object) { - var result = pairs(object), - length = result.length; - - while (length--) { - result[length][2] = isStrictComparable(result[length][1]); - } - return result; - } - - /** - * Gets the native function at `key` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. - */ - function getNative(object, key) { - var value = object == null ? undefined : object[key]; - return isNative(value) ? value : undefined; - } - - /** - * Gets the view, applying any `transforms` to the `start` and `end` positions. - * - * @private - * @param {number} start The start of the view. - * @param {number} end The end of the view. - * @param {Array} transforms The transformations to apply to the view. - * @returns {Object} Returns an object containing the `start` and `end` - * positions of the view. - */ - function getView(start, end, transforms) { - var index = -1, - length = transforms.length; - - while (++index < length) { - var data = transforms[index], - size = data.size; - - switch (data.type) { - case 'drop': start += size; break; - case 'dropRight': end -= size; break; - case 'take': end = nativeMin(end, start + size); break; - case 'takeRight': start = nativeMax(start, end - size); break; - } - } - return { 'start': start, 'end': end }; - } - - /** - * Initializes an array clone. - * - * @private - * @param {Array} array The array to clone. - * @returns {Array} Returns the initialized clone. - */ - function initCloneArray(array) { - var length = array.length, - result = new array.constructor(length); - - // Add array properties assigned by `RegExp#exec`. - if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { - result.index = array.index; - result.input = array.input; - } - return result; - } - - /** - * Initializes an object clone. - * - * @private - * @param {Object} object The object to clone. - * @returns {Object} Returns the initialized clone. - */ - function initCloneObject(object) { - var Ctor = object.constructor; - if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) { - Ctor = Object; - } - return new Ctor; - } - - /** - * Initializes an object clone based on its `toStringTag`. - * - * **Note:** This function only supports cloning values with tags of - * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. - * - * @private - * @param {Object} object The object to clone. - * @param {string} tag The `toStringTag` of the object to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the initialized clone. - */ - function initCloneByTag(object, tag, isDeep) { - var Ctor = object.constructor; - switch (tag) { - case arrayBufferTag: - return bufferClone(object); - - case boolTag: - case dateTag: - return new Ctor(+object); - - case float32Tag: case float64Tag: - case int8Tag: case int16Tag: case int32Tag: - case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: - var buffer = object.buffer; - return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length); - - case numberTag: - case stringTag: - return new Ctor(object); - - case regexpTag: - var result = new Ctor(object.source, reFlags.exec(object)); - result.lastIndex = object.lastIndex; - } - return result; - } - - /** - * Invokes the method at `path` on `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the method to invoke. - * @param {Array} args The arguments to invoke the method with. - * @returns {*} Returns the result of the invoked method. - */ - function invokePath(object, path, args) { - if (object != null && !isKey(path, object)) { - path = toPath(path); - object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); - path = last(path); - } - var func = object == null ? object : object[path]; - return func == null ? undefined : func.apply(object, args); - } - - /** - * Checks if `value` is array-like. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is array-like, else `false`. - */ - function isArrayLike(value) { - return value != null && isLength(getLength(value)); - } - - /** - * Checks if `value` is a valid array-like index. - * - * @private - * @param {*} value The value to check. - * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. - * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. - */ - function isIndex(value, length) { - value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; - length = length == null ? MAX_SAFE_INTEGER : length; - return value > -1 && value % 1 == 0 && value < length; - } - - /** - * Checks if the provided arguments are from an iteratee call. - * - * @private - * @param {*} value The potential iteratee value argument. - * @param {*} index The potential iteratee index or key argument. - * @param {*} object The potential iteratee object argument. - * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`. - */ - function isIterateeCall(value, index, object) { - if (!isObject(object)) { - return false; - } - var type = typeof index; - if (type == 'number' - ? (isArrayLike(object) && isIndex(index, object.length)) - : (type == 'string' && index in object)) { - var other = object[index]; - return value === value ? (value === other) : (other !== other); - } - return false; - } - - /** - * Checks if `value` is a property name and not a property path. - * - * @private - * @param {*} value The value to check. - * @param {Object} [object] The object to query keys on. - * @returns {boolean} Returns `true` if `value` is a property name, else `false`. - */ - function isKey(value, object) { - var type = typeof value; - if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') { - return true; - } - if (isArray(value)) { - return false; - } - var result = !reIsDeepProp.test(value); - return result || (object != null && value in toObject(object)); - } - - /** - * Checks if `func` has a lazy counterpart. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`. - */ - function isLaziable(func) { - var funcName = getFuncName(func); - if (!(funcName in LazyWrapper.prototype)) { - return false; - } - var other = lodash[funcName]; - if (func === other) { - return true; - } - var data = getData(other); - return !!data && func === data[0]; - } - - /** - * Checks if `value` is a valid array-like length. - * - * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. - */ - function isLength(value) { - return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; - } - - /** - * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` if suitable for strict - * equality comparisons, else `false`. - */ - function isStrictComparable(value) { - return value === value && !isObject(value); - } - - /** - * Merges the function metadata of `source` into `data`. - * - * Merging metadata reduces the number of wrappers required to invoke a function. - * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` - * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg` - * augment function arguments, making the order in which they are executed important, - * preventing the merging of metadata. However, we make an exception for a safe - * common case where curried functions have `_.ary` and or `_.rearg` applied. - * - * @private - * @param {Array} data The destination metadata. - * @param {Array} source The source metadata. - * @returns {Array} Returns `data`. - */ - function mergeData(data, source) { - var bitmask = data[1], - srcBitmask = source[1], - newBitmask = bitmask | srcBitmask, - isCommon = newBitmask < ARY_FLAG; - - var isCombo = - (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) || - (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) || - (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG); - - // Exit early if metadata can't be merged. - if (!(isCommon || isCombo)) { - return data; - } - // Use source `thisArg` if available. - if (srcBitmask & BIND_FLAG) { - data[2] = source[2]; - // Set when currying a bound function. - newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG; - } - // Compose partial arguments. - var value = source[3]; - if (value) { - var partials = data[3]; - data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value); - data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]); - } - // Compose partial right arguments. - value = source[5]; - if (value) { - partials = data[5]; - data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value); - data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]); - } - // Use source `argPos` if available. - value = source[7]; - if (value) { - data[7] = arrayCopy(value); - } - // Use source `ary` if it's smaller. - if (srcBitmask & ARY_FLAG) { - data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); - } - // Use source `arity` if one is not provided. - if (data[9] == null) { - data[9] = source[9]; - } - // Use source `func` and merge bitmasks. - data[0] = source[0]; - data[1] = newBitmask; - - return data; - } - - /** - * Used by `_.defaultsDeep` to customize its `_.merge` use. - * - * @private - * @param {*} objectValue The destination object property value. - * @param {*} sourceValue The source object property value. - * @returns {*} Returns the value to assign to the destination object. - */ - function mergeDefaults(objectValue, sourceValue) { - return objectValue === undefined ? sourceValue : merge(objectValue, sourceValue, mergeDefaults); - } - - /** - * A specialized version of `_.pick` which picks `object` properties specified - * by `props`. - * - * @private - * @param {Object} object The source object. - * @param {string[]} props The property names to pick. - * @returns {Object} Returns the new object. - */ - function pickByArray(object, props) { - object = toObject(object); - - var index = -1, - length = props.length, - result = {}; - - while (++index < length) { - var key = props[index]; - if (key in object) { - result[key] = object[key]; - } - } - return result; - } - - /** - * A specialized version of `_.pick` which picks `object` properties `predicate` - * returns truthy for. - * - * @private - * @param {Object} object The source object. - * @param {Function} predicate The function invoked per iteration. - * @returns {Object} Returns the new object. - */ - function pickByCallback(object, predicate) { - var result = {}; - baseForIn(object, function(value, key, object) { - if (predicate(value, key, object)) { - result[key] = value; - } - }); - return result; - } - - /** - * Reorder `array` according to the specified indexes where the element at - * the first index is assigned as the first element, the element at - * the second index is assigned as the second element, and so on. - * - * @private - * @param {Array} array The array to reorder. - * @param {Array} indexes The arranged array indexes. - * @returns {Array} Returns `array`. - */ - function reorder(array, indexes) { - var arrLength = array.length, - length = nativeMin(indexes.length, arrLength), - oldArray = arrayCopy(array); - - while (length--) { - var index = indexes[length]; - array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; - } - return array; - } - - /** - * Sets metadata for `func`. - * - * **Note:** If this function becomes hot, i.e. is invoked a lot in a short - * period of time, it will trip its breaker and transition to an identity function - * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070) - * for more details. - * - * @private - * @param {Function} func The function to associate metadata with. - * @param {*} data The metadata. - * @returns {Function} Returns `func`. - */ - var setData = (function() { - var count = 0, - lastCalled = 0; - - return function(key, value) { - var stamp = now(), - remaining = HOT_SPAN - (stamp - lastCalled); - - lastCalled = stamp; - if (remaining > 0) { - if (++count >= HOT_COUNT) { - return key; - } - } else { - count = 0; - } - return baseSetData(key, value); - }; - }()); - - /** - * A fallback implementation of `Object.keys` which creates an array of the - * own enumerable property names of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ - function shimKeys(object) { - var props = keysIn(object), - propsLength = props.length, - length = propsLength && object.length; - - var allowIndexes = !!length && isLength(length) && - (isArray(object) || isArguments(object)); - - var index = -1, - result = []; - - while (++index < propsLength) { - var key = props[index]; - if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { - result.push(key); - } - } - return result; - } - - /** - * Converts `value` to an array-like object if it's not one. - * - * @private - * @param {*} value The value to process. - * @returns {Array|Object} Returns the array-like object. - */ - function toIterable(value) { - if (value == null) { - return []; - } - if (!isArrayLike(value)) { - return values(value); - } - return isObject(value) ? value : Object(value); - } - - /** - * Converts `value` to an object if it's not one. - * - * @private - * @param {*} value The value to process. - * @returns {Object} Returns the object. - */ - function toObject(value) { - return isObject(value) ? value : Object(value); - } - - /** - * Converts `value` to property path array if it's not one. - * - * @private - * @param {*} value The value to process. - * @returns {Array} Returns the property path array. - */ - function toPath(value) { - if (isArray(value)) { - return value; - } - var result = []; - baseToString(value).replace(rePropName, function(match, number, quote, string) { - result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); - }); - return result; - } - - /** - * Creates a clone of `wrapper`. - * - * @private - * @param {Object} wrapper The wrapper to clone. - * @returns {Object} Returns the cloned wrapper. - */ - function wrapperClone(wrapper) { - return wrapper instanceof LazyWrapper - ? wrapper.clone() - : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__)); - } - - /*------------------------------------------------------------------------*/ - - /** - * Creates an array of elements split into groups the length of `size`. - * If `collection` can't be split evenly, the final chunk will be the remaining - * elements. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to process. - * @param {number} [size=1] The length of each chunk. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {Array} Returns the new array containing chunks. - * @example - * - * _.chunk(['a', 'b', 'c', 'd'], 2); - * // => [['a', 'b'], ['c', 'd']] - * - * _.chunk(['a', 'b', 'c', 'd'], 3); - * // => [['a', 'b', 'c'], ['d']] - */ - function chunk(array, size, guard) { - if (guard ? isIterateeCall(array, size, guard) : size == null) { - size = 1; - } else { - size = nativeMax(nativeFloor(size) || 1, 1); - } - var index = 0, - length = array ? array.length : 0, - resIndex = -1, - result = Array(nativeCeil(length / size)); - - while (index < length) { - result[++resIndex] = baseSlice(array, index, (index += size)); - } - return result; - } - - /** - * Creates an array with all falsey values removed. The values `false`, `null`, - * `0`, `""`, `undefined`, and `NaN` are falsey. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to compact. - * @returns {Array} Returns the new array of filtered values. - * @example - * - * _.compact([0, 1, false, 2, '', 3]); - * // => [1, 2, 3] - */ - function compact(array) { - var index = -1, - length = array ? array.length : 0, - resIndex = -1, - result = []; - - while (++index < length) { - var value = array[index]; - if (value) { - result[++resIndex] = value; - } - } - return result; - } - - /** - * Creates an array of unique `array` values not included in the other - * provided arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to inspect. - * @param {...Array} [values] The arrays of values to exclude. - * @returns {Array} Returns the new array of filtered values. - * @example - * - * _.difference([1, 2, 3], [4, 2]); - * // => [1, 3] - */ - var difference = restParam(function(array, values) { - return (isObjectLike(array) && isArrayLike(array)) - ? baseDifference(array, baseFlatten(values, false, true)) - : []; - }); - - /** - * Creates a slice of `array` with `n` elements dropped from the beginning. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=1] The number of elements to drop. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.drop([1, 2, 3]); - * // => [2, 3] - * - * _.drop([1, 2, 3], 2); - * // => [3] - * - * _.drop([1, 2, 3], 5); - * // => [] - * - * _.drop([1, 2, 3], 0); - * // => [1, 2, 3] - */ - function drop(array, n, guard) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - if (guard ? isIterateeCall(array, n, guard) : n == null) { - n = 1; - } - return baseSlice(array, n < 0 ? 0 : n); - } - - /** - * Creates a slice of `array` with `n` elements dropped from the end. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=1] The number of elements to drop. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.dropRight([1, 2, 3]); - * // => [1, 2] - * - * _.dropRight([1, 2, 3], 2); - * // => [1] - * - * _.dropRight([1, 2, 3], 5); - * // => [] - * - * _.dropRight([1, 2, 3], 0); - * // => [1, 2, 3] - */ - function dropRight(array, n, guard) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - if (guard ? isIterateeCall(array, n, guard) : n == null) { - n = 1; - } - n = length - (+n || 0); - return baseSlice(array, 0, n < 0 ? 0 : n); - } - - /** - * Creates a slice of `array` excluding elements dropped from the end. - * Elements are dropped until `predicate` returns falsey. The predicate is - * bound to `thisArg` and invoked with three arguments: (value, index, array). - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that match the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.dropRightWhile([1, 2, 3], function(n) { - * return n > 1; - * }); - * // => [1] - * - * var users = [ - * { 'user': 'barney', 'active': true }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': false } - * ]; - * - * // using the `_.matches` callback shorthand - * _.pluck(_.dropRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); - * // => ['barney', 'fred'] - * - * // using the `_.matchesProperty` callback shorthand - * _.pluck(_.dropRightWhile(users, 'active', false), 'user'); - * // => ['barney'] - * - * // using the `_.property` callback shorthand - * _.pluck(_.dropRightWhile(users, 'active'), 'user'); - * // => ['barney', 'fred', 'pebbles'] - */ - function dropRightWhile(array, predicate, thisArg) { - return (array && array.length) - ? baseWhile(array, getCallback(predicate, thisArg, 3), true, true) - : []; - } - - /** - * Creates a slice of `array` excluding elements dropped from the beginning. - * Elements are dropped until `predicate` returns falsey. The predicate is - * bound to `thisArg` and invoked with three arguments: (value, index, array). - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.dropWhile([1, 2, 3], function(n) { - * return n < 3; - * }); - * // => [3] - * - * var users = [ - * { 'user': 'barney', 'active': false }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': true } - * ]; - * - * // using the `_.matches` callback shorthand - * _.pluck(_.dropWhile(users, { 'user': 'barney', 'active': false }), 'user'); - * // => ['fred', 'pebbles'] - * - * // using the `_.matchesProperty` callback shorthand - * _.pluck(_.dropWhile(users, 'active', false), 'user'); - * // => ['pebbles'] - * - * // using the `_.property` callback shorthand - * _.pluck(_.dropWhile(users, 'active'), 'user'); - * // => ['barney', 'fred', 'pebbles'] - */ - function dropWhile(array, predicate, thisArg) { - return (array && array.length) - ? baseWhile(array, getCallback(predicate, thisArg, 3), true) - : []; - } - - /** - * Fills elements of `array` with `value` from `start` up to, but not - * including, `end`. - * - * **Note:** This method mutates `array`. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to fill. - * @param {*} value The value to fill `array` with. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns `array`. - * @example - * - * var array = [1, 2, 3]; - * - * _.fill(array, 'a'); - * console.log(array); - * // => ['a', 'a', 'a'] - * - * _.fill(Array(3), 2); - * // => [2, 2, 2] - * - * _.fill([4, 6, 8], '*', 1, 2); - * // => [4, '*', 8] - */ - function fill(array, value, start, end) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - if (start && typeof start != 'number' && isIterateeCall(array, value, start)) { - start = 0; - end = length; - } - return baseFill(array, value, start, end); - } - - /** - * This method is like `_.find` except that it returns the index of the first - * element `predicate` returns truthy for instead of the element itself. - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to search. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {number} Returns the index of the found element, else `-1`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': false }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': true } - * ]; - * - * _.findIndex(users, function(chr) { - * return chr.user == 'barney'; - * }); - * // => 0 - * - * // using the `_.matches` callback shorthand - * _.findIndex(users, { 'user': 'fred', 'active': false }); - * // => 1 - * - * // using the `_.matchesProperty` callback shorthand - * _.findIndex(users, 'active', false); - * // => 0 - * - * // using the `_.property` callback shorthand - * _.findIndex(users, 'active'); - * // => 2 - */ - var findIndex = createFindIndex(); - - /** - * This method is like `_.findIndex` except that it iterates over elements - * of `collection` from right to left. - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to search. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {number} Returns the index of the found element, else `-1`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': true }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': false } - * ]; - * - * _.findLastIndex(users, function(chr) { - * return chr.user == 'pebbles'; - * }); - * // => 2 - * - * // using the `_.matches` callback shorthand - * _.findLastIndex(users, { 'user': 'barney', 'active': true }); - * // => 0 - * - * // using the `_.matchesProperty` callback shorthand - * _.findLastIndex(users, 'active', false); - * // => 2 - * - * // using the `_.property` callback shorthand - * _.findLastIndex(users, 'active'); - * // => 0 - */ - var findLastIndex = createFindIndex(true); - - /** - * Gets the first element of `array`. - * - * @static - * @memberOf _ - * @alias head - * @category Array - * @param {Array} array The array to query. - * @returns {*} Returns the first element of `array`. - * @example - * - * _.first([1, 2, 3]); - * // => 1 - * - * _.first([]); - * // => undefined - */ - function first(array) { - return array ? array[0] : undefined; - } - - /** - * Flattens a nested array. If `isDeep` is `true` the array is recursively - * flattened, otherwise it is only flattened a single level. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to flatten. - * @param {boolean} [isDeep] Specify a deep flatten. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {Array} Returns the new flattened array. - * @example - * - * _.flatten([1, [2, 3, [4]]]); - * // => [1, 2, 3, [4]] - * - * // using `isDeep` - * _.flatten([1, [2, 3, [4]]], true); - * // => [1, 2, 3, 4] - */ - function flatten(array, isDeep, guard) { - var length = array ? array.length : 0; - if (guard && isIterateeCall(array, isDeep, guard)) { - isDeep = false; - } - return length ? baseFlatten(array, isDeep) : []; - } - - /** - * Recursively flattens a nested array. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to recursively flatten. - * @returns {Array} Returns the new flattened array. - * @example - * - * _.flattenDeep([1, [2, 3, [4]]]); - * // => [1, 2, 3, 4] - */ - function flattenDeep(array) { - var length = array ? array.length : 0; - return length ? baseFlatten(array, true) : []; - } - - /** - * Gets the index at which the first occurrence of `value` is found in `array` - * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. If `fromIndex` is negative, it is used as the offset - * from the end of `array`. If `array` is sorted providing `true` for `fromIndex` - * performs a faster binary search. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {boolean|number} [fromIndex=0] The index to search from or `true` - * to perform a binary search on a sorted array. - * @returns {number} Returns the index of the matched value, else `-1`. - * @example - * - * _.indexOf([1, 2, 1, 2], 2); - * // => 1 - * - * // using `fromIndex` - * _.indexOf([1, 2, 1, 2], 2, 2); - * // => 3 - * - * // performing a binary search - * _.indexOf([1, 1, 2, 2], 2, true); - * // => 2 - */ - function indexOf(array, value, fromIndex) { - var length = array ? array.length : 0; - if (!length) { - return -1; - } - if (typeof fromIndex == 'number') { - fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex; - } else if (fromIndex) { - var index = binaryIndex(array, value); - if (index < length && - (value === value ? (value === array[index]) : (array[index] !== array[index]))) { - return index; - } - return -1; - } - return baseIndexOf(array, value, fromIndex || 0); - } - - /** - * Gets all but the last element of `array`. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.initial([1, 2, 3]); - * // => [1, 2] - */ - function initial(array) { - return dropRight(array, 1); - } - - /** - * Creates an array of unique values that are included in all of the provided - * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. - * - * @static - * @memberOf _ - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of shared values. - * @example - * _.intersection([1, 2], [4, 2], [2, 1]); - * // => [2] - */ - var intersection = restParam(function(arrays) { - var othLength = arrays.length, - othIndex = othLength, - caches = Array(length), - indexOf = getIndexOf(), - isCommon = indexOf == baseIndexOf, - result = []; - - while (othIndex--) { - var value = arrays[othIndex] = isArrayLike(value = arrays[othIndex]) ? value : []; - caches[othIndex] = (isCommon && value.length >= 120) ? createCache(othIndex && value) : null; - } - var array = arrays[0], - index = -1, - length = array ? array.length : 0, - seen = caches[0]; - - outer: - while (++index < length) { - value = array[index]; - if ((seen ? cacheIndexOf(seen, value) : indexOf(result, value, 0)) < 0) { - var othIndex = othLength; - while (--othIndex) { - var cache = caches[othIndex]; - if ((cache ? cacheIndexOf(cache, value) : indexOf(arrays[othIndex], value, 0)) < 0) { - continue outer; - } - } - if (seen) { - seen.push(value); - } - result.push(value); - } - } - return result; - }); - - /** - * Gets the last element of `array`. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @returns {*} Returns the last element of `array`. - * @example - * - * _.last([1, 2, 3]); - * // => 3 - */ - function last(array) { - var length = array ? array.length : 0; - return length ? array[length - 1] : undefined; - } - - /** - * This method is like `_.indexOf` except that it iterates over elements of - * `array` from right to left. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {boolean|number} [fromIndex=array.length-1] The index to search from - * or `true` to perform a binary search on a sorted array. - * @returns {number} Returns the index of the matched value, else `-1`. - * @example - * - * _.lastIndexOf([1, 2, 1, 2], 2); - * // => 3 - * - * // using `fromIndex` - * _.lastIndexOf([1, 2, 1, 2], 2, 2); - * // => 1 - * - * // performing a binary search - * _.lastIndexOf([1, 1, 2, 2], 2, true); - * // => 3 - */ - function lastIndexOf(array, value, fromIndex) { - var length = array ? array.length : 0; - if (!length) { - return -1; - } - var index = length; - if (typeof fromIndex == 'number') { - index = (fromIndex < 0 ? nativeMax(length + fromIndex, 0) : nativeMin(fromIndex || 0, length - 1)) + 1; - } else if (fromIndex) { - index = binaryIndex(array, value, true) - 1; - var other = array[index]; - if (value === value ? (value === other) : (other !== other)) { - return index; - } - return -1; - } - if (value !== value) { - return indexOfNaN(array, index, true); - } - while (index--) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * Removes all provided values from `array` using - * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. - * - * **Note:** Unlike `_.without`, this method mutates `array`. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to modify. - * @param {...*} [values] The values to remove. - * @returns {Array} Returns `array`. - * @example - * - * var array = [1, 2, 3, 1, 2, 3]; - * - * _.pull(array, 2, 3); - * console.log(array); - * // => [1, 1] - */ - function pull() { - var args = arguments, - array = args[0]; - - if (!(array && array.length)) { - return array; - } - var index = 0, - indexOf = getIndexOf(), - length = args.length; - - while (++index < length) { - var fromIndex = 0, - value = args[index]; - - while ((fromIndex = indexOf(array, value, fromIndex)) > -1) { - splice.call(array, fromIndex, 1); - } - } - return array; - } - - /** - * Removes elements from `array` corresponding to the given indexes and returns - * an array of the removed elements. Indexes may be specified as an array of - * indexes or as individual arguments. - * - * **Note:** Unlike `_.at`, this method mutates `array`. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to modify. - * @param {...(number|number[])} [indexes] The indexes of elements to remove, - * specified as individual indexes or arrays of indexes. - * @returns {Array} Returns the new array of removed elements. - * @example - * - * var array = [5, 10, 15, 20]; - * var evens = _.pullAt(array, 1, 3); - * - * console.log(array); - * // => [5, 15] - * - * console.log(evens); - * // => [10, 20] - */ - var pullAt = restParam(function(array, indexes) { - indexes = baseFlatten(indexes); - - var result = baseAt(array, indexes); - basePullAt(array, indexes.sort(baseCompareAscending)); - return result; - }); - - /** - * Removes all elements from `array` that `predicate` returns truthy for - * and returns an array of the removed elements. The predicate is bound to - * `thisArg` and invoked with three arguments: (value, index, array). - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * **Note:** Unlike `_.filter`, this method mutates `array`. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to modify. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the new array of removed elements. - * @example - * - * var array = [1, 2, 3, 4]; - * var evens = _.remove(array, function(n) { - * return n % 2 == 0; - * }); - * - * console.log(array); - * // => [1, 3] - * - * console.log(evens); - * // => [2, 4] - */ - function remove(array, predicate, thisArg) { - var result = []; - if (!(array && array.length)) { - return result; - } - var index = -1, - indexes = [], - length = array.length; - - predicate = getCallback(predicate, thisArg, 3); - while (++index < length) { - var value = array[index]; - if (predicate(value, index, array)) { - result.push(value); - indexes.push(index); - } - } - basePullAt(array, indexes); - return result; - } - - /** - * Gets all but the first element of `array`. - * - * @static - * @memberOf _ - * @alias tail - * @category Array - * @param {Array} array The array to query. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.rest([1, 2, 3]); - * // => [2, 3] - */ - function rest(array) { - return drop(array, 1); - } - - /** - * Creates a slice of `array` from `start` up to, but not including, `end`. - * - * **Note:** This method is used instead of `Array#slice` to support node - * lists in IE < 9 and to ensure dense arrays are returned. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to slice. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns the slice of `array`. - */ - function slice(array, start, end) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { - start = 0; - end = length; - } - return baseSlice(array, start, end); - } - - /** - * Uses a binary search to determine the lowest index at which `value` should - * be inserted into `array` in order to maintain its sort order. If an iteratee - * function is provided it is invoked for `value` and each element of `array` - * to compute their sort ranking. The iteratee is bound to `thisArg` and - * invoked with one argument; (value). - * - * If a property name is provided for `iteratee` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `iteratee` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - * @example - * - * _.sortedIndex([30, 50], 40); - * // => 1 - * - * _.sortedIndex([4, 4, 5, 5], 5); - * // => 2 - * - * var dict = { 'data': { 'thirty': 30, 'forty': 40, 'fifty': 50 } }; - * - * // using an iteratee function - * _.sortedIndex(['thirty', 'fifty'], 'forty', function(word) { - * return this.data[word]; - * }, dict); - * // => 1 - * - * // using the `_.property` callback shorthand - * _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); - * // => 1 - */ - var sortedIndex = createSortedIndex(); - - /** - * This method is like `_.sortedIndex` except that it returns the highest - * index at which `value` should be inserted into `array` in order to - * maintain its sort order. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - * @example - * - * _.sortedLastIndex([4, 4, 5, 5], 5); - * // => 4 - */ - var sortedLastIndex = createSortedIndex(true); - - /** - * Creates a slice of `array` with `n` elements taken from the beginning. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=1] The number of elements to take. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.take([1, 2, 3]); - * // => [1] - * - * _.take([1, 2, 3], 2); - * // => [1, 2] - * - * _.take([1, 2, 3], 5); - * // => [1, 2, 3] - * - * _.take([1, 2, 3], 0); - * // => [] - */ - function take(array, n, guard) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - if (guard ? isIterateeCall(array, n, guard) : n == null) { - n = 1; - } - return baseSlice(array, 0, n < 0 ? 0 : n); - } - - /** - * Creates a slice of `array` with `n` elements taken from the end. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=1] The number of elements to take. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.takeRight([1, 2, 3]); - * // => [3] - * - * _.takeRight([1, 2, 3], 2); - * // => [2, 3] - * - * _.takeRight([1, 2, 3], 5); - * // => [1, 2, 3] - * - * _.takeRight([1, 2, 3], 0); - * // => [] - */ - function takeRight(array, n, guard) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - if (guard ? isIterateeCall(array, n, guard) : n == null) { - n = 1; - } - n = length - (+n || 0); - return baseSlice(array, n < 0 ? 0 : n); - } - - /** - * Creates a slice of `array` with elements taken from the end. Elements are - * taken until `predicate` returns falsey. The predicate is bound to `thisArg` - * and invoked with three arguments: (value, index, array). - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.takeRightWhile([1, 2, 3], function(n) { - * return n > 1; - * }); - * // => [2, 3] - * - * var users = [ - * { 'user': 'barney', 'active': true }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': false } - * ]; - * - * // using the `_.matches` callback shorthand - * _.pluck(_.takeRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); - * // => ['pebbles'] - * - * // using the `_.matchesProperty` callback shorthand - * _.pluck(_.takeRightWhile(users, 'active', false), 'user'); - * // => ['fred', 'pebbles'] - * - * // using the `_.property` callback shorthand - * _.pluck(_.takeRightWhile(users, 'active'), 'user'); - * // => [] - */ - function takeRightWhile(array, predicate, thisArg) { - return (array && array.length) - ? baseWhile(array, getCallback(predicate, thisArg, 3), false, true) - : []; - } - - /** - * Creates a slice of `array` with elements taken from the beginning. Elements - * are taken until `predicate` returns falsey. The predicate is bound to - * `thisArg` and invoked with three arguments: (value, index, array). - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.takeWhile([1, 2, 3], function(n) { - * return n < 3; - * }); - * // => [1, 2] - * - * var users = [ - * { 'user': 'barney', 'active': false }, - * { 'user': 'fred', 'active': false}, - * { 'user': 'pebbles', 'active': true } - * ]; - * - * // using the `_.matches` callback shorthand - * _.pluck(_.takeWhile(users, { 'user': 'barney', 'active': false }), 'user'); - * // => ['barney'] - * - * // using the `_.matchesProperty` callback shorthand - * _.pluck(_.takeWhile(users, 'active', false), 'user'); - * // => ['barney', 'fred'] - * - * // using the `_.property` callback shorthand - * _.pluck(_.takeWhile(users, 'active'), 'user'); - * // => [] - */ - function takeWhile(array, predicate, thisArg) { - return (array && array.length) - ? baseWhile(array, getCallback(predicate, thisArg, 3)) - : []; - } - - /** - * Creates an array of unique values, in order, from all of the provided arrays - * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. - * - * @static - * @memberOf _ - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of combined values. - * @example - * - * _.union([1, 2], [4, 2], [2, 1]); - * // => [1, 2, 4] - */ - var union = restParam(function(arrays) { - return baseUniq(baseFlatten(arrays, false, true)); - }); - - /** - * Creates a duplicate-free version of an array, using - * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons, in which only the first occurence of each element - * is kept. Providing `true` for `isSorted` performs a faster search algorithm - * for sorted arrays. If an iteratee function is provided it is invoked for - * each element in the array to generate the criterion by which uniqueness - * is computed. The `iteratee` is bound to `thisArg` and invoked with three - * arguments: (value, index, array). - * - * If a property name is provided for `iteratee` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `iteratee` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @alias unique - * @category Array - * @param {Array} array The array to inspect. - * @param {boolean} [isSorted] Specify the array is sorted. - * @param {Function|Object|string} [iteratee] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Array} Returns the new duplicate-value-free array. - * @example - * - * _.uniq([2, 1, 2]); - * // => [2, 1] - * - * // using `isSorted` - * _.uniq([1, 1, 2], true); - * // => [1, 2] - * - * // using an iteratee function - * _.uniq([1, 2.5, 1.5, 2], function(n) { - * return this.floor(n); - * }, Math); - * // => [1, 2.5] - * - * // using the `_.property` callback shorthand - * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 1 }, { 'x': 2 }] - */ - function uniq(array, isSorted, iteratee, thisArg) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - if (isSorted != null && typeof isSorted != 'boolean') { - thisArg = iteratee; - iteratee = isIterateeCall(array, isSorted, thisArg) ? undefined : isSorted; - isSorted = false; - } - var callback = getCallback(); - if (!(iteratee == null && callback === baseCallback)) { - iteratee = callback(iteratee, thisArg, 3); - } - return (isSorted && getIndexOf() == baseIndexOf) - ? sortedUniq(array, iteratee) - : baseUniq(array, iteratee); - } - - /** - * This method is like `_.zip` except that it accepts an array of grouped - * elements and creates an array regrouping the elements to their pre-zip - * configuration. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array of grouped elements to process. - * @returns {Array} Returns the new array of regrouped elements. - * @example - * - * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]); - * // => [['fred', 30, true], ['barney', 40, false]] - * - * _.unzip(zipped); - * // => [['fred', 'barney'], [30, 40], [true, false]] - */ - function unzip(array) { - if (!(array && array.length)) { - return []; - } - var index = -1, - length = 0; - - array = arrayFilter(array, function(group) { - if (isArrayLike(group)) { - length = nativeMax(group.length, length); - return true; - } - }); - var result = Array(length); - while (++index < length) { - result[index] = arrayMap(array, baseProperty(index)); - } - return result; - } - - /** - * This method is like `_.unzip` except that it accepts an iteratee to specify - * how regrouped values should be combined. The `iteratee` is bound to `thisArg` - * and invoked with four arguments: (accumulator, value, index, group). - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array of grouped elements to process. - * @param {Function} [iteratee] The function to combine regrouped values. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Array} Returns the new array of regrouped elements. - * @example - * - * var zipped = _.zip([1, 2], [10, 20], [100, 200]); - * // => [[1, 10, 100], [2, 20, 200]] - * - * _.unzipWith(zipped, _.add); - * // => [3, 30, 300] - */ - function unzipWith(array, iteratee, thisArg) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - var result = unzip(array); - if (iteratee == null) { - return result; - } - iteratee = bindCallback(iteratee, thisArg, 4); - return arrayMap(result, function(group) { - return arrayReduce(group, iteratee, undefined, true); - }); - } - - /** - * Creates an array excluding all provided values using - * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to filter. - * @param {...*} [values] The values to exclude. - * @returns {Array} Returns the new array of filtered values. - * @example - * - * _.without([1, 2, 1, 3], 1, 2); - * // => [3] - */ - var without = restParam(function(array, values) { - return isArrayLike(array) - ? baseDifference(array, values) - : []; - }); - - /** - * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) - * of the provided arrays. - * - * @static - * @memberOf _ - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of values. - * @example - * - * _.xor([1, 2], [4, 2]); - * // => [1, 4] - */ - function xor() { - var index = -1, - length = arguments.length; - - while (++index < length) { - var array = arguments[index]; - if (isArrayLike(array)) { - var result = result - ? arrayPush(baseDifference(result, array), baseDifference(array, result)) - : array; - } - } - return result ? baseUniq(result) : []; - } - - /** - * Creates an array of grouped elements, the first of which contains the first - * elements of the given arrays, the second of which contains the second elements - * of the given arrays, and so on. - * - * @static - * @memberOf _ - * @category Array - * @param {...Array} [arrays] The arrays to process. - * @returns {Array} Returns the new array of grouped elements. - * @example - * - * _.zip(['fred', 'barney'], [30, 40], [true, false]); - * // => [['fred', 30, true], ['barney', 40, false]] - */ - var zip = restParam(unzip); - - /** - * The inverse of `_.pairs`; this method returns an object composed from arrays - * of property names and values. Provide either a single two dimensional array, - * e.g. `[[key1, value1], [key2, value2]]` or two arrays, one of property names - * and one of corresponding values. - * - * @static - * @memberOf _ - * @alias object - * @category Array - * @param {Array} props The property names. - * @param {Array} [values=[]] The property values. - * @returns {Object} Returns the new object. - * @example - * - * _.zipObject([['fred', 30], ['barney', 40]]); - * // => { 'fred': 30, 'barney': 40 } - * - * _.zipObject(['fred', 'barney'], [30, 40]); - * // => { 'fred': 30, 'barney': 40 } - */ - function zipObject(props, values) { - var index = -1, - length = props ? props.length : 0, - result = {}; - - if (length && !values && !isArray(props[0])) { - values = []; - } - while (++index < length) { - var key = props[index]; - if (values) { - result[key] = values[index]; - } else if (key) { - result[key[0]] = key[1]; - } - } - return result; - } - - /** - * This method is like `_.zip` except that it accepts an iteratee to specify - * how grouped values should be combined. The `iteratee` is bound to `thisArg` - * and invoked with four arguments: (accumulator, value, index, group). - * - * @static - * @memberOf _ - * @category Array - * @param {...Array} [arrays] The arrays to process. - * @param {Function} [iteratee] The function to combine grouped values. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Array} Returns the new array of grouped elements. - * @example - * - * _.zipWith([1, 2], [10, 20], [100, 200], _.add); - * // => [111, 222] - */ - var zipWith = restParam(function(arrays) { - var length = arrays.length, - iteratee = length > 2 ? arrays[length - 2] : undefined, - thisArg = length > 1 ? arrays[length - 1] : undefined; - - if (length > 2 && typeof iteratee == 'function') { - length -= 2; - } else { - iteratee = (length > 1 && typeof thisArg == 'function') ? (--length, thisArg) : undefined; - thisArg = undefined; - } - arrays.length = length; - return unzipWith(arrays, iteratee, thisArg); - }); - - /*------------------------------------------------------------------------*/ - - /** - * Creates a `lodash` object that wraps `value` with explicit method - * chaining enabled. - * - * @static - * @memberOf _ - * @category Chain - * @param {*} value The value to wrap. - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 }, - * { 'user': 'pebbles', 'age': 1 } - * ]; - * - * var youngest = _.chain(users) - * .sortBy('age') - * .map(function(chr) { - * return chr.user + ' is ' + chr.age; - * }) - * .first() - * .value(); - * // => 'pebbles is 1' - */ - function chain(value) { - var result = lodash(value); - result.__chain__ = true; - return result; - } - - /** - * This method invokes `interceptor` and returns `value`. The interceptor is - * bound to `thisArg` and invoked with one argument; (value). The purpose of - * this method is to "tap into" a method chain in order to perform operations - * on intermediate results within the chain. - * - * @static - * @memberOf _ - * @category Chain - * @param {*} value The value to provide to `interceptor`. - * @param {Function} interceptor The function to invoke. - * @param {*} [thisArg] The `this` binding of `interceptor`. - * @returns {*} Returns `value`. - * @example - * - * _([1, 2, 3]) - * .tap(function(array) { - * array.pop(); - * }) - * .reverse() - * .value(); - * // => [2, 1] - */ - function tap(value, interceptor, thisArg) { - interceptor.call(thisArg, value); - return value; - } - - /** - * This method is like `_.tap` except that it returns the result of `interceptor`. - * - * @static - * @memberOf _ - * @category Chain - * @param {*} value The value to provide to `interceptor`. - * @param {Function} interceptor The function to invoke. - * @param {*} [thisArg] The `this` binding of `interceptor`. - * @returns {*} Returns the result of `interceptor`. - * @example - * - * _(' abc ') - * .chain() - * .trim() - * .thru(function(value) { - * return [value]; - * }) - * .value(); - * // => ['abc'] - */ - function thru(value, interceptor, thisArg) { - return interceptor.call(thisArg, value); - } - - /** - * Enables explicit method chaining on the wrapper object. - * - * @name chain - * @memberOf _ - * @category Chain - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 } - * ]; - * - * // without explicit chaining - * _(users).first(); - * // => { 'user': 'barney', 'age': 36 } - * - * // with explicit chaining - * _(users).chain() - * .first() - * .pick('user') - * .value(); - * // => { 'user': 'barney' } - */ - function wrapperChain() { - return chain(this); - } - - /** - * Executes the chained sequence and returns the wrapped result. - * - * @name commit - * @memberOf _ - * @category Chain - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var array = [1, 2]; - * var wrapped = _(array).push(3); - * - * console.log(array); - * // => [1, 2] - * - * wrapped = wrapped.commit(); - * console.log(array); - * // => [1, 2, 3] - * - * wrapped.last(); - * // => 3 - * - * console.log(array); - * // => [1, 2, 3] - */ - function wrapperCommit() { - return new LodashWrapper(this.value(), this.__chain__); - } - - /** - * Creates a new array joining a wrapped array with any additional arrays - * and/or values. - * - * @name concat - * @memberOf _ - * @category Chain - * @param {...*} [values] The values to concatenate. - * @returns {Array} Returns the new concatenated array. - * @example - * - * var array = [1]; - * var wrapped = _(array).concat(2, [3], [[4]]); - * - * console.log(wrapped.value()); - * // => [1, 2, 3, [4]] - * - * console.log(array); - * // => [1] - */ - var wrapperConcat = restParam(function(values) { - values = baseFlatten(values); - return this.thru(function(array) { - return arrayConcat(isArray(array) ? array : [toObject(array)], values); - }); - }); - - /** - * Creates a clone of the chained sequence planting `value` as the wrapped value. - * - * @name plant - * @memberOf _ - * @category Chain - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var array = [1, 2]; - * var wrapped = _(array).map(function(value) { - * return Math.pow(value, 2); - * }); - * - * var other = [3, 4]; - * var otherWrapped = wrapped.plant(other); - * - * otherWrapped.value(); - * // => [9, 16] - * - * wrapped.value(); - * // => [1, 4] - */ - function wrapperPlant(value) { - var result, - parent = this; - - while (parent instanceof baseLodash) { - var clone = wrapperClone(parent); - if (result) { - previous.__wrapped__ = clone; - } else { - result = clone; - } - var previous = clone; - parent = parent.__wrapped__; - } - previous.__wrapped__ = value; - return result; - } - - /** - * Reverses the wrapped array so the first element becomes the last, the - * second element becomes the second to last, and so on. - * - * **Note:** This method mutates the wrapped array. - * - * @name reverse - * @memberOf _ - * @category Chain - * @returns {Object} Returns the new reversed `lodash` wrapper instance. - * @example - * - * var array = [1, 2, 3]; - * - * _(array).reverse().value() - * // => [3, 2, 1] - * - * console.log(array); - * // => [3, 2, 1] - */ - function wrapperReverse() { - var value = this.__wrapped__; - - var interceptor = function(value) { - return (wrapped && wrapped.__dir__ < 0) ? value : value.reverse(); - }; - if (value instanceof LazyWrapper) { - var wrapped = value; - if (this.__actions__.length) { - wrapped = new LazyWrapper(this); - } - wrapped = wrapped.reverse(); - wrapped.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined }); - return new LodashWrapper(wrapped, this.__chain__); - } - return this.thru(interceptor); - } - - /** - * Produces the result of coercing the unwrapped value to a string. - * - * @name toString - * @memberOf _ - * @category Chain - * @returns {string} Returns the coerced string value. - * @example - * - * _([1, 2, 3]).toString(); - * // => '1,2,3' - */ - function wrapperToString() { - return (this.value() + ''); - } - - /** - * Executes the chained sequence to extract the unwrapped value. - * - * @name value - * @memberOf _ - * @alias run, toJSON, valueOf - * @category Chain - * @returns {*} Returns the resolved unwrapped value. - * @example - * - * _([1, 2, 3]).value(); - * // => [1, 2, 3] - */ - function wrapperValue() { - return baseWrapperValue(this.__wrapped__, this.__actions__); - } - - /*------------------------------------------------------------------------*/ - - /** - * Creates an array of elements corresponding to the given keys, or indexes, - * of `collection`. Keys may be specified as individual arguments or as arrays - * of keys. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {...(number|number[]|string|string[])} [props] The property names - * or indexes of elements to pick, specified individually or in arrays. - * @returns {Array} Returns the new array of picked elements. - * @example - * - * _.at(['a', 'b', 'c'], [0, 2]); - * // => ['a', 'c'] - * - * _.at(['barney', 'fred', 'pebbles'], 0, 2); - * // => ['barney', 'pebbles'] - */ - var at = restParam(function(collection, props) { - return baseAt(collection, baseFlatten(props)); - }); - - /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` through `iteratee`. The corresponding value - * of each key is the number of times the key was returned by `iteratee`. - * The `iteratee` is bound to `thisArg` and invoked with three arguments: - * (value, index|key, collection). - * - * If a property name is provided for `iteratee` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `iteratee` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.countBy([4.3, 6.1, 6.4], function(n) { - * return Math.floor(n); - * }); - * // => { '4': 1, '6': 2 } - * - * _.countBy([4.3, 6.1, 6.4], function(n) { - * return this.floor(n); - * }, Math); - * // => { '4': 1, '6': 2 } - * - * _.countBy(['one', 'two', 'three'], 'length'); - * // => { '3': 2, '5': 1 } - */ - var countBy = createAggregator(function(result, value, key) { - hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1); - }); - - /** - * Checks if `predicate` returns truthy for **all** elements of `collection`. - * The predicate is bound to `thisArg` and invoked with three arguments: - * (value, index|key, collection). - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @alias all - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {boolean} Returns `true` if all elements pass the predicate check, - * else `false`. - * @example - * - * _.every([true, 1, null, 'yes'], Boolean); - * // => false - * - * var users = [ - * { 'user': 'barney', 'active': false }, - * { 'user': 'fred', 'active': false } - * ]; - * - * // using the `_.matches` callback shorthand - * _.every(users, { 'user': 'barney', 'active': false }); - * // => false - * - * // using the `_.matchesProperty` callback shorthand - * _.every(users, 'active', false); - * // => true - * - * // using the `_.property` callback shorthand - * _.every(users, 'active'); - * // => false - */ - function every(collection, predicate, thisArg) { - var func = isArray(collection) ? arrayEvery : baseEvery; - if (thisArg && isIterateeCall(collection, predicate, thisArg)) { - predicate = undefined; - } - if (typeof predicate != 'function' || thisArg !== undefined) { - predicate = getCallback(predicate, thisArg, 3); - } - return func(collection, predicate); - } - - /** - * Iterates over elements of `collection`, returning an array of all elements - * `predicate` returns truthy for. The predicate is bound to `thisArg` and - * invoked with three arguments: (value, index|key, collection). - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @alias select - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the new filtered array. - * @example - * - * _.filter([4, 5, 6], function(n) { - * return n % 2 == 0; - * }); - * // => [4, 6] - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': true }, - * { 'user': 'fred', 'age': 40, 'active': false } - * ]; - * - * // using the `_.matches` callback shorthand - * _.pluck(_.filter(users, { 'age': 36, 'active': true }), 'user'); - * // => ['barney'] - * - * // using the `_.matchesProperty` callback shorthand - * _.pluck(_.filter(users, 'active', false), 'user'); - * // => ['fred'] - * - * // using the `_.property` callback shorthand - * _.pluck(_.filter(users, 'active'), 'user'); - * // => ['barney'] - */ - function filter(collection, predicate, thisArg) { - var func = isArray(collection) ? arrayFilter : baseFilter; - predicate = getCallback(predicate, thisArg, 3); - return func(collection, predicate); - } - - /** - * Iterates over elements of `collection`, returning the first element - * `predicate` returns truthy for. The predicate is bound to `thisArg` and - * invoked with three arguments: (value, index|key, collection). - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @alias detect - * @category Collection - * @param {Array|Object|string} collection The collection to search. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {*} Returns the matched element, else `undefined`. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': true }, - * { 'user': 'fred', 'age': 40, 'active': false }, - * { 'user': 'pebbles', 'age': 1, 'active': true } - * ]; - * - * _.result(_.find(users, function(chr) { - * return chr.age < 40; - * }), 'user'); - * // => 'barney' - * - * // using the `_.matches` callback shorthand - * _.result(_.find(users, { 'age': 1, 'active': true }), 'user'); - * // => 'pebbles' - * - * // using the `_.matchesProperty` callback shorthand - * _.result(_.find(users, 'active', false), 'user'); - * // => 'fred' - * - * // using the `_.property` callback shorthand - * _.result(_.find(users, 'active'), 'user'); - * // => 'barney' - */ - var find = createFind(baseEach); - - /** - * This method is like `_.find` except that it iterates over elements of - * `collection` from right to left. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to search. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {*} Returns the matched element, else `undefined`. - * @example - * - * _.findLast([1, 2, 3, 4], function(n) { - * return n % 2 == 1; - * }); - * // => 3 - */ - var findLast = createFind(baseEachRight, true); - - /** - * Performs a deep comparison between each element in `collection` and the - * source object, returning the first element that has equivalent property - * values. - * - * **Note:** This method supports comparing arrays, booleans, `Date` objects, - * numbers, `Object` objects, regexes, and strings. Objects are compared by - * their own, not inherited, enumerable properties. For comparing a single - * own or inherited property value see `_.matchesProperty`. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to search. - * @param {Object} source The object of property values to match. - * @returns {*} Returns the matched element, else `undefined`. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': true }, - * { 'user': 'fred', 'age': 40, 'active': false } - * ]; - * - * _.result(_.findWhere(users, { 'age': 36, 'active': true }), 'user'); - * // => 'barney' - * - * _.result(_.findWhere(users, { 'age': 40, 'active': false }), 'user'); - * // => 'fred' - */ - function findWhere(collection, source) { - return find(collection, baseMatches(source)); - } - - /** - * Iterates over elements of `collection` invoking `iteratee` for each element. - * The `iteratee` is bound to `thisArg` and invoked with three arguments: - * (value, index|key, collection). Iteratee functions may exit iteration early - * by explicitly returning `false`. - * - * **Note:** As with other "Collections" methods, objects with a "length" property - * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` - * may be used for object iteration. - * - * @static - * @memberOf _ - * @alias each - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Array|Object|string} Returns `collection`. - * @example - * - * _([1, 2]).forEach(function(n) { - * console.log(n); - * }).value(); - * // => logs each value from left to right and returns the array - * - * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) { - * console.log(n, key); - * }); - * // => logs each value-key pair and returns the object (iteration order is not guaranteed) - */ - var forEach = createForEach(arrayEach, baseEach); - - /** - * This method is like `_.forEach` except that it iterates over elements of - * `collection` from right to left. - * - * @static - * @memberOf _ - * @alias eachRight - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Array|Object|string} Returns `collection`. - * @example - * - * _([1, 2]).forEachRight(function(n) { - * console.log(n); - * }).value(); - * // => logs each value from right to left and returns the array - */ - var forEachRight = createForEach(arrayEachRight, baseEachRight); - - /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` through `iteratee`. The corresponding value - * of each key is an array of the elements responsible for generating the key. - * The `iteratee` is bound to `thisArg` and invoked with three arguments: - * (value, index|key, collection). - * - * If a property name is provided for `iteratee` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `iteratee` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.groupBy([4.2, 6.1, 6.4], function(n) { - * return Math.floor(n); - * }); - * // => { '4': [4.2], '6': [6.1, 6.4] } - * - * _.groupBy([4.2, 6.1, 6.4], function(n) { - * return this.floor(n); - * }, Math); - * // => { '4': [4.2], '6': [6.1, 6.4] } - * - * // using the `_.property` callback shorthand - * _.groupBy(['one', 'two', 'three'], 'length'); - * // => { '3': ['one', 'two'], '5': ['three'] } - */ - var groupBy = createAggregator(function(result, value, key) { - if (hasOwnProperty.call(result, key)) { - result[key].push(value); - } else { - result[key] = [value]; - } - }); - - /** - * Checks if `value` is in `collection` using - * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. If `fromIndex` is negative, it is used as the offset - * from the end of `collection`. - * - * @static - * @memberOf _ - * @alias contains, include - * @category Collection - * @param {Array|Object|string} collection The collection to search. - * @param {*} target The value to search for. - * @param {number} [fromIndex=0] The index to search from. - * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. - * @returns {boolean} Returns `true` if a matching element is found, else `false`. - * @example - * - * _.includes([1, 2, 3], 1); - * // => true - * - * _.includes([1, 2, 3], 1, 2); - * // => false - * - * _.includes({ 'user': 'fred', 'age': 40 }, 'fred'); - * // => true - * - * _.includes('pebbles', 'eb'); - * // => true - */ - function includes(collection, target, fromIndex, guard) { - var length = collection ? getLength(collection) : 0; - if (!isLength(length)) { - collection = values(collection); - length = collection.length; - } - if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) { - fromIndex = 0; - } else { - fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0); - } - return (typeof collection == 'string' || !isArray(collection) && isString(collection)) - ? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1) - : (!!length && getIndexOf(collection, target, fromIndex) > -1); - } - - /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` through `iteratee`. The corresponding value - * of each key is the last element responsible for generating the key. The - * iteratee function is bound to `thisArg` and invoked with three arguments: - * (value, index|key, collection). - * - * If a property name is provided for `iteratee` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `iteratee` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * var keyData = [ - * { 'dir': 'left', 'code': 97 }, - * { 'dir': 'right', 'code': 100 } - * ]; - * - * _.indexBy(keyData, 'dir'); - * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } - * - * _.indexBy(keyData, function(object) { - * return String.fromCharCode(object.code); - * }); - * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } - * - * _.indexBy(keyData, function(object) { - * return this.fromCharCode(object.code); - * }, String); - * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } - */ - var indexBy = createAggregator(function(result, value, key) { - result[key] = value; - }); - - /** - * Invokes the method at `path` of each element in `collection`, returning - * an array of the results of each invoked method. Any additional arguments - * are provided to each invoked method. If `methodName` is a function it is - * invoked for, and `this` bound to, each element in `collection`. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Array|Function|string} path The path of the method to invoke or - * the function invoked per iteration. - * @param {...*} [args] The arguments to invoke the method with. - * @returns {Array} Returns the array of results. - * @example - * - * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); - * // => [[1, 5, 7], [1, 2, 3]] - * - * _.invoke([123, 456], String.prototype.split, ''); - * // => [['1', '2', '3'], ['4', '5', '6']] - */ - var invoke = restParam(function(collection, path, args) { - var index = -1, - isFunc = typeof path == 'function', - isProp = isKey(path), - result = isArrayLike(collection) ? Array(collection.length) : []; - - baseEach(collection, function(value) { - var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined); - result[++index] = func ? func.apply(value, args) : invokePath(value, path, args); - }); - return result; - }); - - /** - * Creates an array of values by running each element in `collection` through - * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three - * arguments: (value, index|key, collection). - * - * If a property name is provided for `iteratee` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `iteratee` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * Many lodash methods are guarded to work as iteratees for methods like - * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. - * - * The guarded methods are: - * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`, - * `drop`, `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`, - * `parseInt`, `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`, - * `trimLeft`, `trimRight`, `trunc`, `random`, `range`, `sample`, `some`, - * `sum`, `uniq`, and `words` - * - * @static - * @memberOf _ - * @alias collect - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Array} Returns the new mapped array. - * @example - * - * function timesThree(n) { - * return n * 3; - * } - * - * _.map([1, 2], timesThree); - * // => [3, 6] - * - * _.map({ 'a': 1, 'b': 2 }, timesThree); - * // => [3, 6] (iteration order is not guaranteed) - * - * var users = [ - * { 'user': 'barney' }, - * { 'user': 'fred' } - * ]; - * - * // using the `_.property` callback shorthand - * _.map(users, 'user'); - * // => ['barney', 'fred'] - */ - function map(collection, iteratee, thisArg) { - var func = isArray(collection) ? arrayMap : baseMap; - iteratee = getCallback(iteratee, thisArg, 3); - return func(collection, iteratee); - } - - /** - * Creates an array of elements split into two groups, the first of which - * contains elements `predicate` returns truthy for, while the second of which - * contains elements `predicate` returns falsey for. The predicate is bound - * to `thisArg` and invoked with three arguments: (value, index|key, collection). - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the array of grouped elements. - * @example - * - * _.partition([1, 2, 3], function(n) { - * return n % 2; - * }); - * // => [[1, 3], [2]] - * - * _.partition([1.2, 2.3, 3.4], function(n) { - * return this.floor(n) % 2; - * }, Math); - * // => [[1.2, 3.4], [2.3]] - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': true }, - * { 'user': 'pebbles', 'age': 1, 'active': false } - * ]; - * - * var mapper = function(array) { - * return _.pluck(array, 'user'); - * }; - * - * // using the `_.matches` callback shorthand - * _.map(_.partition(users, { 'age': 1, 'active': false }), mapper); - * // => [['pebbles'], ['barney', 'fred']] - * - * // using the `_.matchesProperty` callback shorthand - * _.map(_.partition(users, 'active', false), mapper); - * // => [['barney', 'pebbles'], ['fred']] - * - * // using the `_.property` callback shorthand - * _.map(_.partition(users, 'active'), mapper); - * // => [['fred'], ['barney', 'pebbles']] - */ - var partition = createAggregator(function(result, value, key) { - result[key ? 0 : 1].push(value); - }, function() { return [[], []]; }); - - /** - * Gets the property value of `path` from all elements in `collection`. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Array|string} path The path of the property to pluck. - * @returns {Array} Returns the property values. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 } - * ]; - * - * _.pluck(users, 'user'); - * // => ['barney', 'fred'] - * - * var userIndex = _.indexBy(users, 'user'); - * _.pluck(userIndex, 'age'); - * // => [36, 40] (iteration order is not guaranteed) - */ - function pluck(collection, path) { - return map(collection, property(path)); - } - - /** - * Reduces `collection` to a value which is the accumulated result of running - * each element in `collection` through `iteratee`, where each successive - * invocation is supplied the return value of the previous. If `accumulator` - * is not provided the first element of `collection` is used as the initial - * value. The `iteratee` is bound to `thisArg` and invoked with four arguments: - * (accumulator, value, index|key, collection). - * - * Many lodash methods are guarded to work as iteratees for methods like - * `_.reduce`, `_.reduceRight`, and `_.transform`. - * - * The guarded methods are: - * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `sortByAll`, - * and `sortByOrder` - * - * @static - * @memberOf _ - * @alias foldl, inject - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {*} Returns the accumulated value. - * @example - * - * _.reduce([1, 2], function(total, n) { - * return total + n; - * }); - * // => 3 - * - * _.reduce({ 'a': 1, 'b': 2 }, function(result, n, key) { - * result[key] = n * 3; - * return result; - * }, {}); - * // => { 'a': 3, 'b': 6 } (iteration order is not guaranteed) - */ - var reduce = createReduce(arrayReduce, baseEach); - - /** - * This method is like `_.reduce` except that it iterates over elements of - * `collection` from right to left. - * - * @static - * @memberOf _ - * @alias foldr - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {*} Returns the accumulated value. - * @example - * - * var array = [[0, 1], [2, 3], [4, 5]]; - * - * _.reduceRight(array, function(flattened, other) { - * return flattened.concat(other); - * }, []); - * // => [4, 5, 2, 3, 0, 1] - */ - var reduceRight = createReduce(arrayReduceRight, baseEachRight); - - /** - * The opposite of `_.filter`; this method returns the elements of `collection` - * that `predicate` does **not** return truthy for. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the new filtered array. - * @example - * - * _.reject([1, 2, 3, 4], function(n) { - * return n % 2 == 0; - * }); - * // => [1, 3] - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': true } - * ]; - * - * // using the `_.matches` callback shorthand - * _.pluck(_.reject(users, { 'age': 40, 'active': true }), 'user'); - * // => ['barney'] - * - * // using the `_.matchesProperty` callback shorthand - * _.pluck(_.reject(users, 'active', false), 'user'); - * // => ['fred'] - * - * // using the `_.property` callback shorthand - * _.pluck(_.reject(users, 'active'), 'user'); - * // => ['barney'] - */ - function reject(collection, predicate, thisArg) { - var func = isArray(collection) ? arrayFilter : baseFilter; - predicate = getCallback(predicate, thisArg, 3); - return func(collection, function(value, index, collection) { - return !predicate(value, index, collection); - }); - } - - /** - * Gets a random element or `n` random elements from a collection. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to sample. - * @param {number} [n] The number of elements to sample. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {*} Returns the random sample(s). - * @example - * - * _.sample([1, 2, 3, 4]); - * // => 2 - * - * _.sample([1, 2, 3, 4], 2); - * // => [3, 1] - */ - function sample(collection, n, guard) { - if (guard ? isIterateeCall(collection, n, guard) : n == null) { - collection = toIterable(collection); - var length = collection.length; - return length > 0 ? collection[baseRandom(0, length - 1)] : undefined; - } - var index = -1, - result = toArray(collection), - length = result.length, - lastIndex = length - 1; - - n = nativeMin(n < 0 ? 0 : (+n || 0), length); - while (++index < n) { - var rand = baseRandom(index, lastIndex), - value = result[rand]; - - result[rand] = result[index]; - result[index] = value; - } - result.length = n; - return result; - } - - /** - * Creates an array of shuffled values, using a version of the - * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to shuffle. - * @returns {Array} Returns the new shuffled array. - * @example - * - * _.shuffle([1, 2, 3, 4]); - * // => [4, 1, 3, 2] - */ - function shuffle(collection) { - return sample(collection, POSITIVE_INFINITY); - } - - /** - * Gets the size of `collection` by returning its length for array-like - * values or the number of own enumerable properties for objects. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to inspect. - * @returns {number} Returns the size of `collection`. - * @example - * - * _.size([1, 2, 3]); - * // => 3 - * - * _.size({ 'a': 1, 'b': 2 }); - * // => 2 - * - * _.size('pebbles'); - * // => 7 - */ - function size(collection) { - var length = collection ? getLength(collection) : 0; - return isLength(length) ? length : keys(collection).length; - } - - /** - * Checks if `predicate` returns truthy for **any** element of `collection`. - * The function returns as soon as it finds a passing value and does not iterate - * over the entire collection. The predicate is bound to `thisArg` and invoked - * with three arguments: (value, index|key, collection). - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @alias any - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. - * @example - * - * _.some([null, 0, 'yes', false], Boolean); - * // => true - * - * var users = [ - * { 'user': 'barney', 'active': true }, - * { 'user': 'fred', 'active': false } - * ]; - * - * // using the `_.matches` callback shorthand - * _.some(users, { 'user': 'barney', 'active': false }); - * // => false - * - * // using the `_.matchesProperty` callback shorthand - * _.some(users, 'active', false); - * // => true - * - * // using the `_.property` callback shorthand - * _.some(users, 'active'); - * // => true - */ - function some(collection, predicate, thisArg) { - var func = isArray(collection) ? arraySome : baseSome; - if (thisArg && isIterateeCall(collection, predicate, thisArg)) { - predicate = undefined; - } - if (typeof predicate != 'function' || thisArg !== undefined) { - predicate = getCallback(predicate, thisArg, 3); - } - return func(collection, predicate); - } - - /** - * Creates an array of elements, sorted in ascending order by the results of - * running each element in a collection through `iteratee`. This method performs - * a stable sort, that is, it preserves the original sort order of equal elements. - * The `iteratee` is bound to `thisArg` and invoked with three arguments: - * (value, index|key, collection). - * - * If a property name is provided for `iteratee` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `iteratee` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Array} Returns the new sorted array. - * @example - * - * _.sortBy([1, 2, 3], function(n) { - * return Math.sin(n); - * }); - * // => [3, 1, 2] - * - * _.sortBy([1, 2, 3], function(n) { - * return this.sin(n); - * }, Math); - * // => [3, 1, 2] - * - * var users = [ - * { 'user': 'fred' }, - * { 'user': 'pebbles' }, - * { 'user': 'barney' } - * ]; - * - * // using the `_.property` callback shorthand - * _.pluck(_.sortBy(users, 'user'), 'user'); - * // => ['barney', 'fred', 'pebbles'] - */ - function sortBy(collection, iteratee, thisArg) { - if (collection == null) { - return []; - } - if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { - iteratee = undefined; - } - var index = -1; - iteratee = getCallback(iteratee, thisArg, 3); - - var result = baseMap(collection, function(value, key, collection) { - return { 'criteria': iteratee(value, key, collection), 'index': ++index, 'value': value }; - }); - return baseSortBy(result, compareAscending); - } - - /** - * This method is like `_.sortBy` except that it can sort by multiple iteratees - * or property names. - * - * If a property name is provided for an iteratee the created `_.property` - * style callback returns the property value of the given element. - * - * If an object is provided for an iteratee the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {...(Function|Function[]|Object|Object[]|string|string[])} iteratees - * The iteratees to sort by, specified as individual values or arrays of values. - * @returns {Array} Returns the new sorted array. - * @example - * - * var users = [ - * { 'user': 'fred', 'age': 48 }, - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 42 }, - * { 'user': 'barney', 'age': 34 } - * ]; - * - * _.map(_.sortByAll(users, ['user', 'age']), _.values); - * // => [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]] - * - * _.map(_.sortByAll(users, 'user', function(chr) { - * return Math.floor(chr.age / 10); - * }), _.values); - * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] - */ - var sortByAll = restParam(function(collection, iteratees) { - if (collection == null) { - return []; - } - var guard = iteratees[2]; - if (guard && isIterateeCall(iteratees[0], iteratees[1], guard)) { - iteratees.length = 1; - } - return baseSortByOrder(collection, baseFlatten(iteratees), []); - }); - - /** - * This method is like `_.sortByAll` except that it allows specifying the - * sort orders of the iteratees to sort by. If `orders` is unspecified, all - * values are sorted in ascending order. Otherwise, a value is sorted in - * ascending order if its corresponding order is "asc", and descending if "desc". - * - * If a property name is provided for an iteratee the created `_.property` - * style callback returns the property value of the given element. - * - * If an object is provided for an iteratee the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. - * @param {boolean[]} [orders] The sort orders of `iteratees`. - * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. - * @returns {Array} Returns the new sorted array. - * @example - * - * var users = [ - * { 'user': 'fred', 'age': 48 }, - * { 'user': 'barney', 'age': 34 }, - * { 'user': 'fred', 'age': 42 }, - * { 'user': 'barney', 'age': 36 } - * ]; - * - * // sort by `user` in ascending order and by `age` in descending order - * _.map(_.sortByOrder(users, ['user', 'age'], ['asc', 'desc']), _.values); - * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] - */ - function sortByOrder(collection, iteratees, orders, guard) { - if (collection == null) { - return []; - } - if (guard && isIterateeCall(iteratees, orders, guard)) { - orders = undefined; - } - if (!isArray(iteratees)) { - iteratees = iteratees == null ? [] : [iteratees]; - } - if (!isArray(orders)) { - orders = orders == null ? [] : [orders]; - } - return baseSortByOrder(collection, iteratees, orders); - } - - /** - * Performs a deep comparison between each element in `collection` and the - * source object, returning an array of all elements that have equivalent - * property values. - * - * **Note:** This method supports comparing arrays, booleans, `Date` objects, - * numbers, `Object` objects, regexes, and strings. Objects are compared by - * their own, not inherited, enumerable properties. For comparing a single - * own or inherited property value see `_.matchesProperty`. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to search. - * @param {Object} source The object of property values to match. - * @returns {Array} Returns the new filtered array. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false, 'pets': ['hoppy'] }, - * { 'user': 'fred', 'age': 40, 'active': true, 'pets': ['baby puss', 'dino'] } - * ]; - * - * _.pluck(_.where(users, { 'age': 36, 'active': false }), 'user'); - * // => ['barney'] - * - * _.pluck(_.where(users, { 'pets': ['dino'] }), 'user'); - * // => ['fred'] - */ - function where(collection, source) { - return filter(collection, baseMatches(source)); - } - - /*------------------------------------------------------------------------*/ - - /** - * Gets the number of milliseconds that have elapsed since the Unix epoch - * (1 January 1970 00:00:00 UTC). - * - * @static - * @memberOf _ - * @category Date - * @example - * - * _.defer(function(stamp) { - * console.log(_.now() - stamp); - * }, _.now()); - * // => logs the number of milliseconds it took for the deferred function to be invoked - */ - var now = nativeNow || function() { - return new Date().getTime(); - }; - - /*------------------------------------------------------------------------*/ - - /** - * The opposite of `_.before`; this method creates a function that invokes - * `func` once it is called `n` or more times. - * - * @static - * @memberOf _ - * @category Function - * @param {number} n The number of calls before `func` is invoked. - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var saves = ['profile', 'settings']; - * - * var done = _.after(saves.length, function() { - * console.log('done saving!'); - * }); - * - * _.forEach(saves, function(type) { - * asyncSave({ 'type': type, 'complete': done }); - * }); - * // => logs 'done saving!' after the two async saves have completed - */ - function after(n, func) { - if (typeof func != 'function') { - if (typeof n == 'function') { - var temp = n; - n = func; - func = temp; - } else { - throw new TypeError(FUNC_ERROR_TEXT); - } - } - n = nativeIsFinite(n = +n) ? n : 0; - return function() { - if (--n < 1) { - return func.apply(this, arguments); - } - }; - } - - /** - * Creates a function that accepts up to `n` arguments ignoring any - * additional arguments. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to cap arguments for. - * @param {number} [n=func.length] The arity cap. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {Function} Returns the new function. - * @example - * - * _.map(['6', '8', '10'], _.ary(parseInt, 1)); - * // => [6, 8, 10] - */ - function ary(func, n, guard) { - if (guard && isIterateeCall(func, n, guard)) { - n = undefined; - } - n = (func && n == null) ? func.length : nativeMax(+n || 0, 0); - return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n); - } - - /** - * Creates a function that invokes `func`, with the `this` binding and arguments - * of the created function, while it is called less than `n` times. Subsequent - * calls to the created function return the result of the last `func` invocation. - * - * @static - * @memberOf _ - * @category Function - * @param {number} n The number of calls at which `func` is no longer invoked. - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * jQuery('#add').on('click', _.before(5, addContactToList)); - * // => allows adding up to 4 contacts to the list - */ - function before(n, func) { - var result; - if (typeof func != 'function') { - if (typeof n == 'function') { - var temp = n; - n = func; - func = temp; - } else { - throw new TypeError(FUNC_ERROR_TEXT); - } - } - return function() { - if (--n > 0) { - result = func.apply(this, arguments); - } - if (n <= 1) { - func = undefined; - } - return result; - }; - } - - /** - * Creates a function that invokes `func` with the `this` binding of `thisArg` - * and prepends any additional `_.bind` arguments to those provided to the - * bound function. - * - * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, - * may be used as a placeholder for partially applied arguments. - * - * **Note:** Unlike native `Function#bind` this method does not set the "length" - * property of bound functions. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to bind. - * @param {*} thisArg The `this` binding of `func`. - * @param {...*} [partials] The arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * var greet = function(greeting, punctuation) { - * return greeting + ' ' + this.user + punctuation; - * }; - * - * var object = { 'user': 'fred' }; - * - * var bound = _.bind(greet, object, 'hi'); - * bound('!'); - * // => 'hi fred!' - * - * // using placeholders - * var bound = _.bind(greet, object, _, '!'); - * bound('hi'); - * // => 'hi fred!' - */ - var bind = restParam(function(func, thisArg, partials) { - var bitmask = BIND_FLAG; - if (partials.length) { - var holders = replaceHolders(partials, bind.placeholder); - bitmask |= PARTIAL_FLAG; - } - return createWrapper(func, bitmask, thisArg, partials, holders); - }); - - /** - * Binds methods of an object to the object itself, overwriting the existing - * method. Method names may be specified as individual arguments or as arrays - * of method names. If no method names are provided all enumerable function - * properties, own and inherited, of `object` are bound. - * - * **Note:** This method does not set the "length" property of bound functions. - * - * @static - * @memberOf _ - * @category Function - * @param {Object} object The object to bind and assign the bound methods to. - * @param {...(string|string[])} [methodNames] The object method names to bind, - * specified as individual method names or arrays of method names. - * @returns {Object} Returns `object`. - * @example - * - * var view = { - * 'label': 'docs', - * 'onClick': function() { - * console.log('clicked ' + this.label); - * } - * }; - * - * _.bindAll(view); - * jQuery('#docs').on('click', view.onClick); - * // => logs 'clicked docs' when the element is clicked - */ - var bindAll = restParam(function(object, methodNames) { - methodNames = methodNames.length ? baseFlatten(methodNames) : functions(object); - - var index = -1, - length = methodNames.length; - - while (++index < length) { - var key = methodNames[index]; - object[key] = createWrapper(object[key], BIND_FLAG, object); - } - return object; - }); - - /** - * Creates a function that invokes the method at `object[key]` and prepends - * any additional `_.bindKey` arguments to those provided to the bound function. - * - * This method differs from `_.bind` by allowing bound functions to reference - * methods that may be redefined or don't yet exist. - * See [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern) - * for more details. - * - * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic - * builds, may be used as a placeholder for partially applied arguments. - * - * @static - * @memberOf _ - * @category Function - * @param {Object} object The object the method belongs to. - * @param {string} key The key of the method. - * @param {...*} [partials] The arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * var object = { - * 'user': 'fred', - * 'greet': function(greeting, punctuation) { - * return greeting + ' ' + this.user + punctuation; - * } - * }; - * - * var bound = _.bindKey(object, 'greet', 'hi'); - * bound('!'); - * // => 'hi fred!' - * - * object.greet = function(greeting, punctuation) { - * return greeting + 'ya ' + this.user + punctuation; - * }; - * - * bound('!'); - * // => 'hiya fred!' - * - * // using placeholders - * var bound = _.bindKey(object, 'greet', _, '!'); - * bound('hi'); - * // => 'hiya fred!' - */ - var bindKey = restParam(function(object, key, partials) { - var bitmask = BIND_FLAG | BIND_KEY_FLAG; - if (partials.length) { - var holders = replaceHolders(partials, bindKey.placeholder); - bitmask |= PARTIAL_FLAG; - } - return createWrapper(key, bitmask, object, partials, holders); - }); - - /** - * Creates a function that accepts one or more arguments of `func` that when - * called either invokes `func` returning its result, if all `func` arguments - * have been provided, or returns a function that accepts one or more of the - * remaining `func` arguments, and so on. The arity of `func` may be specified - * if `func.length` is not sufficient. - * - * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, - * may be used as a placeholder for provided arguments. - * - * **Note:** This method does not set the "length" property of curried functions. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to curry. - * @param {number} [arity=func.length] The arity of `func`. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {Function} Returns the new curried function. - * @example - * - * var abc = function(a, b, c) { - * return [a, b, c]; - * }; - * - * var curried = _.curry(abc); - * - * curried(1)(2)(3); - * // => [1, 2, 3] - * - * curried(1, 2)(3); - * // => [1, 2, 3] - * - * curried(1, 2, 3); - * // => [1, 2, 3] - * - * // using placeholders - * curried(1)(_, 3)(2); - * // => [1, 2, 3] - */ - var curry = createCurry(CURRY_FLAG); - - /** - * This method is like `_.curry` except that arguments are applied to `func` - * in the manner of `_.partialRight` instead of `_.partial`. - * - * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic - * builds, may be used as a placeholder for provided arguments. - * - * **Note:** This method does not set the "length" property of curried functions. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to curry. - * @param {number} [arity=func.length] The arity of `func`. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {Function} Returns the new curried function. - * @example - * - * var abc = function(a, b, c) { - * return [a, b, c]; - * }; - * - * var curried = _.curryRight(abc); - * - * curried(3)(2)(1); - * // => [1, 2, 3] - * - * curried(2, 3)(1); - * // => [1, 2, 3] - * - * curried(1, 2, 3); - * // => [1, 2, 3] - * - * // using placeholders - * curried(3)(1, _)(2); - * // => [1, 2, 3] - */ - var curryRight = createCurry(CURRY_RIGHT_FLAG); - - /** - * Creates a debounced function that delays invoking `func` until after `wait` - * milliseconds have elapsed since the last time the debounced function was - * invoked. The debounced function comes with a `cancel` method to cancel - * delayed invocations. Provide an options object to indicate that `func` - * should be invoked on the leading and/or trailing edge of the `wait` timeout. - * Subsequent calls to the debounced function return the result of the last - * `func` invocation. - * - * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked - * on the trailing edge of the timeout only if the the debounced function is - * invoked more than once during the `wait` timeout. - * - * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) - * for details over the differences between `_.debounce` and `_.throttle`. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to debounce. - * @param {number} [wait=0] The number of milliseconds to delay. - * @param {Object} [options] The options object. - * @param {boolean} [options.leading=false] Specify invoking on the leading - * edge of the timeout. - * @param {number} [options.maxWait] The maximum time `func` is allowed to be - * delayed before it is invoked. - * @param {boolean} [options.trailing=true] Specify invoking on the trailing - * edge of the timeout. - * @returns {Function} Returns the new debounced function. - * @example - * - * // avoid costly calculations while the window size is in flux - * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); - * - * // invoke `sendMail` when the click event is fired, debouncing subsequent calls - * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { - * 'leading': true, - * 'trailing': false - * })); - * - * // ensure `batchLog` is invoked once after 1 second of debounced calls - * var source = new EventSource('/stream'); - * jQuery(source).on('message', _.debounce(batchLog, 250, { - * 'maxWait': 1000 - * })); - * - * // cancel a debounced call - * var todoChanges = _.debounce(batchLog, 1000); - * Object.observe(models.todo, todoChanges); - * - * Object.observe(models, function(changes) { - * if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) { - * todoChanges.cancel(); - * } - * }, ['delete']); - * - * // ...at some point `models.todo` is changed - * models.todo.completed = true; - * - * // ...before 1 second has passed `models.todo` is deleted - * // which cancels the debounced `todoChanges` call - * delete models.todo; - */ - function debounce(func, wait, options) { - var args, - maxTimeoutId, - result, - stamp, - thisArg, - timeoutId, - trailingCall, - lastCalled = 0, - maxWait = false, - trailing = true; - - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - wait = wait < 0 ? 0 : (+wait || 0); - if (options === true) { - var leading = true; - trailing = false; - } else if (isObject(options)) { - leading = !!options.leading; - maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait); - trailing = 'trailing' in options ? !!options.trailing : trailing; - } - - function cancel() { - if (timeoutId) { - clearTimeout(timeoutId); - } - if (maxTimeoutId) { - clearTimeout(maxTimeoutId); - } - lastCalled = 0; - maxTimeoutId = timeoutId = trailingCall = undefined; - } - - function complete(isCalled, id) { - if (id) { - clearTimeout(id); - } - maxTimeoutId = timeoutId = trailingCall = undefined; - if (isCalled) { - lastCalled = now(); - result = func.apply(thisArg, args); - if (!timeoutId && !maxTimeoutId) { - args = thisArg = undefined; - } - } - } - - function delayed() { - var remaining = wait - (now() - stamp); - if (remaining <= 0 || remaining > wait) { - complete(trailingCall, maxTimeoutId); - } else { - timeoutId = setTimeout(delayed, remaining); - } - } - - function maxDelayed() { - complete(trailing, timeoutId); - } - - function debounced() { - args = arguments; - stamp = now(); - thisArg = this; - trailingCall = trailing && (timeoutId || !leading); - - if (maxWait === false) { - var leadingCall = leading && !timeoutId; - } else { - if (!maxTimeoutId && !leading) { - lastCalled = stamp; - } - var remaining = maxWait - (stamp - lastCalled), - isCalled = remaining <= 0 || remaining > maxWait; - - if (isCalled) { - if (maxTimeoutId) { - maxTimeoutId = clearTimeout(maxTimeoutId); - } - lastCalled = stamp; - result = func.apply(thisArg, args); - } - else if (!maxTimeoutId) { - maxTimeoutId = setTimeout(maxDelayed, remaining); - } - } - if (isCalled && timeoutId) { - timeoutId = clearTimeout(timeoutId); - } - else if (!timeoutId && wait !== maxWait) { - timeoutId = setTimeout(delayed, wait); - } - if (leadingCall) { - isCalled = true; - result = func.apply(thisArg, args); - } - if (isCalled && !timeoutId && !maxTimeoutId) { - args = thisArg = undefined; - } - return result; - } - debounced.cancel = cancel; - return debounced; - } - - /** - * Defers invoking the `func` until the current call stack has cleared. Any - * additional arguments are provided to `func` when it is invoked. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to defer. - * @param {...*} [args] The arguments to invoke the function with. - * @returns {number} Returns the timer id. - * @example - * - * _.defer(function(text) { - * console.log(text); - * }, 'deferred'); - * // logs 'deferred' after one or more milliseconds - */ - var defer = restParam(function(func, args) { - return baseDelay(func, 1, args); - }); - - /** - * Invokes `func` after `wait` milliseconds. Any additional arguments are - * provided to `func` when it is invoked. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to delay. - * @param {number} wait The number of milliseconds to delay invocation. - * @param {...*} [args] The arguments to invoke the function with. - * @returns {number} Returns the timer id. - * @example - * - * _.delay(function(text) { - * console.log(text); - * }, 1000, 'later'); - * // => logs 'later' after one second - */ - var delay = restParam(function(func, wait, args) { - return baseDelay(func, wait, args); - }); - - /** - * Creates a function that returns the result of invoking the provided - * functions with the `this` binding of the created function, where each - * successive invocation is supplied the return value of the previous. - * - * @static - * @memberOf _ - * @category Function - * @param {...Function} [funcs] Functions to invoke. - * @returns {Function} Returns the new function. - * @example - * - * function square(n) { - * return n * n; - * } - * - * var addSquare = _.flow(_.add, square); - * addSquare(1, 2); - * // => 9 - */ - var flow = createFlow(); - - /** - * This method is like `_.flow` except that it creates a function that - * invokes the provided functions from right to left. - * - * @static - * @memberOf _ - * @alias backflow, compose - * @category Function - * @param {...Function} [funcs] Functions to invoke. - * @returns {Function} Returns the new function. - * @example - * - * function square(n) { - * return n * n; - * } - * - * var addSquare = _.flowRight(square, _.add); - * addSquare(1, 2); - * // => 9 - */ - var flowRight = createFlow(true); - - /** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided it determines the cache key for storing the result based on the - * arguments provided to the memoized function. By default, the first argument - * provided to the memoized function is coerced to a string and used as the - * cache key. The `func` is invoked with the `this` binding of the memoized - * function. - * - * **Note:** The cache is exposed as the `cache` property on the memoized - * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object) - * method interface of `get`, `has`, and `set`. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] The function to resolve the cache key. - * @returns {Function} Returns the new memoizing function. - * @example - * - * var upperCase = _.memoize(function(string) { - * return string.toUpperCase(); - * }); - * - * upperCase('fred'); - * // => 'FRED' - * - * // modifying the result cache - * upperCase.cache.set('fred', 'BARNEY'); - * upperCase('fred'); - * // => 'BARNEY' - * - * // replacing `_.memoize.Cache` - * var object = { 'user': 'fred' }; - * var other = { 'user': 'barney' }; - * var identity = _.memoize(_.identity); - * - * identity(object); - * // => { 'user': 'fred' } - * identity(other); - * // => { 'user': 'fred' } - * - * _.memoize.Cache = WeakMap; - * var identity = _.memoize(_.identity); - * - * identity(object); - * // => { 'user': 'fred' } - * identity(other); - * // => { 'user': 'barney' } - */ - function memoize(func, resolver) { - if (typeof func != 'function' || (resolver && typeof resolver != 'function')) { - throw new TypeError(FUNC_ERROR_TEXT); - } - var memoized = function() { - var args = arguments, - key = resolver ? resolver.apply(this, args) : args[0], - cache = memoized.cache; - - if (cache.has(key)) { - return cache.get(key); - } - var result = func.apply(this, args); - memoized.cache = cache.set(key, result); - return result; - }; - memoized.cache = new memoize.Cache; - return memoized; - } - - /** - * Creates a function that runs each argument through a corresponding - * transform function. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to wrap. - * @param {...(Function|Function[])} [transforms] The functions to transform - * arguments, specified as individual functions or arrays of functions. - * @returns {Function} Returns the new function. - * @example - * - * function doubled(n) { - * return n * 2; - * } - * - * function square(n) { - * return n * n; - * } - * - * var modded = _.modArgs(function(x, y) { - * return [x, y]; - * }, square, doubled); - * - * modded(1, 2); - * // => [1, 4] - * - * modded(5, 10); - * // => [25, 20] - */ - var modArgs = restParam(function(func, transforms) { - transforms = baseFlatten(transforms); - if (typeof func != 'function' || !arrayEvery(transforms, baseIsFunction)) { - throw new TypeError(FUNC_ERROR_TEXT); - } - var length = transforms.length; - return restParam(function(args) { - var index = nativeMin(args.length, length); - while (index--) { - args[index] = transforms[index](args[index]); - } - return func.apply(this, args); - }); - }); - - /** - * Creates a function that negates the result of the predicate `func`. The - * `func` predicate is invoked with the `this` binding and arguments of the - * created function. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} predicate The predicate to negate. - * @returns {Function} Returns the new function. - * @example - * - * function isEven(n) { - * return n % 2 == 0; - * } - * - * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); - * // => [1, 3, 5] - */ - function negate(predicate) { - if (typeof predicate != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - return function() { - return !predicate.apply(this, arguments); - }; - } - - /** - * Creates a function that is restricted to invoking `func` once. Repeat calls - * to the function return the value of the first call. The `func` is invoked - * with the `this` binding and arguments of the created function. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var initialize = _.once(createApplication); - * initialize(); - * initialize(); - * // `initialize` invokes `createApplication` once - */ - function once(func) { - return before(2, func); - } - - /** - * Creates a function that invokes `func` with `partial` arguments prepended - * to those provided to the new function. This method is like `_.bind` except - * it does **not** alter the `this` binding. - * - * The `_.partial.placeholder` value, which defaults to `_` in monolithic - * builds, may be used as a placeholder for partially applied arguments. - * - * **Note:** This method does not set the "length" property of partially - * applied functions. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to partially apply arguments to. - * @param {...*} [partials] The arguments to be partially applied. - * @returns {Function} Returns the new partially applied function. - * @example - * - * var greet = function(greeting, name) { - * return greeting + ' ' + name; - * }; - * - * var sayHelloTo = _.partial(greet, 'hello'); - * sayHelloTo('fred'); - * // => 'hello fred' - * - * // using placeholders - * var greetFred = _.partial(greet, _, 'fred'); - * greetFred('hi'); - * // => 'hi fred' - */ - var partial = createPartial(PARTIAL_FLAG); - - /** - * This method is like `_.partial` except that partially applied arguments - * are appended to those provided to the new function. - * - * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic - * builds, may be used as a placeholder for partially applied arguments. - * - * **Note:** This method does not set the "length" property of partially - * applied functions. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to partially apply arguments to. - * @param {...*} [partials] The arguments to be partially applied. - * @returns {Function} Returns the new partially applied function. - * @example - * - * var greet = function(greeting, name) { - * return greeting + ' ' + name; - * }; - * - * var greetFred = _.partialRight(greet, 'fred'); - * greetFred('hi'); - * // => 'hi fred' - * - * // using placeholders - * var sayHelloTo = _.partialRight(greet, 'hello', _); - * sayHelloTo('fred'); - * // => 'hello fred' - */ - var partialRight = createPartial(PARTIAL_RIGHT_FLAG); - - /** - * Creates a function that invokes `func` with arguments arranged according - * to the specified indexes where the argument value at the first index is - * provided as the first argument, the argument value at the second index is - * provided as the second argument, and so on. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to rearrange arguments for. - * @param {...(number|number[])} indexes The arranged argument indexes, - * specified as individual indexes or arrays of indexes. - * @returns {Function} Returns the new function. - * @example - * - * var rearged = _.rearg(function(a, b, c) { - * return [a, b, c]; - * }, 2, 0, 1); - * - * rearged('b', 'c', 'a') - * // => ['a', 'b', 'c'] - * - * var map = _.rearg(_.map, [1, 0]); - * map(function(n) { - * return n * 3; - * }, [1, 2, 3]); - * // => [3, 6, 9] - */ - var rearg = restParam(function(func, indexes) { - return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes)); - }); - - /** - * Creates a function that invokes `func` with the `this` binding of the - * created function and arguments from `start` and beyond provided as an array. - * - * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters). - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @returns {Function} Returns the new function. - * @example - * - * var say = _.restParam(function(what, names) { - * return what + ' ' + _.initial(names).join(', ') + - * (_.size(names) > 1 ? ', & ' : '') + _.last(names); - * }); - * - * say('hello', 'fred', 'barney', 'pebbles'); - * // => 'hello fred, barney, & pebbles' - */ - function restParam(func, start) { - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0); - return function() { - var args = arguments, - index = -1, - length = nativeMax(args.length - start, 0), - rest = Array(length); - - while (++index < length) { - rest[index] = args[start + index]; - } - switch (start) { - case 0: return func.call(this, rest); - case 1: return func.call(this, args[0], rest); - case 2: return func.call(this, args[0], args[1], rest); - } - var otherArgs = Array(start + 1); - index = -1; - while (++index < start) { - otherArgs[index] = args[index]; - } - otherArgs[start] = rest; - return func.apply(this, otherArgs); - }; - } - - /** - * Creates a function that invokes `func` with the `this` binding of the created - * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3). - * - * **Note:** This method is based on the [spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator). - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to spread arguments over. - * @returns {Function} Returns the new function. - * @example - * - * var say = _.spread(function(who, what) { - * return who + ' says ' + what; - * }); - * - * say(['fred', 'hello']); - * // => 'fred says hello' - * - * // with a Promise - * var numbers = Promise.all([ - * Promise.resolve(40), - * Promise.resolve(36) - * ]); - * - * numbers.then(_.spread(function(x, y) { - * return x + y; - * })); - * // => a Promise of 76 - */ - function spread(func) { - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - return function(array) { - return func.apply(this, array); - }; - } - - /** - * Creates a throttled function that only invokes `func` at most once per - * every `wait` milliseconds. The throttled function comes with a `cancel` - * method to cancel delayed invocations. Provide an options object to indicate - * that `func` should be invoked on the leading and/or trailing edge of the - * `wait` timeout. Subsequent calls to the throttled function return the - * result of the last `func` call. - * - * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked - * on the trailing edge of the timeout only if the the throttled function is - * invoked more than once during the `wait` timeout. - * - * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) - * for details over the differences between `_.throttle` and `_.debounce`. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to throttle. - * @param {number} [wait=0] The number of milliseconds to throttle invocations to. - * @param {Object} [options] The options object. - * @param {boolean} [options.leading=true] Specify invoking on the leading - * edge of the timeout. - * @param {boolean} [options.trailing=true] Specify invoking on the trailing - * edge of the timeout. - * @returns {Function} Returns the new throttled function. - * @example - * - * // avoid excessively updating the position while scrolling - * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); - * - * // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes - * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { - * 'trailing': false - * })); - * - * // cancel a trailing throttled call - * jQuery(window).on('popstate', throttled.cancel); - */ - function throttle(func, wait, options) { - var leading = true, - trailing = true; - - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - if (options === false) { - leading = false; - } else if (isObject(options)) { - leading = 'leading' in options ? !!options.leading : leading; - trailing = 'trailing' in options ? !!options.trailing : trailing; - } - return debounce(func, wait, { 'leading': leading, 'maxWait': +wait, 'trailing': trailing }); - } - - /** - * Creates a function that provides `value` to the wrapper function as its - * first argument. Any additional arguments provided to the function are - * appended to those provided to the wrapper function. The wrapper is invoked - * with the `this` binding of the created function. - * - * @static - * @memberOf _ - * @category Function - * @param {*} value The value to wrap. - * @param {Function} wrapper The wrapper function. - * @returns {Function} Returns the new function. - * @example - * - * var p = _.wrap(_.escape, function(func, text) { - * return '

' + func(text) + '

'; - * }); - * - * p('fred, barney, & pebbles'); - * // => '

fred, barney, & pebbles

' - */ - function wrap(value, wrapper) { - wrapper = wrapper == null ? identity : wrapper; - return createWrapper(wrapper, PARTIAL_FLAG, undefined, [value], []); - } - - /*------------------------------------------------------------------------*/ - - /** - * Creates a clone of `value`. If `isDeep` is `true` nested objects are cloned, - * otherwise they are assigned by reference. If `customizer` is provided it is - * invoked to produce the cloned values. If `customizer` returns `undefined` - * cloning is handled by the method instead. The `customizer` is bound to - * `thisArg` and invoked with two argument; (value [, index|key, object]). - * - * **Note:** This method is loosely based on the - * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm). - * The enumerable properties of `arguments` objects and objects created by - * constructors other than `Object` are cloned to plain `Object` objects. An - * empty object is returned for uncloneable values such as functions, DOM nodes, - * Maps, Sets, and WeakMaps. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @param {Function} [customizer] The function to customize cloning values. - * @param {*} [thisArg] The `this` binding of `customizer`. - * @returns {*} Returns the cloned value. - * @example - * - * var users = [ - * { 'user': 'barney' }, - * { 'user': 'fred' } - * ]; - * - * var shallow = _.clone(users); - * shallow[0] === users[0]; - * // => true - * - * var deep = _.clone(users, true); - * deep[0] === users[0]; - * // => false - * - * // using a customizer callback - * var el = _.clone(document.body, function(value) { - * if (_.isElement(value)) { - * return value.cloneNode(false); - * } - * }); - * - * el === document.body - * // => false - * el.nodeName - * // => BODY - * el.childNodes.length; - * // => 0 - */ - function clone(value, isDeep, customizer, thisArg) { - if (isDeep && typeof isDeep != 'boolean' && isIterateeCall(value, isDeep, customizer)) { - isDeep = false; - } - else if (typeof isDeep == 'function') { - thisArg = customizer; - customizer = isDeep; - isDeep = false; - } - return typeof customizer == 'function' - ? baseClone(value, isDeep, bindCallback(customizer, thisArg, 1)) - : baseClone(value, isDeep); - } - - /** - * Creates a deep clone of `value`. If `customizer` is provided it is invoked - * to produce the cloned values. If `customizer` returns `undefined` cloning - * is handled by the method instead. The `customizer` is bound to `thisArg` - * and invoked with two argument; (value [, index|key, object]). - * - * **Note:** This method is loosely based on the - * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm). - * The enumerable properties of `arguments` objects and objects created by - * constructors other than `Object` are cloned to plain `Object` objects. An - * empty object is returned for uncloneable values such as functions, DOM nodes, - * Maps, Sets, and WeakMaps. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to deep clone. - * @param {Function} [customizer] The function to customize cloning values. - * @param {*} [thisArg] The `this` binding of `customizer`. - * @returns {*} Returns the deep cloned value. - * @example - * - * var users = [ - * { 'user': 'barney' }, - * { 'user': 'fred' } - * ]; - * - * var deep = _.cloneDeep(users); - * deep[0] === users[0]; - * // => false - * - * // using a customizer callback - * var el = _.cloneDeep(document.body, function(value) { - * if (_.isElement(value)) { - * return value.cloneNode(true); - * } - * }); - * - * el === document.body - * // => false - * el.nodeName - * // => BODY - * el.childNodes.length; - * // => 20 - */ - function cloneDeep(value, customizer, thisArg) { - return typeof customizer == 'function' - ? baseClone(value, true, bindCallback(customizer, thisArg, 1)) - : baseClone(value, true); - } - - /** - * Checks if `value` is greater than `other`. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`. - * @example - * - * _.gt(3, 1); - * // => true - * - * _.gt(3, 3); - * // => false - * - * _.gt(1, 3); - * // => false - */ - function gt(value, other) { - return value > other; - } - - /** - * Checks if `value` is greater than or equal to `other`. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is greater than or equal to `other`, else `false`. - * @example - * - * _.gte(3, 1); - * // => true - * - * _.gte(3, 3); - * // => true - * - * _.gte(1, 3); - * // => false - */ - function gte(value, other) { - return value >= other; - } - - /** - * Checks if `value` is classified as an `arguments` object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isArguments(function() { return arguments; }()); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false - */ - function isArguments(value) { - return isObjectLike(value) && isArrayLike(value) && - hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee'); - } - - /** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(function() { return arguments; }()); - * // => false - */ - var isArray = nativeIsArray || function(value) { - return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag; - }; - - /** - * Checks if `value` is classified as a boolean primitive or object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isBoolean(false); - * // => true - * - * _.isBoolean(null); - * // => false - */ - function isBoolean(value) { - return value === true || value === false || (isObjectLike(value) && objToString.call(value) == boolTag); - } - - /** - * Checks if `value` is classified as a `Date` object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isDate(new Date); - * // => true - * - * _.isDate('Mon April 23 2012'); - * // => false - */ - function isDate(value) { - return isObjectLike(value) && objToString.call(value) == dateTag; - } - - /** - * Checks if `value` is a DOM element. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. - * @example - * - * _.isElement(document.body); - * // => true - * - * _.isElement(''); - * // => false - */ - function isElement(value) { - return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value); - } - - /** - * Checks if `value` is empty. A value is considered empty unless it is an - * `arguments` object, array, string, or jQuery-like collection with a length - * greater than `0` or an object with own enumerable properties. - * - * @static - * @memberOf _ - * @category Lang - * @param {Array|Object|string} value The value to inspect. - * @returns {boolean} Returns `true` if `value` is empty, else `false`. - * @example - * - * _.isEmpty(null); - * // => true - * - * _.isEmpty(true); - * // => true - * - * _.isEmpty(1); - * // => true - * - * _.isEmpty([1, 2, 3]); - * // => false - * - * _.isEmpty({ 'a': 1 }); - * // => false - */ - function isEmpty(value) { - if (value == null) { - return true; - } - if (isArrayLike(value) && (isArray(value) || isString(value) || isArguments(value) || - (isObjectLike(value) && isFunction(value.splice)))) { - return !value.length; - } - return !keys(value).length; - } - - /** - * Performs a deep comparison between two values to determine if they are - * equivalent. If `customizer` is provided it is invoked to compare values. - * If `customizer` returns `undefined` comparisons are handled by the method - * instead. The `customizer` is bound to `thisArg` and invoked with three - * arguments: (value, other [, index|key]). - * - * **Note:** This method supports comparing arrays, booleans, `Date` objects, - * numbers, `Object` objects, regexes, and strings. Objects are compared by - * their own, not inherited, enumerable properties. Functions and DOM nodes - * are **not** supported. Provide a customizer function to extend support - * for comparing other values. - * - * @static - * @memberOf _ - * @alias eq - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @param {Function} [customizer] The function to customize value comparisons. - * @param {*} [thisArg] The `this` binding of `customizer`. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'user': 'fred' }; - * var other = { 'user': 'fred' }; - * - * object == other; - * // => false - * - * _.isEqual(object, other); - * // => true - * - * // using a customizer callback - * var array = ['hello', 'goodbye']; - * var other = ['hi', 'goodbye']; - * - * _.isEqual(array, other, function(value, other) { - * if (_.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/)) { - * return true; - * } - * }); - * // => true - */ - function isEqual(value, other, customizer, thisArg) { - customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined; - var result = customizer ? customizer(value, other) : undefined; - return result === undefined ? baseIsEqual(value, other, customizer) : !!result; - } - - /** - * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, - * `SyntaxError`, `TypeError`, or `URIError` object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an error object, else `false`. - * @example - * - * _.isError(new Error); - * // => true - * - * _.isError(Error); - * // => false - */ - function isError(value) { - return isObjectLike(value) && typeof value.message == 'string' && objToString.call(value) == errorTag; - } - - /** - * Checks if `value` is a finite primitive number. - * - * **Note:** This method is based on [`Number.isFinite`](http://ecma-international.org/ecma-262/6.0/#sec-number.isfinite). - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. - * @example - * - * _.isFinite(10); - * // => true - * - * _.isFinite('10'); - * // => false - * - * _.isFinite(true); - * // => false - * - * _.isFinite(Object(10)); - * // => false - * - * _.isFinite(Infinity); - * // => false - */ - function isFinite(value) { - return typeof value == 'number' && nativeIsFinite(value); - } - - /** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ - function isFunction(value) { - // The use of `Object#toString` avoids issues with the `typeof` operator - // in older versions of Chrome and Safari which return 'function' for regexes - // and Safari 8 equivalents which return 'object' for typed array constructors. - return isObject(value) && objToString.call(value) == funcTag; - } - - /** - * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. - * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(1); - * // => false - */ - function isObject(value) { - // Avoid a V8 JIT bug in Chrome 19-20. - // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. - var type = typeof value; - return !!value && (type == 'object' || type == 'function'); - } - - /** - * Performs a deep comparison between `object` and `source` to determine if - * `object` contains equivalent property values. If `customizer` is provided - * it is invoked to compare values. If `customizer` returns `undefined` - * comparisons are handled by the method instead. The `customizer` is bound - * to `thisArg` and invoked with three arguments: (value, other, index|key). - * - * **Note:** This method supports comparing properties of arrays, booleans, - * `Date` objects, numbers, `Object` objects, regexes, and strings. Functions - * and DOM nodes are **not** supported. Provide a customizer function to extend - * support for comparing other values. - * - * @static - * @memberOf _ - * @category Lang - * @param {Object} object The object to inspect. - * @param {Object} source The object of property values to match. - * @param {Function} [customizer] The function to customize value comparisons. - * @param {*} [thisArg] The `this` binding of `customizer`. - * @returns {boolean} Returns `true` if `object` is a match, else `false`. - * @example - * - * var object = { 'user': 'fred', 'age': 40 }; - * - * _.isMatch(object, { 'age': 40 }); - * // => true - * - * _.isMatch(object, { 'age': 36 }); - * // => false - * - * // using a customizer callback - * var object = { 'greeting': 'hello' }; - * var source = { 'greeting': 'hi' }; - * - * _.isMatch(object, source, function(value, other) { - * return _.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/) || undefined; - * }); - * // => true - */ - function isMatch(object, source, customizer, thisArg) { - customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined; - return baseIsMatch(object, getMatchData(source), customizer); - } - - /** - * Checks if `value` is `NaN`. - * - * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4) - * which returns `true` for `undefined` and other non-numeric values. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. - * @example - * - * _.isNaN(NaN); - * // => true - * - * _.isNaN(new Number(NaN)); - * // => true - * - * isNaN(undefined); - * // => true - * - * _.isNaN(undefined); - * // => false - */ - function isNaN(value) { - // An `NaN` primitive is the only value that is not equal to itself. - // Perform the `toStringTag` check first to avoid errors with some host objects in IE. - return isNumber(value) && value != +value; - } - - /** - * Checks if `value` is a native function. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, else `false`. - * @example - * - * _.isNative(Array.prototype.push); - * // => true - * - * _.isNative(_); - * // => false - */ - function isNative(value) { - if (value == null) { - return false; - } - if (isFunction(value)) { - return reIsNative.test(fnToString.call(value)); - } - return isObjectLike(value) && reIsHostCtor.test(value); - } - - /** - * Checks if `value` is `null`. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `null`, else `false`. - * @example - * - * _.isNull(null); - * // => true - * - * _.isNull(void 0); - * // => false - */ - function isNull(value) { - return value === null; - } - - /** - * Checks if `value` is classified as a `Number` primitive or object. - * - * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified - * as numbers, use the `_.isFinite` method. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isNumber(8.4); - * // => true - * - * _.isNumber(NaN); - * // => true - * - * _.isNumber('8.4'); - * // => false - */ - function isNumber(value) { - return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag); - } - - /** - * Checks if `value` is a plain object, that is, an object created by the - * `Object` constructor or one with a `[[Prototype]]` of `null`. - * - * **Note:** This method assumes objects created by the `Object` constructor - * have no inherited enumerable properties. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. - * @example - * - * function Foo() { - * this.a = 1; - * } - * - * _.isPlainObject(new Foo); - * // => false - * - * _.isPlainObject([1, 2, 3]); - * // => false - * - * _.isPlainObject({ 'x': 0, 'y': 0 }); - * // => true - * - * _.isPlainObject(Object.create(null)); - * // => true - */ - function isPlainObject(value) { - var Ctor; - - // Exit early for non `Object` objects. - if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isArguments(value)) || - (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) { - return false; - } - // IE < 9 iterates inherited properties before own properties. If the first - // iterated property is an object's own property then there are no inherited - // enumerable properties. - var result; - // In most environments an object's own properties are iterated before - // its inherited properties. If the last iterated property is an object's - // own property then there are no inherited enumerable properties. - baseForIn(value, function(subValue, key) { - result = key; - }); - return result === undefined || hasOwnProperty.call(value, result); - } - - /** - * Checks if `value` is classified as a `RegExp` object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isRegExp(/abc/); - * // => true - * - * _.isRegExp('/abc/'); - * // => false - */ - function isRegExp(value) { - return isObject(value) && objToString.call(value) == regexpTag; - } - - /** - * Checks if `value` is classified as a `String` primitive or object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isString('abc'); - * // => true - * - * _.isString(1); - * // => false - */ - function isString(value) { - return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag); - } - - /** - * Checks if `value` is classified as a typed array. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isTypedArray(new Uint8Array); - * // => true - * - * _.isTypedArray([]); - * // => false - */ - function isTypedArray(value) { - return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)]; - } - - /** - * Checks if `value` is `undefined`. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. - * @example - * - * _.isUndefined(void 0); - * // => true - * - * _.isUndefined(null); - * // => false - */ - function isUndefined(value) { - return value === undefined; - } - - /** - * Checks if `value` is less than `other`. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is less than `other`, else `false`. - * @example - * - * _.lt(1, 3); - * // => true - * - * _.lt(3, 3); - * // => false - * - * _.lt(3, 1); - * // => false - */ - function lt(value, other) { - return value < other; - } - - /** - * Checks if `value` is less than or equal to `other`. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is less than or equal to `other`, else `false`. - * @example - * - * _.lte(1, 3); - * // => true - * - * _.lte(3, 3); - * // => true - * - * _.lte(3, 1); - * // => false - */ - function lte(value, other) { - return value <= other; - } - - /** - * Converts `value` to an array. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to convert. - * @returns {Array} Returns the converted array. - * @example - * - * (function() { - * return _.toArray(arguments).slice(1); - * }(1, 2, 3)); - * // => [2, 3] - */ - function toArray(value) { - var length = value ? getLength(value) : 0; - if (!isLength(length)) { - return values(value); - } - if (!length) { - return []; - } - return arrayCopy(value); - } - - /** - * Converts `value` to a plain object flattening inherited enumerable - * properties of `value` to own properties of the plain object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to convert. - * @returns {Object} Returns the converted plain object. - * @example - * - * function Foo() { - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.assign({ 'a': 1 }, new Foo); - * // => { 'a': 1, 'b': 2 } - * - * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); - * // => { 'a': 1, 'b': 2, 'c': 3 } - */ - function toPlainObject(value) { - return baseCopy(value, keysIn(value)); - } - - /*------------------------------------------------------------------------*/ - - /** - * Recursively merges own enumerable properties of the source object(s), that - * don't resolve to `undefined` into the destination object. Subsequent sources - * overwrite property assignments of previous sources. If `customizer` is - * provided it is invoked to produce the merged values of the destination and - * source properties. If `customizer` returns `undefined` merging is handled - * by the method instead. The `customizer` is bound to `thisArg` and invoked - * with five arguments: (objectValue, sourceValue, key, object, source). - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @param {Function} [customizer] The function to customize assigned values. - * @param {*} [thisArg] The `this` binding of `customizer`. - * @returns {Object} Returns `object`. - * @example - * - * var users = { - * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] - * }; - * - * var ages = { - * 'data': [{ 'age': 36 }, { 'age': 40 }] - * }; - * - * _.merge(users, ages); - * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] } - * - * // using a customizer callback - * var object = { - * 'fruits': ['apple'], - * 'vegetables': ['beet'] - * }; - * - * var other = { - * 'fruits': ['banana'], - * 'vegetables': ['carrot'] - * }; - * - * _.merge(object, other, function(a, b) { - * if (_.isArray(a)) { - * return a.concat(b); - * } - * }); - * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] } - */ - var merge = createAssigner(baseMerge); - - /** - * Assigns own enumerable properties of source object(s) to the destination - * object. Subsequent sources overwrite property assignments of previous sources. - * If `customizer` is provided it is invoked to produce the assigned values. - * The `customizer` is bound to `thisArg` and invoked with five arguments: - * (objectValue, sourceValue, key, object, source). - * - * **Note:** This method mutates `object` and is based on - * [`Object.assign`](http://ecma-international.org/ecma-262/6.0/#sec-object.assign). - * - * @static - * @memberOf _ - * @alias extend - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @param {Function} [customizer] The function to customize assigned values. - * @param {*} [thisArg] The `this` binding of `customizer`. - * @returns {Object} Returns `object`. - * @example - * - * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' }); - * // => { 'user': 'fred', 'age': 40 } - * - * // using a customizer callback - * var defaults = _.partialRight(_.assign, function(value, other) { - * return _.isUndefined(value) ? other : value; - * }); - * - * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); - * // => { 'user': 'barney', 'age': 36 } - */ - var assign = createAssigner(function(object, source, customizer) { - return customizer - ? assignWith(object, source, customizer) - : baseAssign(object, source); - }); - - /** - * Creates an object that inherits from the given `prototype` object. If a - * `properties` object is provided its own enumerable properties are assigned - * to the created object. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} prototype The object to inherit from. - * @param {Object} [properties] The properties to assign to the object. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {Object} Returns the new object. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * function Circle() { - * Shape.call(this); - * } - * - * Circle.prototype = _.create(Shape.prototype, { - * 'constructor': Circle - * }); - * - * var circle = new Circle; - * circle instanceof Circle; - * // => true - * - * circle instanceof Shape; - * // => true - */ - function create(prototype, properties, guard) { - var result = baseCreate(prototype); - if (guard && isIterateeCall(prototype, properties, guard)) { - properties = undefined; - } - return properties ? baseAssign(result, properties) : result; - } - - /** - * Assigns own enumerable properties of source object(s) to the destination - * object for all destination properties that resolve to `undefined`. Once a - * property is set, additional values of the same property are ignored. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @example - * - * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); - * // => { 'user': 'barney', 'age': 36 } - */ - var defaults = createDefaults(assign, assignDefaults); - - /** - * This method is like `_.defaults` except that it recursively assigns - * default properties. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @example - * - * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } }); - * // => { 'user': { 'name': 'barney', 'age': 36 } } - * - */ - var defaultsDeep = createDefaults(merge, mergeDefaults); - - /** - * This method is like `_.find` except that it returns the key of the first - * element `predicate` returns truthy for instead of the element itself. - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to search. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {string|undefined} Returns the key of the matched element, else `undefined`. - * @example - * - * var users = { - * 'barney': { 'age': 36, 'active': true }, - * 'fred': { 'age': 40, 'active': false }, - * 'pebbles': { 'age': 1, 'active': true } - * }; - * - * _.findKey(users, function(chr) { - * return chr.age < 40; - * }); - * // => 'barney' (iteration order is not guaranteed) - * - * // using the `_.matches` callback shorthand - * _.findKey(users, { 'age': 1, 'active': true }); - * // => 'pebbles' - * - * // using the `_.matchesProperty` callback shorthand - * _.findKey(users, 'active', false); - * // => 'fred' - * - * // using the `_.property` callback shorthand - * _.findKey(users, 'active'); - * // => 'barney' - */ - var findKey = createFindKey(baseForOwn); - - /** - * This method is like `_.findKey` except that it iterates over elements of - * a collection in the opposite order. - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to search. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {string|undefined} Returns the key of the matched element, else `undefined`. - * @example - * - * var users = { - * 'barney': { 'age': 36, 'active': true }, - * 'fred': { 'age': 40, 'active': false }, - * 'pebbles': { 'age': 1, 'active': true } - * }; - * - * _.findLastKey(users, function(chr) { - * return chr.age < 40; - * }); - * // => returns `pebbles` assuming `_.findKey` returns `barney` - * - * // using the `_.matches` callback shorthand - * _.findLastKey(users, { 'age': 36, 'active': true }); - * // => 'barney' - * - * // using the `_.matchesProperty` callback shorthand - * _.findLastKey(users, 'active', false); - * // => 'fred' - * - * // using the `_.property` callback shorthand - * _.findLastKey(users, 'active'); - * // => 'pebbles' - */ - var findLastKey = createFindKey(baseForOwnRight); - - /** - * Iterates over own and inherited enumerable properties of an object invoking - * `iteratee` for each property. The `iteratee` is bound to `thisArg` and invoked - * with three arguments: (value, key, object). Iteratee functions may exit - * iteration early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Object} Returns `object`. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.forIn(new Foo, function(value, key) { - * console.log(key); - * }); - * // => logs 'a', 'b', and 'c' (iteration order is not guaranteed) - */ - var forIn = createForIn(baseFor); - - /** - * This method is like `_.forIn` except that it iterates over properties of - * `object` in the opposite order. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Object} Returns `object`. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.forInRight(new Foo, function(value, key) { - * console.log(key); - * }); - * // => logs 'c', 'b', and 'a' assuming `_.forIn ` logs 'a', 'b', and 'c' - */ - var forInRight = createForIn(baseForRight); - - /** - * Iterates over own enumerable properties of an object invoking `iteratee` - * for each property. The `iteratee` is bound to `thisArg` and invoked with - * three arguments: (value, key, object). Iteratee functions may exit iteration - * early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Object} Returns `object`. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.forOwn(new Foo, function(value, key) { - * console.log(key); - * }); - * // => logs 'a' and 'b' (iteration order is not guaranteed) - */ - var forOwn = createForOwn(baseForOwn); - - /** - * This method is like `_.forOwn` except that it iterates over properties of - * `object` in the opposite order. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Object} Returns `object`. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.forOwnRight(new Foo, function(value, key) { - * console.log(key); - * }); - * // => logs 'b' and 'a' assuming `_.forOwn` logs 'a' and 'b' - */ - var forOwnRight = createForOwn(baseForOwnRight); - - /** - * Creates an array of function property names from all enumerable properties, - * own and inherited, of `object`. - * - * @static - * @memberOf _ - * @alias methods - * @category Object - * @param {Object} object The object to inspect. - * @returns {Array} Returns the new array of property names. - * @example - * - * _.functions(_); - * // => ['after', 'ary', 'assign', ...] - */ - function functions(object) { - return baseFunctions(object, keysIn(object)); - } - - /** - * Gets the property value at `path` of `object`. If the resolved value is - * `undefined` the `defaultValue` is used in its place. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @param {*} [defaultValue] The value returned if the resolved value is `undefined`. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.get(object, 'a[0].b.c'); - * // => 3 - * - * _.get(object, ['a', '0', 'b', 'c']); - * // => 3 - * - * _.get(object, 'a.b.c', 'default'); - * // => 'default' - */ - function get(object, path, defaultValue) { - var result = object == null ? undefined : baseGet(object, toPath(path), path + ''); - return result === undefined ? defaultValue : result; - } - - /** - * Checks if `path` is a direct property. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @returns {boolean} Returns `true` if `path` is a direct property, else `false`. - * @example - * - * var object = { 'a': { 'b': { 'c': 3 } } }; - * - * _.has(object, 'a'); - * // => true - * - * _.has(object, 'a.b.c'); - * // => true - * - * _.has(object, ['a', 'b', 'c']); - * // => true - */ - function has(object, path) { - if (object == null) { - return false; - } - var result = hasOwnProperty.call(object, path); - if (!result && !isKey(path)) { - path = toPath(path); - object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); - if (object == null) { - return false; - } - path = last(path); - result = hasOwnProperty.call(object, path); - } - return result || (isLength(object.length) && isIndex(path, object.length) && - (isArray(object) || isArguments(object))); - } - - /** - * Creates an object composed of the inverted keys and values of `object`. - * If `object` contains duplicate values, subsequent values overwrite property - * assignments of previous values unless `multiValue` is `true`. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to invert. - * @param {boolean} [multiValue] Allow multiple values per key. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {Object} Returns the new inverted object. - * @example - * - * var object = { 'a': 1, 'b': 2, 'c': 1 }; - * - * _.invert(object); - * // => { '1': 'c', '2': 'b' } - * - * // with `multiValue` - * _.invert(object, true); - * // => { '1': ['a', 'c'], '2': ['b'] } - */ - function invert(object, multiValue, guard) { - if (guard && isIterateeCall(object, multiValue, guard)) { - multiValue = undefined; - } - var index = -1, - props = keys(object), - length = props.length, - result = {}; - - while (++index < length) { - var key = props[index], - value = object[key]; - - if (multiValue) { - if (hasOwnProperty.call(result, value)) { - result[value].push(key); - } else { - result[value] = [key]; - } - } - else { - result[value] = key; - } - } - return result; - } - - /** - * Creates an array of the own enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. See the - * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) - * for more details. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keys(new Foo); - * // => ['a', 'b'] (iteration order is not guaranteed) - * - * _.keys('hi'); - * // => ['0', '1'] - */ - var keys = !nativeKeys ? shimKeys : function(object) { - var Ctor = object == null ? undefined : object.constructor; - if ((typeof Ctor == 'function' && Ctor.prototype === object) || - (typeof object != 'function' && isArrayLike(object))) { - return shimKeys(object); - } - return isObject(object) ? nativeKeys(object) : []; - }; - - /** - * Creates an array of the own and inherited enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keysIn(new Foo); - * // => ['a', 'b', 'c'] (iteration order is not guaranteed) - */ - function keysIn(object) { - if (object == null) { - return []; - } - if (!isObject(object)) { - object = Object(object); - } - var length = object.length; - length = (length && isLength(length) && - (isArray(object) || isArguments(object)) && length) || 0; - - var Ctor = object.constructor, - index = -1, - isProto = typeof Ctor == 'function' && Ctor.prototype === object, - result = Array(length), - skipIndexes = length > 0; - - while (++index < length) { - result[index] = (index + ''); - } - for (var key in object) { - if (!(skipIndexes && isIndex(key, length)) && - !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { - result.push(key); - } - } - return result; - } - - /** - * The opposite of `_.mapValues`; this method creates an object with the - * same values as `object` and keys generated by running each own enumerable - * property of `object` through `iteratee`. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Object} Returns the new mapped object. - * @example - * - * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { - * return key + value; - * }); - * // => { 'a1': 1, 'b2': 2 } - */ - var mapKeys = createObjectMapper(true); - - /** - * Creates an object with the same keys as `object` and values generated by - * running each own enumerable property of `object` through `iteratee`. The - * iteratee function is bound to `thisArg` and invoked with three arguments: - * (value, key, object). - * - * If a property name is provided for `iteratee` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `iteratee` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Object} Returns the new mapped object. - * @example - * - * _.mapValues({ 'a': 1, 'b': 2 }, function(n) { - * return n * 3; - * }); - * // => { 'a': 3, 'b': 6 } - * - * var users = { - * 'fred': { 'user': 'fred', 'age': 40 }, - * 'pebbles': { 'user': 'pebbles', 'age': 1 } - * }; - * - * // using the `_.property` callback shorthand - * _.mapValues(users, 'age'); - * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) - */ - var mapValues = createObjectMapper(); - - /** - * The opposite of `_.pick`; this method creates an object composed of the - * own and inherited enumerable properties of `object` that are not omitted. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The source object. - * @param {Function|...(string|string[])} [predicate] The function invoked per - * iteration or property names to omit, specified as individual property - * names or arrays of property names. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'user': 'fred', 'age': 40 }; - * - * _.omit(object, 'age'); - * // => { 'user': 'fred' } - * - * _.omit(object, _.isNumber); - * // => { 'user': 'fred' } - */ - var omit = restParam(function(object, props) { - if (object == null) { - return {}; - } - if (typeof props[0] != 'function') { - var props = arrayMap(baseFlatten(props), String); - return pickByArray(object, baseDifference(keysIn(object), props)); - } - var predicate = bindCallback(props[0], props[1], 3); - return pickByCallback(object, function(value, key, object) { - return !predicate(value, key, object); - }); - }); - - /** - * Creates a two dimensional array of the key-value pairs for `object`, - * e.g. `[[key1, value1], [key2, value2]]`. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the new array of key-value pairs. - * @example - * - * _.pairs({ 'barney': 36, 'fred': 40 }); - * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed) - */ - function pairs(object) { - object = toObject(object); - - var index = -1, - props = keys(object), - length = props.length, - result = Array(length); - - while (++index < length) { - var key = props[index]; - result[index] = [key, object[key]]; - } - return result; - } - - /** - * Creates an object composed of the picked `object` properties. Property - * names may be specified as individual arguments or as arrays of property - * names. If `predicate` is provided it is invoked for each property of `object` - * picking the properties `predicate` returns truthy for. The predicate is - * bound to `thisArg` and invoked with three arguments: (value, key, object). - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The source object. - * @param {Function|...(string|string[])} [predicate] The function invoked per - * iteration or property names to pick, specified as individual property - * names or arrays of property names. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'user': 'fred', 'age': 40 }; - * - * _.pick(object, 'user'); - * // => { 'user': 'fred' } - * - * _.pick(object, _.isString); - * // => { 'user': 'fred' } - */ - var pick = restParam(function(object, props) { - if (object == null) { - return {}; - } - return typeof props[0] == 'function' - ? pickByCallback(object, bindCallback(props[0], props[1], 3)) - : pickByArray(object, baseFlatten(props)); - }); - - /** - * This method is like `_.get` except that if the resolved value is a function - * it is invoked with the `this` binding of its parent object and its result - * is returned. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to resolve. - * @param {*} [defaultValue] The value returned if the resolved value is `undefined`. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; - * - * _.result(object, 'a[0].b.c1'); - * // => 3 - * - * _.result(object, 'a[0].b.c2'); - * // => 4 - * - * _.result(object, 'a.b.c', 'default'); - * // => 'default' - * - * _.result(object, 'a.b.c', _.constant('default')); - * // => 'default' - */ - function result(object, path, defaultValue) { - var result = object == null ? undefined : object[path]; - if (result === undefined) { - if (object != null && !isKey(path, object)) { - path = toPath(path); - object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); - result = object == null ? undefined : object[last(path)]; - } - result = result === undefined ? defaultValue : result; - } - return isFunction(result) ? result.call(object) : result; - } - - /** - * Sets the property value of `path` on `object`. If a portion of `path` - * does not exist it is created. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to augment. - * @param {Array|string} path The path of the property to set. - * @param {*} value The value to set. - * @returns {Object} Returns `object`. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.set(object, 'a[0].b.c', 4); - * console.log(object.a[0].b.c); - * // => 4 - * - * _.set(object, 'x[0].y.z', 5); - * console.log(object.x[0].y.z); - * // => 5 - */ - function set(object, path, value) { - if (object == null) { - return object; - } - var pathKey = (path + ''); - path = (object[pathKey] != null || isKey(path, object)) ? [pathKey] : toPath(path); - - var index = -1, - length = path.length, - lastIndex = length - 1, - nested = object; - - while (nested != null && ++index < length) { - var key = path[index]; - if (isObject(nested)) { - if (index == lastIndex) { - nested[key] = value; - } else if (nested[key] == null) { - nested[key] = isIndex(path[index + 1]) ? [] : {}; - } - } - nested = nested[key]; - } - return object; - } - - /** - * An alternative to `_.reduce`; this method transforms `object` to a new - * `accumulator` object which is the result of running each of its own enumerable - * properties through `iteratee`, with each invocation potentially mutating - * the `accumulator` object. The `iteratee` is bound to `thisArg` and invoked - * with four arguments: (accumulator, value, key, object). Iteratee functions - * may exit iteration early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @category Object - * @param {Array|Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [accumulator] The custom accumulator value. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {*} Returns the accumulated value. - * @example - * - * _.transform([2, 3, 4], function(result, n) { - * result.push(n *= n); - * return n % 2 == 0; - * }); - * // => [4, 9] - * - * _.transform({ 'a': 1, 'b': 2 }, function(result, n, key) { - * result[key] = n * 3; - * }); - * // => { 'a': 3, 'b': 6 } - */ - function transform(object, iteratee, accumulator, thisArg) { - var isArr = isArray(object) || isTypedArray(object); - iteratee = getCallback(iteratee, thisArg, 4); - - if (accumulator == null) { - if (isArr || isObject(object)) { - var Ctor = object.constructor; - if (isArr) { - accumulator = isArray(object) ? new Ctor : []; - } else { - accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined); - } - } else { - accumulator = {}; - } - } - (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) { - return iteratee(accumulator, value, index, object); - }); - return accumulator; - } - - /** - * Creates an array of the own enumerable property values of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property values. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.values(new Foo); - * // => [1, 2] (iteration order is not guaranteed) - * - * _.values('hi'); - * // => ['h', 'i'] - */ - function values(object) { - return baseValues(object, keys(object)); - } - - /** - * Creates an array of the own and inherited enumerable property values - * of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property values. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.valuesIn(new Foo); - * // => [1, 2, 3] (iteration order is not guaranteed) - */ - function valuesIn(object) { - return baseValues(object, keysIn(object)); - } - - /*------------------------------------------------------------------------*/ - - /** - * Checks if `n` is between `start` and up to but not including, `end`. If - * `end` is not specified it is set to `start` with `start` then set to `0`. - * - * @static - * @memberOf _ - * @category Number - * @param {number} n The number to check. - * @param {number} [start=0] The start of the range. - * @param {number} end The end of the range. - * @returns {boolean} Returns `true` if `n` is in the range, else `false`. - * @example - * - * _.inRange(3, 2, 4); - * // => true - * - * _.inRange(4, 8); - * // => true - * - * _.inRange(4, 2); - * // => false - * - * _.inRange(2, 2); - * // => false - * - * _.inRange(1.2, 2); - * // => true - * - * _.inRange(5.2, 4); - * // => false - */ - function inRange(value, start, end) { - start = +start || 0; - if (end === undefined) { - end = start; - start = 0; - } else { - end = +end || 0; - } - return value >= nativeMin(start, end) && value < nativeMax(start, end); - } - - /** - * Produces a random number between `min` and `max` (inclusive). If only one - * argument is provided a number between `0` and the given number is returned. - * If `floating` is `true`, or either `min` or `max` are floats, a floating-point - * number is returned instead of an integer. - * - * @static - * @memberOf _ - * @category Number - * @param {number} [min=0] The minimum possible value. - * @param {number} [max=1] The maximum possible value. - * @param {boolean} [floating] Specify returning a floating-point number. - * @returns {number} Returns the random number. - * @example - * - * _.random(0, 5); - * // => an integer between 0 and 5 - * - * _.random(5); - * // => also an integer between 0 and 5 - * - * _.random(5, true); - * // => a floating-point number between 0 and 5 - * - * _.random(1.2, 5.2); - * // => a floating-point number between 1.2 and 5.2 - */ - function random(min, max, floating) { - if (floating && isIterateeCall(min, max, floating)) { - max = floating = undefined; - } - var noMin = min == null, - noMax = max == null; - - if (floating == null) { - if (noMax && typeof min == 'boolean') { - floating = min; - min = 1; - } - else if (typeof max == 'boolean') { - floating = max; - noMax = true; - } - } - if (noMin && noMax) { - max = 1; - noMax = false; - } - min = +min || 0; - if (noMax) { - max = min; - min = 0; - } else { - max = +max || 0; - } - if (floating || min % 1 || max % 1) { - var rand = nativeRandom(); - return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand + '').length - 1)))), max); - } - return baseRandom(min, max); - } - - /*------------------------------------------------------------------------*/ - - /** - * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the camel cased string. - * @example - * - * _.camelCase('Foo Bar'); - * // => 'fooBar' - * - * _.camelCase('--foo-bar'); - * // => 'fooBar' - * - * _.camelCase('__foo_bar__'); - * // => 'fooBar' - */ - var camelCase = createCompounder(function(result, word, index) { - word = word.toLowerCase(); - return result + (index ? (word.charAt(0).toUpperCase() + word.slice(1)) : word); - }); - - /** - * Capitalizes the first character of `string`. - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to capitalize. - * @returns {string} Returns the capitalized string. - * @example - * - * _.capitalize('fred'); - * // => 'Fred' - */ - function capitalize(string) { - string = baseToString(string); - return string && (string.charAt(0).toUpperCase() + string.slice(1)); - } - - /** - * Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) - * to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to deburr. - * @returns {string} Returns the deburred string. - * @example - * - * _.deburr('déjà vu'); - * // => 'deja vu' - */ - function deburr(string) { - string = baseToString(string); - return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, ''); - } - - /** - * Checks if `string` ends with the given target string. - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to search. - * @param {string} [target] The string to search for. - * @param {number} [position=string.length] The position to search from. - * @returns {boolean} Returns `true` if `string` ends with `target`, else `false`. - * @example - * - * _.endsWith('abc', 'c'); - * // => true - * - * _.endsWith('abc', 'b'); - * // => false - * - * _.endsWith('abc', 'b', 2); - * // => true - */ - function endsWith(string, target, position) { - string = baseToString(string); - target = (target + ''); - - var length = string.length; - position = position === undefined - ? length - : nativeMin(position < 0 ? 0 : (+position || 0), length); - - position -= target.length; - return position >= 0 && string.indexOf(target, position) == position; - } - - /** - * Converts the characters "&", "<", ">", '"', "'", and "\`", in `string` to - * their corresponding HTML entities. - * - * **Note:** No other characters are escaped. To escape additional characters - * use a third-party library like [_he_](https://mths.be/he). - * - * Though the ">" character is escaped for symmetry, characters like - * ">" and "/" don't need escaping in HTML and have no special meaning - * unless they're part of a tag or unquoted attribute value. - * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) - * (under "semi-related fun fact") for more details. - * - * Backticks are escaped because in Internet Explorer < 9, they can break out - * of attribute values or HTML comments. See [#59](https://html5sec.org/#59), - * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and - * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/) - * for more details. - * - * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping) - * to reduce XSS vectors. - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to escape. - * @returns {string} Returns the escaped string. - * @example - * - * _.escape('fred, barney, & pebbles'); - * // => 'fred, barney, & pebbles' - */ - function escape(string) { - // Reset `lastIndex` because in IE < 9 `String#replace` does not. - string = baseToString(string); - return (string && reHasUnescapedHtml.test(string)) - ? string.replace(reUnescapedHtml, escapeHtmlChar) - : string; - } - - /** - * Escapes the `RegExp` special characters "\", "/", "^", "$", ".", "|", "?", - * "*", "+", "(", ")", "[", "]", "{" and "}" in `string`. - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to escape. - * @returns {string} Returns the escaped string. - * @example - * - * _.escapeRegExp('[lodash](https://lodash.com/)'); - * // => '\[lodash\]\(https:\/\/lodash\.com\/\)' - */ - function escapeRegExp(string) { - string = baseToString(string); - return (string && reHasRegExpChars.test(string)) - ? string.replace(reRegExpChars, escapeRegExpChar) - : (string || '(?:)'); - } - - /** - * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the kebab cased string. - * @example - * - * _.kebabCase('Foo Bar'); - * // => 'foo-bar' - * - * _.kebabCase('fooBar'); - * // => 'foo-bar' - * - * _.kebabCase('__foo_bar__'); - * // => 'foo-bar' - */ - var kebabCase = createCompounder(function(result, word, index) { - return result + (index ? '-' : '') + word.toLowerCase(); - }); - - /** - * Pads `string` on the left and right sides if it's shorter than `length`. - * Padding characters are truncated if they can't be evenly divided by `length`. - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to pad. - * @param {number} [length=0] The padding length. - * @param {string} [chars=' '] The string used as padding. - * @returns {string} Returns the padded string. - * @example - * - * _.pad('abc', 8); - * // => ' abc ' - * - * _.pad('abc', 8, '_-'); - * // => '_-abc_-_' - * - * _.pad('abc', 3); - * // => 'abc' - */ - function pad(string, length, chars) { - string = baseToString(string); - length = +length; - - var strLength = string.length; - if (strLength >= length || !nativeIsFinite(length)) { - return string; - } - var mid = (length - strLength) / 2, - leftLength = nativeFloor(mid), - rightLength = nativeCeil(mid); - - chars = createPadding('', rightLength, chars); - return chars.slice(0, leftLength) + string + chars; - } - - /** - * Pads `string` on the left side if it's shorter than `length`. Padding - * characters are truncated if they exceed `length`. - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to pad. - * @param {number} [length=0] The padding length. - * @param {string} [chars=' '] The string used as padding. - * @returns {string} Returns the padded string. - * @example - * - * _.padLeft('abc', 6); - * // => ' abc' - * - * _.padLeft('abc', 6, '_-'); - * // => '_-_abc' - * - * _.padLeft('abc', 3); - * // => 'abc' - */ - var padLeft = createPadDir(); - - /** - * Pads `string` on the right side if it's shorter than `length`. Padding - * characters are truncated if they exceed `length`. - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to pad. - * @param {number} [length=0] The padding length. - * @param {string} [chars=' '] The string used as padding. - * @returns {string} Returns the padded string. - * @example - * - * _.padRight('abc', 6); - * // => 'abc ' - * - * _.padRight('abc', 6, '_-'); - * // => 'abc_-_' - * - * _.padRight('abc', 3); - * // => 'abc' - */ - var padRight = createPadDir(true); - - /** - * Converts `string` to an integer of the specified radix. If `radix` is - * `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal, - * in which case a `radix` of `16` is used. - * - * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#E) - * of `parseInt`. - * - * @static - * @memberOf _ - * @category String - * @param {string} string The string to convert. - * @param {number} [radix] The radix to interpret `value` by. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {number} Returns the converted integer. - * @example - * - * _.parseInt('08'); - * // => 8 - * - * _.map(['6', '08', '10'], _.parseInt); - * // => [6, 8, 10] - */ - function parseInt(string, radix, guard) { - // Firefox < 21 and Opera < 15 follow ES3 for `parseInt`. - // Chrome fails to trim leading whitespace characters. - // See https://code.google.com/p/v8/issues/detail?id=3109 for more details. - if (guard ? isIterateeCall(string, radix, guard) : radix == null) { - radix = 0; - } else if (radix) { - radix = +radix; - } - string = trim(string); - return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10)); - } - - /** - * Repeats the given string `n` times. - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to repeat. - * @param {number} [n=0] The number of times to repeat the string. - * @returns {string} Returns the repeated string. - * @example - * - * _.repeat('*', 3); - * // => '***' - * - * _.repeat('abc', 2); - * // => 'abcabc' - * - * _.repeat('abc', 0); - * // => '' - */ - function repeat(string, n) { - var result = ''; - string = baseToString(string); - n = +n; - if (n < 1 || !string || !nativeIsFinite(n)) { - return result; - } - // Leverage the exponentiation by squaring algorithm for a faster repeat. - // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details. - do { - if (n % 2) { - result += string; - } - n = nativeFloor(n / 2); - string += string; - } while (n); - - return result; - } - - /** - * Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case). - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the snake cased string. - * @example - * - * _.snakeCase('Foo Bar'); - * // => 'foo_bar' - * - * _.snakeCase('fooBar'); - * // => 'foo_bar' - * - * _.snakeCase('--foo-bar'); - * // => 'foo_bar' - */ - var snakeCase = createCompounder(function(result, word, index) { - return result + (index ? '_' : '') + word.toLowerCase(); - }); - - /** - * Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the start cased string. - * @example - * - * _.startCase('--foo-bar'); - * // => 'Foo Bar' - * - * _.startCase('fooBar'); - * // => 'Foo Bar' - * - * _.startCase('__foo_bar__'); - * // => 'Foo Bar' - */ - var startCase = createCompounder(function(result, word, index) { - return result + (index ? ' ' : '') + (word.charAt(0).toUpperCase() + word.slice(1)); - }); - - /** - * Checks if `string` starts with the given target string. - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to search. - * @param {string} [target] The string to search for. - * @param {number} [position=0] The position to search from. - * @returns {boolean} Returns `true` if `string` starts with `target`, else `false`. - * @example - * - * _.startsWith('abc', 'a'); - * // => true - * - * _.startsWith('abc', 'b'); - * // => false - * - * _.startsWith('abc', 'b', 1); - * // => true - */ - function startsWith(string, target, position) { - string = baseToString(string); - position = position == null - ? 0 - : nativeMin(position < 0 ? 0 : (+position || 0), string.length); - - return string.lastIndexOf(target, position) == position; - } - - /** - * Creates a compiled template function that can interpolate data properties - * in "interpolate" delimiters, HTML-escape interpolated data properties in - * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data - * properties may be accessed as free variables in the template. If a setting - * object is provided it takes precedence over `_.templateSettings` values. - * - * **Note:** In the development build `_.template` utilizes - * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) - * for easier debugging. - * - * For more information on precompiling templates see - * [lodash's custom builds documentation](https://lodash.com/custom-builds). - * - * For more information on Chrome extension sandboxes see - * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval). - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The template string. - * @param {Object} [options] The options object. - * @param {RegExp} [options.escape] The HTML "escape" delimiter. - * @param {RegExp} [options.evaluate] The "evaluate" delimiter. - * @param {Object} [options.imports] An object to import into the template as free variables. - * @param {RegExp} [options.interpolate] The "interpolate" delimiter. - * @param {string} [options.sourceURL] The sourceURL of the template's compiled source. - * @param {string} [options.variable] The data object variable name. - * @param- {Object} [otherOptions] Enables the legacy `options` param signature. - * @returns {Function} Returns the compiled template function. - * @example - * - * // using the "interpolate" delimiter to create a compiled template - * var compiled = _.template('hello <%= user %>!'); - * compiled({ 'user': 'fred' }); - * // => 'hello fred!' - * - * // using the HTML "escape" delimiter to escape data property values - * var compiled = _.template('<%- value %>'); - * compiled({ 'value': '