Skip to content

Instantly share code, notes, and snippets.

@1wheel
Last active September 20, 2017 06:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 1wheel/edb19f67a301bdd8f28abc70db7e869f to your computer and use it in GitHub Desktop.
Save 1wheel/edb19f67a301bdd8f28abc70db7e869f to your computer and use it in GitHub Desktop.
wl-treemap

During the 2016 Summer NALCS, each team played 18 best of three matches. These charts show the percent of games 1s each team won, and then how their winning percentage in game 2s changed based on the result of game 1.

They also try to show how winning percentage in game 3s changed based on previous matches, but the charts are a little too noisy to see that clearly.

console.clear()
d3.select('body').selectAppend('div.tooltip.tooltip-hidden')
var teamgames = []
d3.loadData('games.csv', (err, [games]) => {
games
.sort((a, b) => a.timestamp > b.timestamp)
.filter(d => d.tournmentName == 'NA 2017 Summer Split' && d.bracketName == 'regular_season')
.forEach(game => {
teamgames.push(_.extend({team: game.winner, won: 1}, game))
teamgames.push(_.extend({team: game.loser, won: 0}, game))
})
byTeam = d3.nestBy(teamgames, d => d.team)
byTeam.forEach(team => {
team.byMatch = d3.nestBy(team, d => d.matchName)
team.bb = [[0, 0], [1, 1]]
team.byWin = d3.nestBy(team.byMatch, d => d[0].won).sort(wonSort)
team.byWin.forEach((w1, i) => {
w1.parent = team.byMatch
w1.percent = w1.length/team.byMatch.length
w1.bb = cutBB(team.bb, w1.percent, w1.key == 1 ? 'l' : 'r')
w1.byWin = d3.nestBy(w1, d => d[1].won).sort(wonSort)
w1.byWin.forEach(w2 => {
w2.parent = w1
w2.percent = w2.length/w1.length
w2.bb = cutBB(w1.bb, w2.percent, w2.key == 1 ? 'u' : 'd')
w2.byWin = d3.nestBy(w2.filter(d => d[2]), d => d[2] ? d[2].won : w2.key).sort(wonSort)
w2.byWin.forEach(w3 => {
w3.parent = w2
w3.percent = w3.length/w2.length
w3.bb = cutBB(w2.bb, w3.percent, w3.key == 1 ? 'l' : 'r')
})
// w2.byWin = null
})
})
})
var sel = d3.select('.graph').html('')
var teamSel = sel.append('div').appendMany(byTeam, 'div')
.st({width: 192, display: 'inline-block'})
teamSel.append('div').text(d => d.key).st({textAlign: 'center'})
teamSel.each(drawTreemap)
var teamSel = sel.append('div').appendMany(byTeam, 'div')
.st({width: 192, display: 'inline-block'})
teamSel.append('div').text(d => d.key).st({textAlign: 'center'})
teamSel.each(drawIce)
})
function drawTreemap(team){
var sel = d3.select(this)
var s = 180
var svg = sel.append('svg').at({width: s, height: s})
team.byWin.forEach(d => drawByWin(d, 0))
function drawByWin(w, delay){
var fill = w.byWin && w.byWin.length ? w.key == 1 ? '#4caf50' : '#ff9800' : w.key == 1 ? '#4caf50' : '#ff9800'
// w.bbstr = JSON.stringify(w.bb)
svg.append('path')
.at({d: bbToPath(w.bb, s), stroke: '#fff'})
.st({fill})
.datum(w)
.call(d3.attachTooltip)
.st({opacity: 0})
.transition().delay(delay).duration(delay ? 500 : 0)
.st({opacity: 1})
if (w.byWin) w.byWin.forEach(d => drawByWin(d, delay*2 + 3000))
}
}
function drawIce(team){
var sel = d3.select(this)
var s = 180
var svg = sel.append('svg').at({width: s, height: s})
.st({overflow: 'hidden'})
drawByWin(team, 0, -s/3, s)
function drawByWin(m, x, y, width){
if (!m) return
var fill = m.key == 1 ? '#4caf50' : '#ff9800'
svg.append('rect')
.at({x, y, width, height: s/3 - 1, fill})
.datum(m)
.call(d3.attachTooltip)
if (!m.byWin || !m.byWin.length) return
var [w, l] = m.byWin
var p = w.percent
drawByWin(w, x, y + s/3, width*p - 1)
drawByWin(l, x + width*p + 1, y + s/3, width*(1 - p) - 1)
// setTimeout(() => {
// svg.append('path')
// .at({d: `M ${x + width} ${y} V ${300}`, stroke: '#000', strokeWidth: 2})
// }, 0)
}
}
function wonSort(a, b){ return a.key > b.key }
function cutBB([[x0, y0], [x1, y1]], p, type){
x0 = x0 + .03
x1 = x1 - .03
y0 = y0 + .03
y1 = y1 - .03
var mx = mix(x0, x1, type == 'l' ? p : 1 - p)
var my = mix(y0, y1, type == 'u' ? p : 1 - p)
if (type == 'l' || type == 'r'){
return type == 'l' ? [[x0, y0], [mx, y1]] : [[mx, y0], [x1, y1]]
} else {
return type == 'u' ? [[x0, y0], [x1, my]] : [[x0, my], [x1, y1]]
}
}
function bbToPath([[x0, y0], [x1, y1]], s){
return [
'M', x0*s, y0*s,
'L', x0*s, y1*s,
'L', x1*s, y1*s,
'L', x1*s, y0*s,
'Z'
].join(' ')
}
function mix(x0, x1, p){
return x0*(1 - p) + x1*p
}
/**
* @license
* Lodash lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE
*/
;(function(){function n(n,t){return n.set(t[0],t[1]),n}function t(n,t){return n.add(t),n}function r(n,t,r){switch(r.length){case 0:return n.call(t);case 1:return n.call(t,r[0]);case 2:return n.call(t,r[0],r[1]);case 3:return n.call(t,r[0],r[1],r[2])}return n.apply(t,r)}function e(n,t,r,e){for(var u=-1,i=null==n?0:n.length;++u<i;){var o=n[u];t(e,o,r(o),n)}return e}function u(n,t){for(var r=-1,e=null==n?0:n.length;++r<e&&false!==t(n[r],r,n););return n}function i(n,t){for(var r=null==n?0:n.length;r--&&false!==t(n[r],r,n););
return n}function o(n,t){for(var r=-1,e=null==n?0:n.length;++r<e;)if(!t(n[r],r,n))return false;return true}function f(n,t){for(var r=-1,e=null==n?0:n.length,u=0,i=[];++r<e;){var o=n[r];t(o,r,n)&&(i[u++]=o)}return i}function c(n,t){return!(null==n||!n.length)&&-1<d(n,t,0)}function a(n,t,r){for(var e=-1,u=null==n?0:n.length;++e<u;)if(r(t,n[e]))return true;return false}function l(n,t){for(var r=-1,e=null==n?0:n.length,u=Array(e);++r<e;)u[r]=t(n[r],r,n);return u}function s(n,t){for(var r=-1,e=t.length,u=n.length;++r<e;)n[u+r]=t[r];
return n}function h(n,t,r,e){var u=-1,i=null==n?0:n.length;for(e&&i&&(r=n[++u]);++u<i;)r=t(r,n[u],u,n);return r}function p(n,t,r,e){var u=null==n?0:n.length;for(e&&u&&(r=n[--u]);u--;)r=t(r,n[u],u,n);return r}function _(n,t){for(var r=-1,e=null==n?0:n.length;++r<e;)if(t(n[r],r,n))return true;return false}function v(n,t,r){var e;return r(n,function(n,r,u){if(t(n,r,u))return e=r,false}),e}function g(n,t,r,e){var u=n.length;for(r+=e?1:-1;e?r--:++r<u;)if(t(n[r],r,n))return r;return-1}function d(n,t,r){if(t===t)n:{
--r;for(var e=n.length;++r<e;)if(n[r]===t){n=r;break n}n=-1}else n=g(n,b,r);return n}function y(n,t,r,e){--r;for(var u=n.length;++r<u;)if(e(n[r],t))return r;return-1}function b(n){return n!==n}function x(n,t){var r=null==n?0:n.length;return r?k(n,t)/r:P}function j(n){return function(t){return null==t?F:t[n]}}function w(n){return function(t){return null==n?F:n[t]}}function m(n,t,r,e,u){return u(n,function(n,u,i){r=e?(e=false,n):t(r,n,u,i)}),r}function A(n,t){var r=n.length;for(n.sort(t);r--;)n[r]=n[r].c;
return n}function k(n,t){for(var r,e=-1,u=n.length;++e<u;){var i=t(n[e]);i!==F&&(r=r===F?i:r+i)}return r}function E(n,t){for(var r=-1,e=Array(n);++r<n;)e[r]=t(r);return e}function O(n,t){return l(t,function(t){return[t,n[t]]})}function S(n){return function(t){return n(t)}}function I(n,t){return l(t,function(t){return n[t]})}function R(n,t){return n.has(t)}function z(n,t){for(var r=-1,e=n.length;++r<e&&-1<d(t,n[r],0););return r}function W(n,t){for(var r=n.length;r--&&-1<d(t,n[r],0););return r}function B(n){
return"\\"+Tn[n]}function L(n){var t=-1,r=Array(n.size);return n.forEach(function(n,e){r[++t]=[e,n]}),r}function U(n,t){return function(r){return n(t(r))}}function C(n,t){for(var r=-1,e=n.length,u=0,i=[];++r<e;){var o=n[r];o!==t&&"__lodash_placeholder__"!==o||(n[r]="__lodash_placeholder__",i[u++]=r)}return i}function D(n){var t=-1,r=Array(n.size);return n.forEach(function(n){r[++t]=n}),r}function M(n){var t=-1,r=Array(n.size);return n.forEach(function(n){r[++t]=[n,n]}),r}function T(n){if(Bn.test(n)){
for(var t=zn.lastIndex=0;zn.test(n);)++t;n=t}else n=tt(n);return n}function $(n){return Bn.test(n)?n.match(zn)||[]:n.split("")}var F,N=1/0,P=NaN,Z=[["ary",128],["bind",1],["bindKey",2],["curry",8],["curryRight",16],["flip",512],["partial",32],["partialRight",64],["rearg",256]],q=/\b__p\+='';/g,V=/\b(__p\+=)''\+/g,K=/(__e\(.*?\)|\b__t\))\+'';/g,G=/&(?:amp|lt|gt|quot|#39);/g,H=/[&<>"']/g,J=RegExp(G.source),Y=RegExp(H.source),Q=/<%-([\s\S]+?)%>/g,X=/<%([\s\S]+?)%>/g,nn=/<%=([\s\S]+?)%>/g,tn=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,rn=/^\w*$/,en=/^\./,un=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,on=/[\\^$.*+?()[\]{}|]/g,fn=RegExp(on.source),cn=/^\s+|\s+$/g,an=/^\s+/,ln=/\s+$/,sn=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,hn=/\{\n\/\* \[wrapped with (.+)\] \*/,pn=/,? & /,_n=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,vn=/\\(\\)?/g,gn=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,dn=/\w*$/,yn=/^[-+]0x[0-9a-f]+$/i,bn=/^0b[01]+$/i,xn=/^\[object .+?Constructor\]$/,jn=/^0o[0-7]+$/i,wn=/^(?:0|[1-9]\d*)$/,mn=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,An=/($^)/,kn=/['\n\r\u2028\u2029\\]/g,En="[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?(?:\\u200d(?:[^\\ud800-\\udfff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?)*",On="(?:[\\u2700-\\u27bf]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])"+En,Sn="(?:[^\\ud800-\\udfff][\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]?|[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\ud800-\\udfff])",In=RegExp("['\u2019]","g"),Rn=RegExp("[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]","g"),zn=RegExp("\\ud83c[\\udffb-\\udfff](?=\\ud83c[\\udffb-\\udfff])|"+Sn+En,"g"),Wn=RegExp(["[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+(?:['\u2019](?:d|ll|m|re|s|t|ve))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde]|$)|(?:[A-Z\\xc0-\\xd6\\xd8-\\xde]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde](?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])|$)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?(?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:d|ll|m|re|s|t|ve))?|[A-Z\\xc0-\\xd6\\xd8-\\xde]+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?|\\d*(?:(?:1ST|2ND|3RD|(?![123])\\dTH)\\b)|\\d*(?:(?:1st|2nd|3rd|(?![123])\\dth)\\b)|\\d+",On].join("|"),"g"),Bn=RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff\\ufe0e\\ufe0f]"),Ln=/[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,Un="Array Buffer DataView Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Map Math Object Promise RegExp Set String Symbol TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap _ clearTimeout isFinite parseInt setTimeout".split(" "),Cn={};
Cn["[object Float32Array]"]=Cn["[object Float64Array]"]=Cn["[object Int8Array]"]=Cn["[object Int16Array]"]=Cn["[object Int32Array]"]=Cn["[object Uint8Array]"]=Cn["[object Uint8ClampedArray]"]=Cn["[object Uint16Array]"]=Cn["[object Uint32Array]"]=true,Cn["[object Arguments]"]=Cn["[object Array]"]=Cn["[object ArrayBuffer]"]=Cn["[object Boolean]"]=Cn["[object DataView]"]=Cn["[object Date]"]=Cn["[object Error]"]=Cn["[object Function]"]=Cn["[object Map]"]=Cn["[object Number]"]=Cn["[object Object]"]=Cn["[object RegExp]"]=Cn["[object Set]"]=Cn["[object String]"]=Cn["[object WeakMap]"]=false;
var Dn={};Dn["[object Arguments]"]=Dn["[object Array]"]=Dn["[object ArrayBuffer]"]=Dn["[object DataView]"]=Dn["[object Boolean]"]=Dn["[object Date]"]=Dn["[object Float32Array]"]=Dn["[object Float64Array]"]=Dn["[object Int8Array]"]=Dn["[object Int16Array]"]=Dn["[object Int32Array]"]=Dn["[object Map]"]=Dn["[object Number]"]=Dn["[object Object]"]=Dn["[object RegExp]"]=Dn["[object Set]"]=Dn["[object String]"]=Dn["[object Symbol]"]=Dn["[object Uint8Array]"]=Dn["[object Uint8ClampedArray]"]=Dn["[object Uint16Array]"]=Dn["[object Uint32Array]"]=true,
Dn["[object Error]"]=Dn["[object Function]"]=Dn["[object WeakMap]"]=false;var Mn,Tn={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},$n=parseFloat,Fn=parseInt,Nn=typeof global=="object"&&global&&global.Object===Object&&global,Pn=typeof self=="object"&&self&&self.Object===Object&&self,Zn=Nn||Pn||Function("return this")(),qn=typeof exports=="object"&&exports&&!exports.nodeType&&exports,Vn=qn&&typeof module=="object"&&module&&!module.nodeType&&module,Kn=Vn&&Vn.exports===qn,Gn=Kn&&Nn.process;
n:{try{Mn=Gn&&Gn.binding&&Gn.binding("util");break n}catch(n){}Mn=void 0}var Hn=Mn&&Mn.isArrayBuffer,Jn=Mn&&Mn.isDate,Yn=Mn&&Mn.isMap,Qn=Mn&&Mn.isRegExp,Xn=Mn&&Mn.isSet,nt=Mn&&Mn.isTypedArray,tt=j("length"),rt=w({"\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","\u0100":"A","\u0102":"A","\u0104":"A","\u0101":"a","\u0103":"a","\u0105":"a","\u0106":"C","\u0108":"C","\u010a":"C",
"\u010c":"C","\u0107":"c","\u0109":"c","\u010b":"c","\u010d":"c","\u010e":"D","\u0110":"D","\u010f":"d","\u0111":"d","\u0112":"E","\u0114":"E","\u0116":"E","\u0118":"E","\u011a":"E","\u0113":"e","\u0115":"e","\u0117":"e","\u0119":"e","\u011b":"e","\u011c":"G","\u011e":"G","\u0120":"G","\u0122":"G","\u011d":"g","\u011f":"g","\u0121":"g","\u0123":"g","\u0124":"H","\u0126":"H","\u0125":"h","\u0127":"h","\u0128":"I","\u012a":"I","\u012c":"I","\u012e":"I","\u0130":"I","\u0129":"i","\u012b":"i","\u012d":"i",
"\u012f":"i","\u0131":"i","\u0134":"J","\u0135":"j","\u0136":"K","\u0137":"k","\u0138":"k","\u0139":"L","\u013b":"L","\u013d":"L","\u013f":"L","\u0141":"L","\u013a":"l","\u013c":"l","\u013e":"l","\u0140":"l","\u0142":"l","\u0143":"N","\u0145":"N","\u0147":"N","\u014a":"N","\u0144":"n","\u0146":"n","\u0148":"n","\u014b":"n","\u014c":"O","\u014e":"O","\u0150":"O","\u014d":"o","\u014f":"o","\u0151":"o","\u0154":"R","\u0156":"R","\u0158":"R","\u0155":"r","\u0157":"r","\u0159":"r","\u015a":"S","\u015c":"S",
"\u015e":"S","\u0160":"S","\u015b":"s","\u015d":"s","\u015f":"s","\u0161":"s","\u0162":"T","\u0164":"T","\u0166":"T","\u0163":"t","\u0165":"t","\u0167":"t","\u0168":"U","\u016a":"U","\u016c":"U","\u016e":"U","\u0170":"U","\u0172":"U","\u0169":"u","\u016b":"u","\u016d":"u","\u016f":"u","\u0171":"u","\u0173":"u","\u0174":"W","\u0175":"w","\u0176":"Y","\u0177":"y","\u0178":"Y","\u0179":"Z","\u017b":"Z","\u017d":"Z","\u017a":"z","\u017c":"z","\u017e":"z","\u0132":"IJ","\u0133":"ij","\u0152":"Oe","\u0153":"oe",
"\u0149":"'n","\u017f":"s"}),et=w({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}),ut=w({"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#39;":"'"}),it=function w(En){function On(n){if(xu(n)&&!af(n)&&!(n instanceof Mn)){if(n instanceof zn)return n;if(ci.call(n,"__wrapped__"))return Pe(n)}return new zn(n)}function Sn(){}function zn(n,t){this.__wrapped__=n,this.__actions__=[],this.__chain__=!!t,this.__index__=0,this.__values__=F}function Mn(n){this.__wrapped__=n,this.__actions__=[],this.__dir__=1,
this.__filtered__=false,this.__iteratees__=[],this.__takeCount__=4294967295,this.__views__=[]}function Tn(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1])}}function Nn(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1])}}function Pn(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1])}}function qn(n){var t=-1,r=null==n?0:n.length;for(this.__data__=new Pn;++t<r;)this.add(n[t])}function Vn(n){
this.size=(this.__data__=new Nn(n)).size}function Gn(n,t){var r,e=af(n),u=!e&&cf(n),i=!e&&!u&&sf(n),o=!e&&!u&&!i&&gf(n),u=(e=e||u||i||o)?E(n.length,ri):[],f=u.length;for(r in n)!t&&!ci.call(n,r)||e&&("length"==r||i&&("offset"==r||"parent"==r)||o&&("buffer"==r||"byteLength"==r||"byteOffset"==r)||Re(r,f))||u.push(r);return u}function tt(n){var t=n.length;return t?n[cr(0,t-1)]:F}function ot(n,t){return Te(Mr(n),gt(t,0,n.length))}function ft(n){return Te(Mr(n))}function ct(n,t,r){(r===F||hu(n[t],r))&&(r!==F||t in n)||_t(n,t,r);
}function at(n,t,r){var e=n[t];ci.call(n,t)&&hu(e,r)&&(r!==F||t in n)||_t(n,t,r)}function lt(n,t){for(var r=n.length;r--;)if(hu(n[r][0],t))return r;return-1}function st(n,t,r,e){return oo(n,function(n,u,i){t(e,n,r(n),i)}),e}function ht(n,t){return n&&Tr(t,Lu(t),n)}function pt(n,t){return n&&Tr(t,Uu(t),n)}function _t(n,t,r){"__proto__"==t&&Ei?Ei(n,t,{configurable:true,enumerable:true,value:r,writable:true}):n[t]=r}function vt(n,t){for(var r=-1,e=t.length,u=Hu(e),i=null==n;++r<e;)u[r]=i?F:Wu(n,t[r]);return u;
}function gt(n,t,r){return n===n&&(r!==F&&(n=n<=r?n:r),t!==F&&(n=n>=t?n:t)),n}function dt(n,t,r,e,i,o){var f,c=1&t,a=2&t,l=4&t;if(r&&(f=i?r(n,e,i,o):r(n)),f!==F)return f;if(!bu(n))return n;if(e=af(n)){if(f=Ee(n),!c)return Mr(n,f)}else{var s=yo(n),h="[object Function]"==s||"[object GeneratorFunction]"==s;if(sf(n))return Wr(n,c);if("[object Object]"==s||"[object Arguments]"==s||h&&!i){if(f=a||h?{}:Oe(n),!c)return a?Fr(n,pt(f,n)):$r(n,ht(f,n))}else{if(!Dn[s])return i?n:{};f=Se(n,s,dt,c)}}if(o||(o=new Vn),
i=o.get(n))return i;o.set(n,f);var a=l?a?ye:de:a?Uu:Lu,p=e?F:a(n);return u(p||n,function(e,u){p&&(u=e,e=n[u]),at(f,u,dt(e,t,r,u,n,o))}),f}function yt(n){var t=Lu(n);return function(r){return bt(r,n,t)}}function bt(n,t,r){var e=r.length;if(null==n)return!e;for(n=ni(n);e--;){var u=r[e],i=t[u],o=n[u];if(o===F&&!(u in n)||!i(o))return false}return true}function xt(n,t,r){if(typeof n!="function")throw new ei("Expected a function");return jo(function(){n.apply(F,r)},t)}function jt(n,t,r,e){var u=-1,i=c,o=true,f=n.length,s=[],h=t.length;
if(!f)return s;r&&(t=l(t,S(r))),e?(i=a,o=false):200<=t.length&&(i=R,o=false,t=new qn(t));n:for(;++u<f;){var p=n[u],_=null==r?p:r(p),p=e||0!==p?p:0;if(o&&_===_){for(var v=h;v--;)if(t[v]===_)continue n;s.push(p)}else i(t,_,e)||s.push(p)}return s}function wt(n,t){var r=true;return oo(n,function(n,e,u){return r=!!t(n,e,u)}),r}function mt(n,t,r){for(var e=-1,u=n.length;++e<u;){var i=n[e],o=t(i);if(null!=o&&(f===F?o===o&&!Au(o):r(o,f)))var f=o,c=i}return c}function At(n,t){var r=[];return oo(n,function(n,e,u){
t(n,e,u)&&r.push(n)}),r}function kt(n,t,r,e,u){var i=-1,o=n.length;for(r||(r=Ie),u||(u=[]);++i<o;){var f=n[i];0<t&&r(f)?1<t?kt(f,t-1,r,e,u):s(u,f):e||(u[u.length]=f)}return u}function Et(n,t){return n&&co(n,t,Lu)}function Ot(n,t){return n&&ao(n,t,Lu)}function St(n,t){return f(t,function(t){return gu(n[t])})}function It(n,t){t=Rr(t,n);for(var r=0,e=t.length;null!=n&&r<e;)n=n[$e(t[r++])];return r&&r==e?n:F}function Rt(n,t,r){return t=t(n),af(n)?t:s(t,r(n))}function zt(n){if(null==n)n=n===F?"[object Undefined]":"[object Null]";else if(ki&&ki in ni(n)){
var t=ci.call(n,ki),r=n[ki];try{n[ki]=F;var e=true}catch(n){}var u=si.call(n);e&&(t?n[ki]=r:delete n[ki]),n=u}else n=si.call(n);return n}function Wt(n,t){return n>t}function Bt(n,t){return null!=n&&ci.call(n,t)}function Lt(n,t){return null!=n&&t in ni(n)}function Ut(n,t,r){for(var e=r?a:c,u=n[0].length,i=n.length,o=i,f=Hu(i),s=1/0,h=[];o--;){var p=n[o];o&&t&&(p=l(p,S(t))),s=Mi(p.length,s),f[o]=!r&&(t||120<=u&&120<=p.length)?new qn(o&&p):F}var p=n[0],_=-1,v=f[0];n:for(;++_<u&&h.length<s;){var g=p[_],d=t?t(g):g,g=r||0!==g?g:0;
if(v?!R(v,d):!e(h,d,r)){for(o=i;--o;){var y=f[o];if(y?!R(y,d):!e(n[o],d,r))continue n}v&&v.push(d),h.push(g)}}return h}function Ct(n,t,r){var e={};return Et(n,function(n,u,i){t(e,r(n),u,i)}),e}function Dt(n,t,e){return t=Rr(t,n),n=2>t.length?n:It(n,vr(t,0,-1)),t=null==n?n:n[$e(Ge(t))],null==t?F:r(t,n,e)}function Mt(n){return xu(n)&&"[object Arguments]"==zt(n)}function Tt(n){return xu(n)&&"[object ArrayBuffer]"==zt(n)}function $t(n){return xu(n)&&"[object Date]"==zt(n)}function Ft(n,t,r,e,u){if(n===t)t=true;else if(null==n||null==t||!xu(n)&&!xu(t))t=n!==n&&t!==t;else n:{
var i=af(n),o=af(t),f=i?"[object Array]":yo(n),c=o?"[object Array]":yo(t),f="[object Arguments]"==f?"[object Object]":f,c="[object Arguments]"==c?"[object Object]":c,a="[object Object]"==f,o="[object Object]"==c;if((c=f==c)&&sf(n)){if(!sf(t)){t=false;break n}i=true,a=false}if(c&&!a)u||(u=new Vn),t=i||gf(n)?_e(n,t,r,e,Ft,u):ve(n,t,f,r,e,Ft,u);else{if(!(1&r)&&(i=a&&ci.call(n,"__wrapped__"),f=o&&ci.call(t,"__wrapped__"),i||f)){n=i?n.value():n,t=f?t.value():t,u||(u=new Vn),t=Ft(n,t,r,e,u);break n}if(c)t:if(u||(u=new Vn),
i=1&r,f=de(n),o=f.length,c=de(t).length,o==c||i){for(a=o;a--;){var l=f[a];if(!(i?l in t:ci.call(t,l))){t=false;break t}}if((c=u.get(n))&&u.get(t))t=c==t;else{c=true,u.set(n,t),u.set(t,n);for(var s=i;++a<o;){var l=f[a],h=n[l],p=t[l];if(e)var _=i?e(p,h,l,t,n,u):e(h,p,l,n,t,u);if(_===F?h!==p&&!Ft(h,p,r,e,u):!_){c=false;break}s||(s="constructor"==l)}c&&!s&&(r=n.constructor,e=t.constructor,r!=e&&"constructor"in n&&"constructor"in t&&!(typeof r=="function"&&r instanceof r&&typeof e=="function"&&e instanceof e)&&(c=false)),
u.delete(n),u.delete(t),t=c}}else t=false;else t=false}}return t}function Nt(n){return xu(n)&&"[object Map]"==yo(n)}function Pt(n,t,r,e){var u=r.length,i=u,o=!e;if(null==n)return!i;for(n=ni(n);u--;){var f=r[u];if(o&&f[2]?f[1]!==n[f[0]]:!(f[0]in n))return false}for(;++u<i;){var f=r[u],c=f[0],a=n[c],l=f[1];if(o&&f[2]){if(a===F&&!(c in n))return false}else{if(f=new Vn,e)var s=e(a,l,c,n,t,f);if(s===F?!Ft(l,a,3,e,f):!s)return false}}return true}function Zt(n){return!(!bu(n)||li&&li in n)&&(gu(n)?_i:xn).test(Fe(n))}function qt(n){
return xu(n)&&"[object RegExp]"==zt(n)}function Vt(n){return xu(n)&&"[object Set]"==yo(n)}function Kt(n){return xu(n)&&yu(n.length)&&!!Cn[zt(n)]}function Gt(n){return typeof n=="function"?n:null==n?Nu:typeof n=="object"?af(n)?Xt(n[0],n[1]):Qt(n):Vu(n)}function Ht(n){if(!Le(n))return Ci(n);var t,r=[];for(t in ni(n))ci.call(n,t)&&"constructor"!=t&&r.push(t);return r}function Jt(n,t){return n<t}function Yt(n,t){var r=-1,e=pu(n)?Hu(n.length):[];return oo(n,function(n,u,i){e[++r]=t(n,u,i)}),e}function Qt(n){
var t=me(n);return 1==t.length&&t[0][2]?Ue(t[0][0],t[0][1]):function(r){return r===n||Pt(r,n,t)}}function Xt(n,t){return We(n)&&t===t&&!bu(t)?Ue($e(n),t):function(r){var e=Wu(r,n);return e===F&&e===t?Bu(r,n):Ft(t,e,3)}}function nr(n,t,r,e,u){n!==t&&co(t,function(i,o){if(bu(i)){u||(u=new Vn);var f=u,c=n[o],a=t[o],l=f.get(a);if(l)ct(n,o,l);else{var l=e?e(c,a,o+"",n,t,f):F,s=l===F;if(s){var h=af(a),p=!h&&sf(a),_=!h&&!p&&gf(a),l=a;h||p||_?af(c)?l=c:_u(c)?l=Mr(c):p?(s=false,l=Wr(a,true)):_?(s=false,l=Lr(a,true)):l=[]:wu(a)||cf(a)?(l=c,
cf(c)?l=Ru(c):(!bu(c)||r&&gu(c))&&(l=Oe(a))):s=false}s&&(f.set(a,l),nr(l,a,r,e,f),f.delete(a)),ct(n,o,l)}}else f=e?e(n[o],i,o+"",n,t,u):F,f===F&&(f=i),ct(n,o,f)},Uu)}function tr(n,t){var r=n.length;if(r)return t+=0>t?r:0,Re(t,r)?n[t]:F}function rr(n,t,r){var e=-1;return t=l(t.length?t:[Nu],S(je())),n=Yt(n,function(n){return{a:l(t,function(t){return t(n)}),b:++e,c:n}}),A(n,function(n,t){var e;n:{e=-1;for(var u=n.a,i=t.a,o=u.length,f=r.length;++e<o;){var c=Ur(u[e],i[e]);if(c){e=e>=f?c:c*("desc"==r[e]?-1:1);
break n}}e=n.b-t.b}return e})}function er(n,t){return ur(n,t,function(t,r){return Bu(n,r)})}function ur(n,t,r){for(var e=-1,u=t.length,i={};++e<u;){var o=t[e],f=It(n,o);r(f,o)&&pr(i,Rr(o,n),f)}return i}function ir(n){return function(t){return It(t,n)}}function or(n,t,r,e){var u=e?y:d,i=-1,o=t.length,f=n;for(n===t&&(t=Mr(t)),r&&(f=l(n,S(r)));++i<o;)for(var c=0,a=t[i],a=r?r(a):a;-1<(c=u(f,a,c,e));)f!==n&&wi.call(f,c,1),wi.call(n,c,1);return n}function fr(n,t){for(var r=n?t.length:0,e=r-1;r--;){var u=t[r];
if(r==e||u!==i){var i=u;Re(u)?wi.call(n,u,1):mr(n,u)}}}function cr(n,t){return n+zi(Fi()*(t-n+1))}function ar(n,t){var r="";if(!n||1>t||9007199254740991<t)return r;do t%2&&(r+=n),(t=zi(t/2))&&(n+=n);while(t);return r}function lr(n,t){return wo(Ce(n,t,Nu),n+"")}function sr(n){return tt(Du(n))}function hr(n,t){var r=Du(n);return Te(r,gt(t,0,r.length))}function pr(n,t,r,e){if(!bu(n))return n;t=Rr(t,n);for(var u=-1,i=t.length,o=i-1,f=n;null!=f&&++u<i;){var c=$e(t[u]),a=r;if(u!=o){var l=f[c],a=e?e(l,c,f):F;
a===F&&(a=bu(l)?l:Re(t[u+1])?[]:{})}at(f,c,a),f=f[c]}return n}function _r(n){return Te(Du(n))}function vr(n,t,r){var e=-1,u=n.length;for(0>t&&(t=-t>u?0:u+t),r=r>u?u:r,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=Hu(u);++e<u;)r[e]=n[e+t];return r}function gr(n,t){var r;return oo(n,function(n,e,u){return r=t(n,e,u),!r}),!!r}function dr(n,t,r){var e=0,u=null==n?e:n.length;if(typeof t=="number"&&t===t&&2147483647>=u){for(;e<u;){var i=e+u>>>1,o=n[i];null!==o&&!Au(o)&&(r?o<=t:o<t)?e=i+1:u=i}return u}return yr(n,t,Nu,r);
}function yr(n,t,r,e){t=r(t);for(var u=0,i=null==n?0:n.length,o=t!==t,f=null===t,c=Au(t),a=t===F;u<i;){var l=zi((u+i)/2),s=r(n[l]),h=s!==F,p=null===s,_=s===s,v=Au(s);(o?e||_:a?_&&(e||h):f?_&&h&&(e||!p):c?_&&h&&!p&&(e||!v):p||v?0:e?s<=t:s<t)?u=l+1:i=l}return Mi(i,4294967294)}function br(n,t){for(var r=-1,e=n.length,u=0,i=[];++r<e;){var o=n[r],f=t?t(o):o;if(!r||!hu(f,c)){var c=f;i[u++]=0===o?0:o}}return i}function xr(n){return typeof n=="number"?n:Au(n)?P:+n}function jr(n){if(typeof n=="string")return n;
if(af(n))return l(n,jr)+"";if(Au(n))return uo?uo.call(n):"";var t=n+"";return"0"==t&&1/n==-N?"-0":t}function wr(n,t,r){var e=-1,u=c,i=n.length,o=true,f=[],l=f;if(r)o=false,u=a;else if(200<=i){if(u=t?null:po(n))return D(u);o=false,u=R,l=new qn}else l=t?[]:f;n:for(;++e<i;){var s=n[e],h=t?t(s):s,s=r||0!==s?s:0;if(o&&h===h){for(var p=l.length;p--;)if(l[p]===h)continue n;t&&l.push(h),f.push(s)}else u(l,h,r)||(l!==f&&l.push(h),f.push(s))}return f}function mr(n,t){return t=Rr(t,n),n=2>t.length?n:It(n,vr(t,0,-1)),
null==n||delete n[$e(Ge(t))]}function Ar(n,t,r,e){for(var u=n.length,i=e?u:-1;(e?i--:++i<u)&&t(n[i],i,n););return r?vr(n,e?0:i,e?i+1:u):vr(n,e?i+1:0,e?u:i)}function kr(n,t){var r=n;return r instanceof Mn&&(r=r.value()),h(t,function(n,t){return t.func.apply(t.thisArg,s([n],t.args))},r)}function Er(n,t,r){var e=n.length;if(2>e)return e?wr(n[0]):[];for(var u=-1,i=Hu(e);++u<e;)for(var o=n[u],f=-1;++f<e;)f!=u&&(i[u]=jt(i[u]||o,n[f],t,r));return wr(kt(i,1),t,r)}function Or(n,t,r){for(var e=-1,u=n.length,i=t.length,o={};++e<u;)r(o,n[e],e<i?t[e]:F);
return o}function Sr(n){return _u(n)?n:[]}function Ir(n){return typeof n=="function"?n:Nu}function Rr(n,t){return af(n)?n:We(n,t)?[n]:mo(zu(n))}function zr(n,t,r){var e=n.length;return r=r===F?e:r,!t&&r>=e?n:vr(n,t,r)}function Wr(n,t){if(t)return n.slice();var r=n.length,r=yi?yi(r):new n.constructor(r);return n.copy(r),r}function Br(n){var t=new n.constructor(n.byteLength);return new di(t).set(new di(n)),t}function Lr(n,t){return new n.constructor(t?Br(n.buffer):n.buffer,n.byteOffset,n.length)}function Ur(n,t){
if(n!==t){var r=n!==F,e=null===n,u=n===n,i=Au(n),o=t!==F,f=null===t,c=t===t,a=Au(t);if(!f&&!a&&!i&&n>t||i&&o&&c&&!f&&!a||e&&o&&c||!r&&c||!u)return 1;if(!e&&!i&&!a&&n<t||a&&r&&u&&!e&&!i||f&&r&&u||!o&&u||!c)return-1}return 0}function Cr(n,t,r,e){var u=-1,i=n.length,o=r.length,f=-1,c=t.length,a=Di(i-o,0),l=Hu(c+a);for(e=!e;++f<c;)l[f]=t[f];for(;++u<o;)(e||u<i)&&(l[r[u]]=n[u]);for(;a--;)l[f++]=n[u++];return l}function Dr(n,t,r,e){var u=-1,i=n.length,o=-1,f=r.length,c=-1,a=t.length,l=Di(i-f,0),s=Hu(l+a);
for(e=!e;++u<l;)s[u]=n[u];for(l=u;++c<a;)s[l+c]=t[c];for(;++o<f;)(e||u<i)&&(s[l+r[o]]=n[u++]);return s}function Mr(n,t){var r=-1,e=n.length;for(t||(t=Hu(e));++r<e;)t[r]=n[r];return t}function Tr(n,t,r,e){var u=!r;r||(r={});for(var i=-1,o=t.length;++i<o;){var f=t[i],c=e?e(r[f],n[f],f,r,n):F;c===F&&(c=n[f]),u?_t(r,f,c):at(r,f,c)}return r}function $r(n,t){return Tr(n,vo(n),t)}function Fr(n,t){return Tr(n,go(n),t)}function Nr(n,t){return function(r,u){var i=af(r)?e:st,o=t?t():{};return i(r,n,je(u,2),o);
}}function Pr(n){return lr(function(t,r){var e=-1,u=r.length,i=1<u?r[u-1]:F,o=2<u?r[2]:F,i=3<n.length&&typeof i=="function"?(u--,i):F;for(o&&ze(r[0],r[1],o)&&(i=3>u?F:i,u=1),t=ni(t);++e<u;)(o=r[e])&&n(t,o,e,i);return t})}function Zr(n,t){return function(r,e){if(null==r)return r;if(!pu(r))return n(r,e);for(var u=r.length,i=t?u:-1,o=ni(r);(t?i--:++i<u)&&false!==e(o[i],i,o););return r}}function qr(n){return function(t,r,e){var u=-1,i=ni(t);e=e(t);for(var o=e.length;o--;){var f=e[n?o:++u];if(false===r(i[f],f,i))break;
}return t}}function Vr(n,t,r){function e(){return(this&&this!==Zn&&this instanceof e?i:n).apply(u?r:this,arguments)}var u=1&t,i=Hr(n);return e}function Kr(n){return function(t){t=zu(t);var r=Bn.test(t)?$(t):F,e=r?r[0]:t.charAt(0);return t=r?zr(r,1).join(""):t.slice(1),e[n]()+t}}function Gr(n){return function(t){return h($u(Tu(t).replace(In,"")),n,"")}}function Hr(n){return function(){var t=arguments;switch(t.length){case 0:return new n;case 1:return new n(t[0]);case 2:return new n(t[0],t[1]);case 3:
return new n(t[0],t[1],t[2]);case 4:return new n(t[0],t[1],t[2],t[3]);case 5:return new n(t[0],t[1],t[2],t[3],t[4]);case 6:return new n(t[0],t[1],t[2],t[3],t[4],t[5]);case 7:return new n(t[0],t[1],t[2],t[3],t[4],t[5],t[6])}var r=io(n.prototype),t=n.apply(r,t);return bu(t)?t:r}}function Jr(n,t,e){function u(){for(var o=arguments.length,f=Hu(o),c=o,a=xe(u);c--;)f[c]=arguments[c];return c=3>o&&f[0]!==a&&f[o-1]!==a?[]:C(f,a),o-=c.length,o<e?fe(n,t,Xr,u.placeholder,F,f,c,F,F,e-o):r(this&&this!==Zn&&this instanceof u?i:n,this,f);
}var i=Hr(n);return u}function Yr(n){return function(t,r,e){var u=ni(t);if(!pu(t)){var i=je(r,3);t=Lu(t),r=function(n){return i(u[n],n,u)}}return r=n(t,r,e),-1<r?u[i?t[r]:r]:F}}function Qr(n){return ge(function(t){var r=t.length,e=r,u=zn.prototype.thru;for(n&&t.reverse();e--;){var i=t[e];if(typeof i!="function")throw new ei("Expected a function");if(u&&!o&&"wrapper"==be(i))var o=new zn([],true)}for(e=o?e:r;++e<r;)var i=t[e],u=be(i),f="wrapper"==u?_o(i):F,o=f&&Be(f[0])&&424==f[1]&&!f[4].length&&1==f[9]?o[be(f[0])].apply(o,f[3]):1==i.length&&Be(i)?o[u]():o.thru(i);
return function(){var n=arguments,e=n[0];if(o&&1==n.length&&af(e))return o.plant(e).value();for(var u=0,n=r?t[u].apply(this,n):e;++u<r;)n=t[u].call(this,n);return n}})}function Xr(n,t,r,e,u,i,o,f,c,a){function l(){for(var d=arguments.length,y=Hu(d),b=d;b--;)y[b]=arguments[b];if(_){var x,j=xe(l),b=y.length;for(x=0;b--;)y[b]===j&&++x}if(e&&(y=Cr(y,e,u,_)),i&&(y=Dr(y,i,o,_)),d-=x,_&&d<a)return j=C(y,j),fe(n,t,Xr,l.placeholder,r,y,j,f,c,a-d);if(j=h?r:this,b=p?j[n]:n,d=y.length,f){x=y.length;for(var w=Mi(f.length,x),m=Mr(y);w--;){
var A=f[w];y[w]=Re(A,x)?m[A]:F}}else v&&1<d&&y.reverse();return s&&c<d&&(y.length=c),this&&this!==Zn&&this instanceof l&&(b=g||Hr(b)),b.apply(j,y)}var s=128&t,h=1&t,p=2&t,_=24&t,v=512&t,g=p?F:Hr(n);return l}function ne(n,t){return function(r,e){return Ct(r,n,t(e))}}function te(n,t){return function(r,e){var u;if(r===F&&e===F)return t;if(r!==F&&(u=r),e!==F){if(u===F)return e;typeof r=="string"||typeof e=="string"?(r=jr(r),e=jr(e)):(r=xr(r),e=xr(e)),u=n(r,e)}return u}}function re(n){return ge(function(t){
return t=l(t,S(je())),lr(function(e){var u=this;return n(t,function(n){return r(n,u,e)})})})}function ee(n,t){t=t===F?" ":jr(t);var r=t.length;return 2>r?r?ar(t,n):t:(r=ar(t,Ri(n/T(t))),Bn.test(t)?zr($(r),0,n).join(""):r.slice(0,n))}function ue(n,t,e,u){function i(){for(var t=-1,c=arguments.length,a=-1,l=u.length,s=Hu(l+c),h=this&&this!==Zn&&this instanceof i?f:n;++a<l;)s[a]=u[a];for(;c--;)s[a++]=arguments[++t];return r(h,o?e:this,s)}var o=1&t,f=Hr(n);return i}function ie(n){return function(t,r,e){
e&&typeof e!="number"&&ze(t,r,e)&&(r=e=F),t=Eu(t),r===F?(r=t,t=0):r=Eu(r),e=e===F?t<r?1:-1:Eu(e);var u=-1;r=Di(Ri((r-t)/(e||1)),0);for(var i=Hu(r);r--;)i[n?r:++u]=t,t+=e;return i}}function oe(n){return function(t,r){return typeof t=="string"&&typeof r=="string"||(t=Iu(t),r=Iu(r)),n(t,r)}}function fe(n,t,r,e,u,i,o,f,c,a){var l=8&t,s=l?o:F;o=l?F:o;var h=l?i:F;return i=l?F:i,t=(t|(l?32:64))&~(l?64:32),4&t||(t&=-4),u=[n,t,u,h,s,i,o,f,c,a],r=r.apply(F,u),Be(n)&&xo(r,u),r.placeholder=e,De(r,n,t)}function ce(n){
var t=Xu[n];return function(n,r){if(n=Iu(n),r=null==r?0:Mi(Ou(r),292)){var e=(zu(n)+"e").split("e"),e=t(e[0]+"e"+(+e[1]+r)),e=(zu(e)+"e").split("e");return+(e[0]+"e"+(+e[1]-r))}return t(n)}}function ae(n){return function(t){var r=yo(t);return"[object Map]"==r?L(t):"[object Set]"==r?M(t):O(t,n(t))}}function le(n,t,r,e,u,i,o,f){var c=2&t;if(!c&&typeof n!="function")throw new ei("Expected a function");var a=e?e.length:0;if(a||(t&=-97,e=u=F),o=o===F?o:Di(Ou(o),0),f=f===F?f:Ou(f),a-=u?u.length:0,64&t){
var l=e,s=u;e=u=F}var h=c?F:_o(n);return i=[n,t,r,e,u,l,s,i,o,f],h&&(r=i[1],n=h[1],t=r|n,e=128==n&&8==r||128==n&&256==r&&i[7].length<=h[8]||384==n&&h[7].length<=h[8]&&8==r,131>t||e)&&(1&n&&(i[2]=h[2],t|=1&r?0:4),(r=h[3])&&(e=i[3],i[3]=e?Cr(e,r,h[4]):r,i[4]=e?C(i[3],"__lodash_placeholder__"):h[4]),(r=h[5])&&(e=i[5],i[5]=e?Dr(e,r,h[6]):r,i[6]=e?C(i[5],"__lodash_placeholder__"):h[6]),(r=h[7])&&(i[7]=r),128&n&&(i[8]=null==i[8]?h[8]:Mi(i[8],h[8])),null==i[9]&&(i[9]=h[9]),i[0]=h[0],i[1]=t),n=i[0],t=i[1],
r=i[2],e=i[3],u=i[4],f=i[9]=i[9]===F?c?0:n.length:Di(i[9]-a,0),!f&&24&t&&(t&=-25),De((h?lo:xo)(t&&1!=t?8==t||16==t?Jr(n,t,f):32!=t&&33!=t||u.length?Xr.apply(F,i):ue(n,t,r,e):Vr(n,t,r),i),n,t)}function se(n,t,r,e){return n===F||hu(n,ii[r])&&!ci.call(e,r)?t:n}function he(n,t,r,e,u,i){return bu(n)&&bu(t)&&(i.set(t,n),nr(n,t,F,he,i),i.delete(t)),n}function pe(n){return wu(n)?F:n}function _e(n,t,r,e,u,i){var o=1&r,f=n.length,c=t.length;if(f!=c&&!(o&&c>f))return false;if((c=i.get(n))&&i.get(t))return c==t;var c=-1,a=true,l=2&r?new qn:F;
for(i.set(n,t),i.set(t,n);++c<f;){var s=n[c],h=t[c];if(e)var p=o?e(h,s,c,t,n,i):e(s,h,c,n,t,i);if(p!==F){if(p)continue;a=false;break}if(l){if(!_(t,function(n,t){if(!R(l,t)&&(s===n||u(s,n,r,e,i)))return l.push(t)})){a=false;break}}else if(s!==h&&!u(s,h,r,e,i)){a=false;break}}return i.delete(n),i.delete(t),a}function ve(n,t,r,e,u,i,o){switch(r){case"[object DataView]":if(n.byteLength!=t.byteLength||n.byteOffset!=t.byteOffset)break;n=n.buffer,t=t.buffer;case"[object ArrayBuffer]":if(n.byteLength!=t.byteLength||!i(new di(n),new di(t)))break;
return true;case"[object Boolean]":case"[object Date]":case"[object Number]":return hu(+n,+t);case"[object Error]":return n.name==t.name&&n.message==t.message;case"[object RegExp]":case"[object String]":return n==t+"";case"[object Map]":var f=L;case"[object Set]":if(f||(f=D),n.size!=t.size&&!(1&e))break;return(r=o.get(n))?r==t:(e|=2,o.set(n,t),t=_e(f(n),f(t),e,u,i,o),o.delete(n),t);case"[object Symbol]":if(eo)return eo.call(n)==eo.call(t)}return false}function ge(n){return wo(Ce(n,F,Ve),n+"")}function de(n){
return Rt(n,Lu,vo)}function ye(n){return Rt(n,Uu,go)}function be(n){for(var t=n.name+"",r=Ji[t],e=ci.call(Ji,t)?r.length:0;e--;){var u=r[e],i=u.func;if(null==i||i==n)return u.name}return t}function xe(n){return(ci.call(On,"placeholder")?On:n).placeholder}function je(){var n=On.iteratee||Pu,n=n===Pu?Gt:n;return arguments.length?n(arguments[0],arguments[1]):n}function we(n,t){var r=n.__data__,e=typeof t;return("string"==e||"number"==e||"symbol"==e||"boolean"==e?"__proto__"!==t:null===t)?r[typeof t=="string"?"string":"hash"]:r.map;
}function me(n){for(var t=Lu(n),r=t.length;r--;){var e=t[r],u=n[e];t[r]=[e,u,u===u&&!bu(u)]}return t}function Ae(n,t){var r=null==n?F:n[t];return Zt(r)?r:F}function ke(n,t,r){t=Rr(t,n);for(var e=-1,u=t.length,i=false;++e<u;){var o=$e(t[e]);if(!(i=null!=n&&r(n,o)))break;n=n[o]}return i||++e!=u?i:(u=null==n?0:n.length,!!u&&yu(u)&&Re(o,u)&&(af(n)||cf(n)))}function Ee(n){var t=n.length,r=n.constructor(t);return t&&"string"==typeof n[0]&&ci.call(n,"index")&&(r.index=n.index,r.input=n.input),r}function Oe(n){
return typeof n.constructor!="function"||Le(n)?{}:io(bi(n))}function Se(r,e,u,i){var o=r.constructor;switch(e){case"[object ArrayBuffer]":return Br(r);case"[object Boolean]":case"[object Date]":return new o(+r);case"[object DataView]":return e=i?Br(r.buffer):r.buffer,new r.constructor(e,r.byteOffset,r.byteLength);case"[object Float32Array]":case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]":
case"[object Uint16Array]":case"[object Uint32Array]":return Lr(r,i);case"[object Map]":return e=i?u(L(r),1):L(r),h(e,n,new r.constructor);case"[object Number]":case"[object String]":return new o(r);case"[object RegExp]":return e=new r.constructor(r.source,dn.exec(r)),e.lastIndex=r.lastIndex,e;case"[object Set]":return e=i?u(D(r),1):D(r),h(e,t,new r.constructor);case"[object Symbol]":return eo?ni(eo.call(r)):{}}}function Ie(n){return af(n)||cf(n)||!!(mi&&n&&n[mi])}function Re(n,t){return t=null==t?9007199254740991:t,
!!t&&(typeof n=="number"||wn.test(n))&&-1<n&&0==n%1&&n<t}function ze(n,t,r){if(!bu(r))return false;var e=typeof t;return!!("number"==e?pu(r)&&Re(t,r.length):"string"==e&&t in r)&&hu(r[t],n)}function We(n,t){if(af(n))return false;var r=typeof n;return!("number"!=r&&"symbol"!=r&&"boolean"!=r&&null!=n&&!Au(n))||(rn.test(n)||!tn.test(n)||null!=t&&n in ni(t))}function Be(n){var t=be(n),r=On[t];return typeof r=="function"&&t in Mn.prototype&&(n===r||(t=_o(r),!!t&&n===t[0]))}function Le(n){var t=n&&n.constructor;
return n===(typeof t=="function"&&t.prototype||ii)}function Ue(n,t){return function(r){return null!=r&&(r[n]===t&&(t!==F||n in ni(r)))}}function Ce(n,t,e){return t=Di(t===F?n.length-1:t,0),function(){for(var u=arguments,i=-1,o=Di(u.length-t,0),f=Hu(o);++i<o;)f[i]=u[t+i];for(i=-1,o=Hu(t+1);++i<t;)o[i]=u[i];return o[t]=e(f),r(n,this,o)}}function De(n,t,r){var e=t+"";t=wo;var u,i=Ne;return u=(u=e.match(hn))?u[1].split(pn):[],r=i(u,r),(i=r.length)&&(u=i-1,r[u]=(1<i?"& ":"")+r[u],r=r.join(2<i?", ":" "),
e=e.replace(sn,"{\n/* [wrapped with "+r+"] */\n")),t(n,e)}function Me(n){var t=0,r=0;return function(){var e=Ti(),u=16-(e-r);if(r=e,0<u){if(800<=++t)return arguments[0]}else t=0;return n.apply(F,arguments)}}function Te(n,t){var r=-1,e=n.length,u=e-1;for(t=t===F?e:t;++r<t;){var e=cr(r,u),i=n[e];n[e]=n[r],n[r]=i}return n.length=t,n}function $e(n){if(typeof n=="string"||Au(n))return n;var t=n+"";return"0"==t&&1/n==-N?"-0":t}function Fe(n){if(null!=n){try{return fi.call(n)}catch(n){}return n+""}return"";
}function Ne(n,t){return u(Z,function(r){var e="_."+r[0];t&r[1]&&!c(n,e)&&n.push(e)}),n.sort()}function Pe(n){if(n instanceof Mn)return n.clone();var t=new zn(n.__wrapped__,n.__chain__);return t.__actions__=Mr(n.__actions__),t.__index__=n.__index__,t.__values__=n.__values__,t}function Ze(n,t,r){var e=null==n?0:n.length;return e?(r=null==r?0:Ou(r),0>r&&(r=Di(e+r,0)),g(n,je(t,3),r)):-1}function qe(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e-1;return r!==F&&(u=Ou(r),u=0>r?Di(e+u,0):Mi(u,e-1)),
g(n,je(t,3),u,true)}function Ve(n){return(null==n?0:n.length)?kt(n,1):[]}function Ke(n){return n&&n.length?n[0]:F}function Ge(n){var t=null==n?0:n.length;return t?n[t-1]:F}function He(n,t){return n&&n.length&&t&&t.length?or(n,t):n}function Je(n){return null==n?n:Ni.call(n)}function Ye(n){if(!n||!n.length)return[];var t=0;return n=f(n,function(n){if(_u(n))return t=Di(n.length,t),true}),E(t,function(t){return l(n,j(t))})}function Qe(n,t){if(!n||!n.length)return[];var e=Ye(n);return null==t?e:l(e,function(n){
return r(t,F,n)})}function Xe(n){return n=On(n),n.__chain__=true,n}function nu(n,t){return t(n)}function tu(){return this}function ru(n,t){return(af(n)?u:oo)(n,je(t,3))}function eu(n,t){return(af(n)?i:fo)(n,je(t,3))}function uu(n,t){return(af(n)?l:Yt)(n,je(t,3))}function iu(n,t,r){return t=r?F:t,t=n&&null==t?n.length:t,le(n,128,F,F,F,F,t)}function ou(n,t){var r;if(typeof t!="function")throw new ei("Expected a function");return n=Ou(n),function(){return 0<--n&&(r=t.apply(this,arguments)),1>=n&&(t=F),
r}}function fu(n,t,r){return t=r?F:t,n=le(n,8,F,F,F,F,F,t),n.placeholder=fu.placeholder,n}function cu(n,t,r){return t=r?F:t,n=le(n,16,F,F,F,F,F,t),n.placeholder=cu.placeholder,n}function au(n,t,r){function e(t){var r=c,e=a;return c=a=F,_=t,s=n.apply(e,r)}function u(n){var r=n-p;return n-=_,p===F||r>=t||0>r||g&&n>=l}function i(){var n=Jo();if(u(n))return o(n);var r,e=jo;r=n-_,n=t-(n-p),r=g?Mi(n,l-r):n,h=e(i,r)}function o(n){return h=F,d&&c?e(n):(c=a=F,s)}function f(){var n=Jo(),r=u(n);if(c=arguments,
a=this,p=n,r){if(h===F)return _=n=p,h=jo(i,t),v?e(n):s;if(g)return h=jo(i,t),e(p)}return h===F&&(h=jo(i,t)),s}var c,a,l,s,h,p,_=0,v=false,g=false,d=true;if(typeof n!="function")throw new ei("Expected a function");return t=Iu(t)||0,bu(r)&&(v=!!r.leading,l=(g="maxWait"in r)?Di(Iu(r.maxWait)||0,t):l,d="trailing"in r?!!r.trailing:d),f.cancel=function(){h!==F&&ho(h),_=0,c=p=a=h=F},f.flush=function(){return h===F?s:o(Jo())},f}function lu(n,t){function r(){var e=arguments,u=t?t.apply(this,e):e[0],i=r.cache;return i.has(u)?i.get(u):(e=n.apply(this,e),
r.cache=i.set(u,e)||i,e)}if(typeof n!="function"||null!=t&&typeof t!="function")throw new ei("Expected a function");return r.cache=new(lu.Cache||Pn),r}function su(n){if(typeof n!="function")throw new ei("Expected a function");return function(){var t=arguments;switch(t.length){case 0:return!n.call(this);case 1:return!n.call(this,t[0]);case 2:return!n.call(this,t[0],t[1]);case 3:return!n.call(this,t[0],t[1],t[2])}return!n.apply(this,t)}}function hu(n,t){return n===t||n!==n&&t!==t}function pu(n){return null!=n&&yu(n.length)&&!gu(n);
}function _u(n){return xu(n)&&pu(n)}function vu(n){if(!xu(n))return false;var t=zt(n);return"[object Error]"==t||"[object DOMException]"==t||typeof n.message=="string"&&typeof n.name=="string"&&!wu(n)}function gu(n){return!!bu(n)&&(n=zt(n),"[object Function]"==n||"[object GeneratorFunction]"==n||"[object AsyncFunction]"==n||"[object Proxy]"==n)}function du(n){return typeof n=="number"&&n==Ou(n)}function yu(n){return typeof n=="number"&&-1<n&&0==n%1&&9007199254740991>=n}function bu(n){var t=typeof n;return null!=n&&("object"==t||"function"==t);
}function xu(n){return null!=n&&typeof n=="object"}function ju(n){return typeof n=="number"||xu(n)&&"[object Number]"==zt(n)}function wu(n){return!(!xu(n)||"[object Object]"!=zt(n))&&(n=bi(n),null===n||(n=ci.call(n,"constructor")&&n.constructor,typeof n=="function"&&n instanceof n&&fi.call(n)==hi))}function mu(n){return typeof n=="string"||!af(n)&&xu(n)&&"[object String]"==zt(n)}function Au(n){return typeof n=="symbol"||xu(n)&&"[object Symbol]"==zt(n)}function ku(n){if(!n)return[];if(pu(n))return mu(n)?$(n):Mr(n);
if(Ai&&n[Ai]){n=n[Ai]();for(var t,r=[];!(t=n.next()).done;)r.push(t.value);return r}return t=yo(n),("[object Map]"==t?L:"[object Set]"==t?D:Du)(n)}function Eu(n){return n?(n=Iu(n),n===N||n===-N?1.7976931348623157e308*(0>n?-1:1):n===n?n:0):0===n?n:0}function Ou(n){n=Eu(n);var t=n%1;return n===n?t?n-t:n:0}function Su(n){return n?gt(Ou(n),0,4294967295):0}function Iu(n){if(typeof n=="number")return n;if(Au(n))return P;if(bu(n)&&(n=typeof n.valueOf=="function"?n.valueOf():n,n=bu(n)?n+"":n),typeof n!="string")return 0===n?n:+n;
n=n.replace(cn,"");var t=bn.test(n);return t||jn.test(n)?Fn(n.slice(2),t?2:8):yn.test(n)?P:+n}function Ru(n){return Tr(n,Uu(n))}function zu(n){return null==n?"":jr(n)}function Wu(n,t,r){return n=null==n?F:It(n,t),n===F?r:n}function Bu(n,t){return null!=n&&ke(n,t,Lt)}function Lu(n){return pu(n)?Gn(n):Ht(n)}function Uu(n){if(pu(n))n=Gn(n,true);else if(bu(n)){var t,r=Le(n),e=[];for(t in n)("constructor"!=t||!r&&ci.call(n,t))&&e.push(t);n=e}else{if(t=[],null!=n)for(r in ni(n))t.push(r);n=t}return n}function Cu(n,t){
if(null==n)return{};var r=l(ye(n),function(n){return[n]});return t=je(t),ur(n,r,function(n,r){return t(n,r[0])})}function Du(n){return null==n?[]:I(n,Lu(n))}function Mu(n){return Nf(zu(n).toLowerCase())}function Tu(n){return(n=zu(n))&&n.replace(mn,rt).replace(Rn,"")}function $u(n,t,r){return n=zu(n),t=r?F:t,t===F?Ln.test(n)?n.match(Wn)||[]:n.match(_n)||[]:n.match(t)||[]}function Fu(n){return function(){return n}}function Nu(n){return n}function Pu(n){return Gt(typeof n=="function"?n:dt(n,1))}function Zu(n,t,r){
var e=Lu(t),i=St(t,e);null!=r||bu(t)&&(i.length||!e.length)||(r=t,t=n,n=this,i=St(t,Lu(t)));var o=!(bu(r)&&"chain"in r&&!r.chain),f=gu(n);return u(i,function(r){var e=t[r];n[r]=e,f&&(n.prototype[r]=function(){var t=this.__chain__;if(o||t){var r=n(this.__wrapped__);return(r.__actions__=Mr(this.__actions__)).push({func:e,args:arguments,thisArg:n}),r.__chain__=t,r}return e.apply(n,s([this.value()],arguments))})}),n}function qu(){}function Vu(n){return We(n)?j($e(n)):ir(n)}function Ku(){return[]}function Gu(){
return false}En=null==En?Zn:it.defaults(Zn.Object(),En,it.pick(Zn,Un));var Hu=En.Array,Ju=En.Date,Yu=En.Error,Qu=En.Function,Xu=En.Math,ni=En.Object,ti=En.RegExp,ri=En.String,ei=En.TypeError,ui=Hu.prototype,ii=ni.prototype,oi=En["__core-js_shared__"],fi=Qu.prototype.toString,ci=ii.hasOwnProperty,ai=0,li=function(){var n=/[^.]+$/.exec(oi&&oi.keys&&oi.keys.IE_PROTO||"");return n?"Symbol(src)_1."+n:""}(),si=ii.toString,hi=fi.call(ni),pi=Zn._,_i=ti("^"+fi.call(ci).replace(on,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),vi=Kn?En.Buffer:F,gi=En.Symbol,di=En.Uint8Array,yi=vi?vi.f:F,bi=U(ni.getPrototypeOf,ni),xi=ni.create,ji=ii.propertyIsEnumerable,wi=ui.splice,mi=gi?gi.isConcatSpreadable:F,Ai=gi?gi.iterator:F,ki=gi?gi.toStringTag:F,Ei=function(){
try{var n=Ae(ni,"defineProperty");return n({},"",{}),n}catch(n){}}(),Oi=En.clearTimeout!==Zn.clearTimeout&&En.clearTimeout,Si=Ju&&Ju.now!==Zn.Date.now&&Ju.now,Ii=En.setTimeout!==Zn.setTimeout&&En.setTimeout,Ri=Xu.ceil,zi=Xu.floor,Wi=ni.getOwnPropertySymbols,Bi=vi?vi.isBuffer:F,Li=En.isFinite,Ui=ui.join,Ci=U(ni.keys,ni),Di=Xu.max,Mi=Xu.min,Ti=Ju.now,$i=En.parseInt,Fi=Xu.random,Ni=ui.reverse,Pi=Ae(En,"DataView"),Zi=Ae(En,"Map"),qi=Ae(En,"Promise"),Vi=Ae(En,"Set"),Ki=Ae(En,"WeakMap"),Gi=Ae(ni,"create"),Hi=Ki&&new Ki,Ji={},Yi=Fe(Pi),Qi=Fe(Zi),Xi=Fe(qi),no=Fe(Vi),to=Fe(Ki),ro=gi?gi.prototype:F,eo=ro?ro.valueOf:F,uo=ro?ro.toString:F,io=function(){
function n(){}return function(t){return bu(t)?xi?xi(t):(n.prototype=t,t=new n,n.prototype=F,t):{}}}();On.templateSettings={escape:Q,evaluate:X,interpolate:nn,variable:"",imports:{_:On}},On.prototype=Sn.prototype,On.prototype.constructor=On,zn.prototype=io(Sn.prototype),zn.prototype.constructor=zn,Mn.prototype=io(Sn.prototype),Mn.prototype.constructor=Mn,Tn.prototype.clear=function(){this.__data__=Gi?Gi(null):{},this.size=0},Tn.prototype.delete=function(n){return n=this.has(n)&&delete this.__data__[n],
this.size-=n?1:0,n},Tn.prototype.get=function(n){var t=this.__data__;return Gi?(n=t[n],"__lodash_hash_undefined__"===n?F:n):ci.call(t,n)?t[n]:F},Tn.prototype.has=function(n){var t=this.__data__;return Gi?t[n]!==F:ci.call(t,n)},Tn.prototype.set=function(n,t){var r=this.__data__;return this.size+=this.has(n)?0:1,r[n]=Gi&&t===F?"__lodash_hash_undefined__":t,this},Nn.prototype.clear=function(){this.__data__=[],this.size=0},Nn.prototype.delete=function(n){var t=this.__data__;return n=lt(t,n),!(0>n)&&(n==t.length-1?t.pop():wi.call(t,n,1),
--this.size,true)},Nn.prototype.get=function(n){var t=this.__data__;return n=lt(t,n),0>n?F:t[n][1]},Nn.prototype.has=function(n){return-1<lt(this.__data__,n)},Nn.prototype.set=function(n,t){var r=this.__data__,e=lt(r,n);return 0>e?(++this.size,r.push([n,t])):r[e][1]=t,this},Pn.prototype.clear=function(){this.size=0,this.__data__={hash:new Tn,map:new(Zi||Nn),string:new Tn}},Pn.prototype.delete=function(n){return n=we(this,n).delete(n),this.size-=n?1:0,n},Pn.prototype.get=function(n){return we(this,n).get(n);
},Pn.prototype.has=function(n){return we(this,n).has(n)},Pn.prototype.set=function(n,t){var r=we(this,n),e=r.size;return r.set(n,t),this.size+=r.size==e?0:1,this},qn.prototype.add=qn.prototype.push=function(n){return this.__data__.set(n,"__lodash_hash_undefined__"),this},qn.prototype.has=function(n){return this.__data__.has(n)},Vn.prototype.clear=function(){this.__data__=new Nn,this.size=0},Vn.prototype.delete=function(n){var t=this.__data__;return n=t.delete(n),this.size=t.size,n},Vn.prototype.get=function(n){
return this.__data__.get(n)},Vn.prototype.has=function(n){return this.__data__.has(n)},Vn.prototype.set=function(n,t){var r=this.__data__;if(r instanceof Nn){var e=r.__data__;if(!Zi||199>e.length)return e.push([n,t]),this.size=++r.size,this;r=this.__data__=new Pn(e)}return r.set(n,t),this.size=r.size,this};var oo=Zr(Et),fo=Zr(Ot,true),co=qr(),ao=qr(true),lo=Hi?function(n,t){return Hi.set(n,t),n}:Nu,so=Ei?function(n,t){return Ei(n,"toString",{configurable:true,enumerable:false,value:Fu(t),writable:true})}:Nu,ho=Oi||function(n){
return Zn.clearTimeout(n)},po=Vi&&1/D(new Vi([,-0]))[1]==N?function(n){return new Vi(n)}:qu,_o=Hi?function(n){return Hi.get(n)}:qu,vo=Wi?function(n){return null==n?[]:(n=ni(n),f(Wi(n),function(t){return ji.call(n,t)}))}:Ku,go=Wi?function(n){for(var t=[];n;)s(t,vo(n)),n=bi(n);return t}:Ku,yo=zt;(Pi&&"[object DataView]"!=yo(new Pi(new ArrayBuffer(1)))||Zi&&"[object Map]"!=yo(new Zi)||qi&&"[object Promise]"!=yo(qi.resolve())||Vi&&"[object Set]"!=yo(new Vi)||Ki&&"[object WeakMap]"!=yo(new Ki))&&(yo=function(n){
var t=zt(n);if(n=(n="[object Object]"==t?n.constructor:F)?Fe(n):"")switch(n){case Yi:return"[object DataView]";case Qi:return"[object Map]";case Xi:return"[object Promise]";case no:return"[object Set]";case to:return"[object WeakMap]"}return t});var bo=oi?gu:Gu,xo=Me(lo),jo=Ii||function(n,t){return Zn.setTimeout(n,t)},wo=Me(so),mo=function(n){n=lu(n,function(n){return 500===t.size&&t.clear(),n});var t=n.cache;return n}(function(n){var t=[];return en.test(n)&&t.push(""),n.replace(un,function(n,r,e,u){
t.push(e?u.replace(vn,"$1"):r||n)}),t}),Ao=lr(function(n,t){return _u(n)?jt(n,kt(t,1,_u,true)):[]}),ko=lr(function(n,t){var r=Ge(t);return _u(r)&&(r=F),_u(n)?jt(n,kt(t,1,_u,true),je(r,2)):[]}),Eo=lr(function(n,t){var r=Ge(t);return _u(r)&&(r=F),_u(n)?jt(n,kt(t,1,_u,true),F,r):[]}),Oo=lr(function(n){var t=l(n,Sr);return t.length&&t[0]===n[0]?Ut(t):[]}),So=lr(function(n){var t=Ge(n),r=l(n,Sr);return t===Ge(r)?t=F:r.pop(),r.length&&r[0]===n[0]?Ut(r,je(t,2)):[]}),Io=lr(function(n){var t=Ge(n),r=l(n,Sr);return(t=typeof t=="function"?t:F)&&r.pop(),
r.length&&r[0]===n[0]?Ut(r,F,t):[]}),Ro=lr(He),zo=ge(function(n,t){var r=null==n?0:n.length,e=vt(n,t);return fr(n,l(t,function(n){return Re(n,r)?+n:n}).sort(Ur)),e}),Wo=lr(function(n){return wr(kt(n,1,_u,true))}),Bo=lr(function(n){var t=Ge(n);return _u(t)&&(t=F),wr(kt(n,1,_u,true),je(t,2))}),Lo=lr(function(n){var t=Ge(n),t=typeof t=="function"?t:F;return wr(kt(n,1,_u,true),F,t)}),Uo=lr(function(n,t){return _u(n)?jt(n,t):[]}),Co=lr(function(n){return Er(f(n,_u))}),Do=lr(function(n){var t=Ge(n);return _u(t)&&(t=F),
Er(f(n,_u),je(t,2))}),Mo=lr(function(n){var t=Ge(n),t=typeof t=="function"?t:F;return Er(f(n,_u),F,t)}),To=lr(Ye),$o=lr(function(n){var t=n.length,t=1<t?n[t-1]:F,t=typeof t=="function"?(n.pop(),t):F;return Qe(n,t)}),Fo=ge(function(n){function t(t){return vt(t,n)}var r=n.length,e=r?n[0]:0,u=this.__wrapped__;return!(1<r||this.__actions__.length)&&u instanceof Mn&&Re(e)?(u=u.slice(e,+e+(r?1:0)),u.__actions__.push({func:nu,args:[t],thisArg:F}),new zn(u,this.__chain__).thru(function(n){return r&&!n.length&&n.push(F),
n})):this.thru(t)}),No=Nr(function(n,t,r){ci.call(n,r)?++n[r]:_t(n,r,1)}),Po=Yr(Ze),Zo=Yr(qe),qo=Nr(function(n,t,r){ci.call(n,r)?n[r].push(t):_t(n,r,[t])}),Vo=lr(function(n,t,e){var u=-1,i=typeof t=="function",o=pu(n)?Hu(n.length):[];return oo(n,function(n){o[++u]=i?r(t,n,e):Dt(n,t,e)}),o}),Ko=Nr(function(n,t,r){_t(n,r,t)}),Go=Nr(function(n,t,r){n[r?0:1].push(t)},function(){return[[],[]]}),Ho=lr(function(n,t){if(null==n)return[];var r=t.length;return 1<r&&ze(n,t[0],t[1])?t=[]:2<r&&ze(t[0],t[1],t[2])&&(t=[t[0]]),
rr(n,kt(t,1),[])}),Jo=Si||function(){return Zn.Date.now()},Yo=lr(function(n,t,r){var e=1;if(r.length)var u=C(r,xe(Yo)),e=32|e;return le(n,e,t,r,u)}),Qo=lr(function(n,t,r){var e=3;if(r.length)var u=C(r,xe(Qo)),e=32|e;return le(t,e,n,r,u)}),Xo=lr(function(n,t){return xt(n,1,t)}),nf=lr(function(n,t,r){return xt(n,Iu(t)||0,r)});lu.Cache=Pn;var tf=lr(function(n,t){t=1==t.length&&af(t[0])?l(t[0],S(je())):l(kt(t,1),S(je()));var e=t.length;return lr(function(u){for(var i=-1,o=Mi(u.length,e);++i<o;)u[i]=t[i].call(this,u[i]);
return r(n,this,u)})}),rf=lr(function(n,t){return le(n,32,F,t,C(t,xe(rf)))}),ef=lr(function(n,t){return le(n,64,F,t,C(t,xe(ef)))}),uf=ge(function(n,t){return le(n,256,F,F,F,t)}),of=oe(Wt),ff=oe(function(n,t){return n>=t}),cf=Mt(function(){return arguments}())?Mt:function(n){return xu(n)&&ci.call(n,"callee")&&!ji.call(n,"callee")},af=Hu.isArray,lf=Hn?S(Hn):Tt,sf=Bi||Gu,hf=Jn?S(Jn):$t,pf=Yn?S(Yn):Nt,_f=Qn?S(Qn):qt,vf=Xn?S(Xn):Vt,gf=nt?S(nt):Kt,df=oe(Jt),yf=oe(function(n,t){return n<=t}),bf=Pr(function(n,t){
if(Le(t)||pu(t))Tr(t,Lu(t),n);else for(var r in t)ci.call(t,r)&&at(n,r,t[r])}),xf=Pr(function(n,t){Tr(t,Uu(t),n)}),jf=Pr(function(n,t,r,e){Tr(t,Uu(t),n,e)}),wf=Pr(function(n,t,r,e){Tr(t,Lu(t),n,e)}),mf=ge(vt),Af=lr(function(n){return n.push(F,se),r(jf,F,n)}),kf=lr(function(n){return n.push(F,he),r(Rf,F,n)}),Ef=ne(function(n,t,r){n[t]=r},Fu(Nu)),Of=ne(function(n,t,r){ci.call(n,t)?n[t].push(r):n[t]=[r]},je),Sf=lr(Dt),If=Pr(function(n,t,r){nr(n,t,r)}),Rf=Pr(function(n,t,r,e){nr(n,t,r,e)}),zf=ge(function(n,t){
var r={};if(null==n)return r;var e=false;t=l(t,function(t){return t=Rr(t,n),e||(e=1<t.length),t}),Tr(n,ye(n),r),e&&(r=dt(r,7,pe));for(var u=t.length;u--;)mr(r,t[u]);return r}),Wf=ge(function(n,t){return null==n?{}:er(n,t)}),Bf=ae(Lu),Lf=ae(Uu),Uf=Gr(function(n,t,r){return t=t.toLowerCase(),n+(r?Mu(t):t)}),Cf=Gr(function(n,t,r){return n+(r?"-":"")+t.toLowerCase()}),Df=Gr(function(n,t,r){return n+(r?" ":"")+t.toLowerCase()}),Mf=Kr("toLowerCase"),Tf=Gr(function(n,t,r){return n+(r?"_":"")+t.toLowerCase();
}),$f=Gr(function(n,t,r){return n+(r?" ":"")+Nf(t)}),Ff=Gr(function(n,t,r){return n+(r?" ":"")+t.toUpperCase()}),Nf=Kr("toUpperCase"),Pf=lr(function(n,t){try{return r(n,F,t)}catch(n){return vu(n)?n:new Yu(n)}}),Zf=ge(function(n,t){return u(t,function(t){t=$e(t),_t(n,t,Yo(n[t],n))}),n}),qf=Qr(),Vf=Qr(true),Kf=lr(function(n,t){return function(r){return Dt(r,n,t)}}),Gf=lr(function(n,t){return function(r){return Dt(n,r,t)}}),Hf=re(l),Jf=re(o),Yf=re(_),Qf=ie(),Xf=ie(true),nc=te(function(n,t){return n+t},0),tc=ce("ceil"),rc=te(function(n,t){
return n/t},1),ec=ce("floor"),uc=te(function(n,t){return n*t},1),ic=ce("round"),oc=te(function(n,t){return n-t},0);return On.after=function(n,t){if(typeof t!="function")throw new ei("Expected a function");return n=Ou(n),function(){if(1>--n)return t.apply(this,arguments)}},On.ary=iu,On.assign=bf,On.assignIn=xf,On.assignInWith=jf,On.assignWith=wf,On.at=mf,On.before=ou,On.bind=Yo,On.bindAll=Zf,On.bindKey=Qo,On.castArray=function(){if(!arguments.length)return[];var n=arguments[0];return af(n)?n:[n]},
On.chain=Xe,On.chunk=function(n,t,r){if(t=(r?ze(n,t,r):t===F)?1:Di(Ou(t),0),r=null==n?0:n.length,!r||1>t)return[];for(var e=0,u=0,i=Hu(Ri(r/t));e<r;)i[u++]=vr(n,e,e+=t);return i},On.compact=function(n){for(var t=-1,r=null==n?0:n.length,e=0,u=[];++t<r;){var i=n[t];i&&(u[e++]=i)}return u},On.concat=function(){var n=arguments.length;if(!n)return[];for(var t=Hu(n-1),r=arguments[0];n--;)t[n-1]=arguments[n];return s(af(r)?Mr(r):[r],kt(t,1))},On.cond=function(n){var t=null==n?0:n.length,e=je();return n=t?l(n,function(n){
if("function"!=typeof n[1])throw new ei("Expected a function");return[e(n[0]),n[1]]}):[],lr(function(e){for(var u=-1;++u<t;){var i=n[u];if(r(i[0],this,e))return r(i[1],this,e)}})},On.conforms=function(n){return yt(dt(n,1))},On.constant=Fu,On.countBy=No,On.create=function(n,t){var r=io(n);return null==t?r:ht(r,t)},On.curry=fu,On.curryRight=cu,On.debounce=au,On.defaults=Af,On.defaultsDeep=kf,On.defer=Xo,On.delay=nf,On.difference=Ao,On.differenceBy=ko,On.differenceWith=Eo,On.drop=function(n,t,r){var e=null==n?0:n.length;
return e?(t=r||t===F?1:Ou(t),vr(n,0>t?0:t,e)):[]},On.dropRight=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===F?1:Ou(t),t=e-t,vr(n,0,0>t?0:t)):[]},On.dropRightWhile=function(n,t){return n&&n.length?Ar(n,je(t,3),true,true):[]},On.dropWhile=function(n,t){return n&&n.length?Ar(n,je(t,3),true):[]},On.fill=function(n,t,r,e){var u=null==n?0:n.length;if(!u)return[];for(r&&typeof r!="number"&&ze(n,t,r)&&(r=0,e=u),u=n.length,r=Ou(r),0>r&&(r=-r>u?0:u+r),e=e===F||e>u?u:Ou(e),0>e&&(e+=u),e=r>e?0:Su(e);r<e;)n[r++]=t;
return n},On.filter=function(n,t){return(af(n)?f:At)(n,je(t,3))},On.flatMap=function(n,t){return kt(uu(n,t),1)},On.flatMapDeep=function(n,t){return kt(uu(n,t),N)},On.flatMapDepth=function(n,t,r){return r=r===F?1:Ou(r),kt(uu(n,t),r)},On.flatten=Ve,On.flattenDeep=function(n){return(null==n?0:n.length)?kt(n,N):[]},On.flattenDepth=function(n,t){return null!=n&&n.length?(t=t===F?1:Ou(t),kt(n,t)):[]},On.flip=function(n){return le(n,512)},On.flow=qf,On.flowRight=Vf,On.fromPairs=function(n){for(var t=-1,r=null==n?0:n.length,e={};++t<r;){
var u=n[t];e[u[0]]=u[1]}return e},On.functions=function(n){return null==n?[]:St(n,Lu(n))},On.functionsIn=function(n){return null==n?[]:St(n,Uu(n))},On.groupBy=qo,On.initial=function(n){return(null==n?0:n.length)?vr(n,0,-1):[]},On.intersection=Oo,On.intersectionBy=So,On.intersectionWith=Io,On.invert=Ef,On.invertBy=Of,On.invokeMap=Vo,On.iteratee=Pu,On.keyBy=Ko,On.keys=Lu,On.keysIn=Uu,On.map=uu,On.mapKeys=function(n,t){var r={};return t=je(t,3),Et(n,function(n,e,u){_t(r,t(n,e,u),n)}),r},On.mapValues=function(n,t){
var r={};return t=je(t,3),Et(n,function(n,e,u){_t(r,e,t(n,e,u))}),r},On.matches=function(n){return Qt(dt(n,1))},On.matchesProperty=function(n,t){return Xt(n,dt(t,1))},On.memoize=lu,On.merge=If,On.mergeWith=Rf,On.method=Kf,On.methodOf=Gf,On.mixin=Zu,On.negate=su,On.nthArg=function(n){return n=Ou(n),lr(function(t){return tr(t,n)})},On.omit=zf,On.omitBy=function(n,t){return Cu(n,su(je(t)))},On.once=function(n){return ou(2,n)},On.orderBy=function(n,t,r,e){return null==n?[]:(af(t)||(t=null==t?[]:[t]),
r=e?F:r,af(r)||(r=null==r?[]:[r]),rr(n,t,r))},On.over=Hf,On.overArgs=tf,On.overEvery=Jf,On.overSome=Yf,On.partial=rf,On.partialRight=ef,On.partition=Go,On.pick=Wf,On.pickBy=Cu,On.property=Vu,On.propertyOf=function(n){return function(t){return null==n?F:It(n,t)}},On.pull=Ro,On.pullAll=He,On.pullAllBy=function(n,t,r){return n&&n.length&&t&&t.length?or(n,t,je(r,2)):n},On.pullAllWith=function(n,t,r){return n&&n.length&&t&&t.length?or(n,t,F,r):n},On.pullAt=zo,On.range=Qf,On.rangeRight=Xf,On.rearg=uf,On.reject=function(n,t){
return(af(n)?f:At)(n,su(je(t,3)))},On.remove=function(n,t){var r=[];if(!n||!n.length)return r;var e=-1,u=[],i=n.length;for(t=je(t,3);++e<i;){var o=n[e];t(o,e,n)&&(r.push(o),u.push(e))}return fr(n,u),r},On.rest=function(n,t){if(typeof n!="function")throw new ei("Expected a function");return t=t===F?t:Ou(t),lr(n,t)},On.reverse=Je,On.sampleSize=function(n,t,r){return t=(r?ze(n,t,r):t===F)?1:Ou(t),(af(n)?ot:hr)(n,t)},On.set=function(n,t,r){return null==n?n:pr(n,t,r)},On.setWith=function(n,t,r,e){return e=typeof e=="function"?e:F,
null==n?n:pr(n,t,r,e)},On.shuffle=function(n){return(af(n)?ft:_r)(n)},On.slice=function(n,t,r){var e=null==n?0:n.length;return e?(r&&typeof r!="number"&&ze(n,t,r)?(t=0,r=e):(t=null==t?0:Ou(t),r=r===F?e:Ou(r)),vr(n,t,r)):[]},On.sortBy=Ho,On.sortedUniq=function(n){return n&&n.length?br(n):[]},On.sortedUniqBy=function(n,t){return n&&n.length?br(n,je(t,2)):[]},On.split=function(n,t,r){return r&&typeof r!="number"&&ze(n,t,r)&&(t=r=F),r=r===F?4294967295:r>>>0,r?(n=zu(n))&&(typeof t=="string"||null!=t&&!_f(t))&&(t=jr(t),
!t&&Bn.test(n))?zr($(n),0,r):n.split(t,r):[]},On.spread=function(n,t){if(typeof n!="function")throw new ei("Expected a function");return t=null==t?0:Di(Ou(t),0),lr(function(e){var u=e[t];return e=zr(e,0,t),u&&s(e,u),r(n,this,e)})},On.tail=function(n){var t=null==n?0:n.length;return t?vr(n,1,t):[]},On.take=function(n,t,r){return n&&n.length?(t=r||t===F?1:Ou(t),vr(n,0,0>t?0:t)):[]},On.takeRight=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===F?1:Ou(t),t=e-t,vr(n,0>t?0:t,e)):[]},On.takeRightWhile=function(n,t){
return n&&n.length?Ar(n,je(t,3),false,true):[]},On.takeWhile=function(n,t){return n&&n.length?Ar(n,je(t,3)):[]},On.tap=function(n,t){return t(n),n},On.throttle=function(n,t,r){var e=true,u=true;if(typeof n!="function")throw new ei("Expected a function");return bu(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),au(n,t,{leading:e,maxWait:t,trailing:u})},On.thru=nu,On.toArray=ku,On.toPairs=Bf,On.toPairsIn=Lf,On.toPath=function(n){return af(n)?l(n,$e):Au(n)?[n]:Mr(mo(zu(n)))},On.toPlainObject=Ru,
On.transform=function(n,t,r){var e=af(n),i=e||sf(n)||gf(n);if(t=je(t,4),null==r){var o=n&&n.constructor;r=i?e?new o:[]:bu(n)&&gu(o)?io(bi(n)):{}}return(i?u:Et)(n,function(n,e,u){return t(r,n,e,u)}),r},On.unary=function(n){return iu(n,1)},On.union=Wo,On.unionBy=Bo,On.unionWith=Lo,On.uniq=function(n){return n&&n.length?wr(n):[]},On.uniqBy=function(n,t){return n&&n.length?wr(n,je(t,2)):[]},On.uniqWith=function(n,t){return t=typeof t=="function"?t:F,n&&n.length?wr(n,F,t):[]},On.unset=function(n,t){return null==n||mr(n,t);
},On.unzip=Ye,On.unzipWith=Qe,On.update=function(n,t,r){return null==n?n:pr(n,t,Ir(r)(It(n,t)),void 0)},On.updateWith=function(n,t,r,e){return e=typeof e=="function"?e:F,null!=n&&(n=pr(n,t,Ir(r)(It(n,t)),e)),n},On.values=Du,On.valuesIn=function(n){return null==n?[]:I(n,Uu(n))},On.without=Uo,On.words=$u,On.wrap=function(n,t){return rf(Ir(t),n)},On.xor=Co,On.xorBy=Do,On.xorWith=Mo,On.zip=To,On.zipObject=function(n,t){return Or(n||[],t||[],at)},On.zipObjectDeep=function(n,t){return Or(n||[],t||[],pr);
},On.zipWith=$o,On.entries=Bf,On.entriesIn=Lf,On.extend=xf,On.extendWith=jf,Zu(On,On),On.add=nc,On.attempt=Pf,On.camelCase=Uf,On.capitalize=Mu,On.ceil=tc,On.clamp=function(n,t,r){return r===F&&(r=t,t=F),r!==F&&(r=Iu(r),r=r===r?r:0),t!==F&&(t=Iu(t),t=t===t?t:0),gt(Iu(n),t,r)},On.clone=function(n){return dt(n,4)},On.cloneDeep=function(n){return dt(n,5)},On.cloneDeepWith=function(n,t){return t=typeof t=="function"?t:F,dt(n,5,t)},On.cloneWith=function(n,t){return t=typeof t=="function"?t:F,dt(n,4,t)},
On.conformsTo=function(n,t){return null==t||bt(n,t,Lu(t))},On.deburr=Tu,On.defaultTo=function(n,t){return null==n||n!==n?t:n},On.divide=rc,On.endsWith=function(n,t,r){n=zu(n),t=jr(t);var e=n.length,e=r=r===F?e:gt(Ou(r),0,e);return r-=t.length,0<=r&&n.slice(r,e)==t},On.eq=hu,On.escape=function(n){return(n=zu(n))&&Y.test(n)?n.replace(H,et):n},On.escapeRegExp=function(n){return(n=zu(n))&&fn.test(n)?n.replace(on,"\\$&"):n},On.every=function(n,t,r){var e=af(n)?o:wt;return r&&ze(n,t,r)&&(t=F),e(n,je(t,3));
},On.find=Po,On.findIndex=Ze,On.findKey=function(n,t){return v(n,je(t,3),Et)},On.findLast=Zo,On.findLastIndex=qe,On.findLastKey=function(n,t){return v(n,je(t,3),Ot)},On.floor=ec,On.forEach=ru,On.forEachRight=eu,On.forIn=function(n,t){return null==n?n:co(n,je(t,3),Uu)},On.forInRight=function(n,t){return null==n?n:ao(n,je(t,3),Uu)},On.forOwn=function(n,t){return n&&Et(n,je(t,3))},On.forOwnRight=function(n,t){return n&&Ot(n,je(t,3))},On.get=Wu,On.gt=of,On.gte=ff,On.has=function(n,t){return null!=n&&ke(n,t,Bt);
},On.hasIn=Bu,On.head=Ke,On.identity=Nu,On.includes=function(n,t,r,e){return n=pu(n)?n:Du(n),r=r&&!e?Ou(r):0,e=n.length,0>r&&(r=Di(e+r,0)),mu(n)?r<=e&&-1<n.indexOf(t,r):!!e&&-1<d(n,t,r)},On.indexOf=function(n,t,r){var e=null==n?0:n.length;return e?(r=null==r?0:Ou(r),0>r&&(r=Di(e+r,0)),d(n,t,r)):-1},On.inRange=function(n,t,r){return t=Eu(t),r===F?(r=t,t=0):r=Eu(r),n=Iu(n),n>=Mi(t,r)&&n<Di(t,r)},On.invoke=Sf,On.isArguments=cf,On.isArray=af,On.isArrayBuffer=lf,On.isArrayLike=pu,On.isArrayLikeObject=_u,
On.isBoolean=function(n){return true===n||false===n||xu(n)&&"[object Boolean]"==zt(n)},On.isBuffer=sf,On.isDate=hf,On.isElement=function(n){return xu(n)&&1===n.nodeType&&!wu(n)},On.isEmpty=function(n){if(null==n)return true;if(pu(n)&&(af(n)||typeof n=="string"||typeof n.splice=="function"||sf(n)||gf(n)||cf(n)))return!n.length;var t=yo(n);if("[object Map]"==t||"[object Set]"==t)return!n.size;if(Le(n))return!Ht(n).length;for(var r in n)if(ci.call(n,r))return false;return true},On.isEqual=function(n,t){return Ft(n,t);
},On.isEqualWith=function(n,t,r){var e=(r=typeof r=="function"?r:F)?r(n,t):F;return e===F?Ft(n,t,F,r):!!e},On.isError=vu,On.isFinite=function(n){return typeof n=="number"&&Li(n)},On.isFunction=gu,On.isInteger=du,On.isLength=yu,On.isMap=pf,On.isMatch=function(n,t){return n===t||Pt(n,t,me(t))},On.isMatchWith=function(n,t,r){return r=typeof r=="function"?r:F,Pt(n,t,me(t),r)},On.isNaN=function(n){return ju(n)&&n!=+n},On.isNative=function(n){if(bo(n))throw new Yu("Unsupported core-js use. Try https://npms.io/search?q=ponyfill.");
return Zt(n)},On.isNil=function(n){return null==n},On.isNull=function(n){return null===n},On.isNumber=ju,On.isObject=bu,On.isObjectLike=xu,On.isPlainObject=wu,On.isRegExp=_f,On.isSafeInteger=function(n){return du(n)&&-9007199254740991<=n&&9007199254740991>=n},On.isSet=vf,On.isString=mu,On.isSymbol=Au,On.isTypedArray=gf,On.isUndefined=function(n){return n===F},On.isWeakMap=function(n){return xu(n)&&"[object WeakMap]"==yo(n)},On.isWeakSet=function(n){return xu(n)&&"[object WeakSet]"==zt(n)},On.join=function(n,t){
return null==n?"":Ui.call(n,t)},On.kebabCase=Cf,On.last=Ge,On.lastIndexOf=function(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e;if(r!==F&&(u=Ou(r),u=0>u?Di(e+u,0):Mi(u,e-1)),t===t){for(r=u+1;r--&&n[r]!==t;);n=r}else n=g(n,b,u,true);return n},On.lowerCase=Df,On.lowerFirst=Mf,On.lt=df,On.lte=yf,On.max=function(n){return n&&n.length?mt(n,Nu,Wt):F},On.maxBy=function(n,t){return n&&n.length?mt(n,je(t,2),Wt):F},On.mean=function(n){return x(n,Nu)},On.meanBy=function(n,t){return x(n,je(t,2))},On.min=function(n){
return n&&n.length?mt(n,Nu,Jt):F},On.minBy=function(n,t){return n&&n.length?mt(n,je(t,2),Jt):F},On.stubArray=Ku,On.stubFalse=Gu,On.stubObject=function(){return{}},On.stubString=function(){return""},On.stubTrue=function(){return true},On.multiply=uc,On.nth=function(n,t){return n&&n.length?tr(n,Ou(t)):F},On.noConflict=function(){return Zn._===this&&(Zn._=pi),this},On.noop=qu,On.now=Jo,On.pad=function(n,t,r){n=zu(n);var e=(t=Ou(t))?T(n):0;return!t||e>=t?n:(t=(t-e)/2,ee(zi(t),r)+n+ee(Ri(t),r))},On.padEnd=function(n,t,r){
n=zu(n);var e=(t=Ou(t))?T(n):0;return t&&e<t?n+ee(t-e,r):n},On.padStart=function(n,t,r){n=zu(n);var e=(t=Ou(t))?T(n):0;return t&&e<t?ee(t-e,r)+n:n},On.parseInt=function(n,t,r){return r||null==t?t=0:t&&(t=+t),$i(zu(n).replace(an,""),t||0)},On.random=function(n,t,r){if(r&&typeof r!="boolean"&&ze(n,t,r)&&(t=r=F),r===F&&(typeof t=="boolean"?(r=t,t=F):typeof n=="boolean"&&(r=n,n=F)),n===F&&t===F?(n=0,t=1):(n=Eu(n),t===F?(t=n,n=0):t=Eu(t)),n>t){var e=n;n=t,t=e}return r||n%1||t%1?(r=Fi(),Mi(n+r*(t-n+$n("1e-"+((r+"").length-1))),t)):cr(n,t);
},On.reduce=function(n,t,r){var e=af(n)?h:m,u=3>arguments.length;return e(n,je(t,4),r,u,oo)},On.reduceRight=function(n,t,r){var e=af(n)?p:m,u=3>arguments.length;return e(n,je(t,4),r,u,fo)},On.repeat=function(n,t,r){return t=(r?ze(n,t,r):t===F)?1:Ou(t),ar(zu(n),t)},On.replace=function(){var n=arguments,t=zu(n[0]);return 3>n.length?t:t.replace(n[1],n[2])},On.result=function(n,t,r){t=Rr(t,n);var e=-1,u=t.length;for(u||(u=1,n=F);++e<u;){var i=null==n?F:n[$e(t[e])];i===F&&(e=u,i=r),n=gu(i)?i.call(n):i;
}return n},On.round=ic,On.runInContext=w,On.sample=function(n){return(af(n)?tt:sr)(n)},On.size=function(n){if(null==n)return 0;if(pu(n))return mu(n)?T(n):n.length;var t=yo(n);return"[object Map]"==t||"[object Set]"==t?n.size:Ht(n).length},On.snakeCase=Tf,On.some=function(n,t,r){var e=af(n)?_:gr;return r&&ze(n,t,r)&&(t=F),e(n,je(t,3))},On.sortedIndex=function(n,t){return dr(n,t)},On.sortedIndexBy=function(n,t,r){return yr(n,t,je(r,2))},On.sortedIndexOf=function(n,t){var r=null==n?0:n.length;if(r){
var e=dr(n,t);if(e<r&&hu(n[e],t))return e}return-1},On.sortedLastIndex=function(n,t){return dr(n,t,true)},On.sortedLastIndexBy=function(n,t,r){return yr(n,t,je(r,2),true)},On.sortedLastIndexOf=function(n,t){if(null==n?0:n.length){var r=dr(n,t,true)-1;if(hu(n[r],t))return r}return-1},On.startCase=$f,On.startsWith=function(n,t,r){return n=zu(n),r=null==r?0:gt(Ou(r),0,n.length),t=jr(t),n.slice(r,r+t.length)==t},On.subtract=oc,On.sum=function(n){return n&&n.length?k(n,Nu):0},On.sumBy=function(n,t){return n&&n.length?k(n,je(t,2)):0;
},On.template=function(n,t,r){var e=On.templateSettings;r&&ze(n,t,r)&&(t=F),n=zu(n),t=jf({},t,e,se),r=jf({},t.imports,e.imports,se);var u,i,o=Lu(r),f=I(r,o),c=0;r=t.interpolate||An;var a="__p+='";r=ti((t.escape||An).source+"|"+r.source+"|"+(r===nn?gn:An).source+"|"+(t.evaluate||An).source+"|$","g");var l="sourceURL"in t?"//# sourceURL="+t.sourceURL+"\n":"";if(n.replace(r,function(t,r,e,o,f,l){return e||(e=o),a+=n.slice(c,l).replace(kn,B),r&&(u=true,a+="'+__e("+r+")+'"),f&&(i=true,a+="';"+f+";\n__p+='"),
e&&(a+="'+((__t=("+e+"))==null?'':__t)+'"),c=l+t.length,t}),a+="';",(t=t.variable)||(a="with(obj){"+a+"}"),a=(i?a.replace(q,""):a).replace(V,"$1").replace(K,"$1;"),a="function("+(t||"obj")+"){"+(t?"":"obj||(obj={});")+"var __t,__p=''"+(u?",__e=_.escape":"")+(i?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+a+"return __p}",t=Pf(function(){return Qu(o,l+"return "+a).apply(F,f)}),t.source=a,vu(t))throw t;return t},On.times=function(n,t){if(n=Ou(n),1>n||9007199254740991<n)return[];
var r=4294967295,e=Mi(n,4294967295);for(t=je(t),n-=4294967295,e=E(e,t);++r<n;)t(r);return e},On.toFinite=Eu,On.toInteger=Ou,On.toLength=Su,On.toLower=function(n){return zu(n).toLowerCase()},On.toNumber=Iu,On.toSafeInteger=function(n){return n?gt(Ou(n),-9007199254740991,9007199254740991):0===n?n:0},On.toString=zu,On.toUpper=function(n){return zu(n).toUpperCase()},On.trim=function(n,t,r){return(n=zu(n))&&(r||t===F)?n.replace(cn,""):n&&(t=jr(t))?(n=$(n),r=$(t),t=z(n,r),r=W(n,r)+1,zr(n,t,r).join("")):n;
},On.trimEnd=function(n,t,r){return(n=zu(n))&&(r||t===F)?n.replace(ln,""):n&&(t=jr(t))?(n=$(n),t=W(n,$(t))+1,zr(n,0,t).join("")):n},On.trimStart=function(n,t,r){return(n=zu(n))&&(r||t===F)?n.replace(an,""):n&&(t=jr(t))?(n=$(n),t=z(n,$(t)),zr(n,t).join("")):n},On.truncate=function(n,t){var r=30,e="...";if(bu(t))var u="separator"in t?t.separator:u,r="length"in t?Ou(t.length):r,e="omission"in t?jr(t.omission):e;n=zu(n);var i=n.length;if(Bn.test(n))var o=$(n),i=o.length;if(r>=i)return n;if(i=r-T(e),1>i)return e;
if(r=o?zr(o,0,i).join(""):n.slice(0,i),u===F)return r+e;if(o&&(i+=r.length-i),_f(u)){if(n.slice(i).search(u)){var f=r;for(u.global||(u=ti(u.source,zu(dn.exec(u))+"g")),u.lastIndex=0;o=u.exec(f);)var c=o.index;r=r.slice(0,c===F?i:c)}}else n.indexOf(jr(u),i)!=i&&(u=r.lastIndexOf(u),-1<u&&(r=r.slice(0,u)));return r+e},On.unescape=function(n){return(n=zu(n))&&J.test(n)?n.replace(G,ut):n},On.uniqueId=function(n){var t=++ai;return zu(n)+t},On.upperCase=Ff,On.upperFirst=Nf,On.each=ru,On.eachRight=eu,On.first=Ke,
Zu(On,function(){var n={};return Et(On,function(t,r){ci.call(On.prototype,r)||(n[r]=t)}),n}(),{chain:false}),On.VERSION="4.17.4",u("bind bindKey curry curryRight partial partialRight".split(" "),function(n){On[n].placeholder=On}),u(["drop","take"],function(n,t){Mn.prototype[n]=function(r){r=r===F?1:Di(Ou(r),0);var e=this.__filtered__&&!t?new Mn(this):this.clone();return e.__filtered__?e.__takeCount__=Mi(r,e.__takeCount__):e.__views__.push({size:Mi(r,4294967295),type:n+(0>e.__dir__?"Right":"")}),e},Mn.prototype[n+"Right"]=function(t){
return this.reverse()[n](t).reverse()}}),u(["filter","map","takeWhile"],function(n,t){var r=t+1,e=1==r||3==r;Mn.prototype[n]=function(n){var t=this.clone();return t.__iteratees__.push({iteratee:je(n,3),type:r}),t.__filtered__=t.__filtered__||e,t}}),u(["head","last"],function(n,t){var r="take"+(t?"Right":"");Mn.prototype[n]=function(){return this[r](1).value()[0]}}),u(["initial","tail"],function(n,t){var r="drop"+(t?"":"Right");Mn.prototype[n]=function(){return this.__filtered__?new Mn(this):this[r](1);
}}),Mn.prototype.compact=function(){return this.filter(Nu)},Mn.prototype.find=function(n){return this.filter(n).head()},Mn.prototype.findLast=function(n){return this.reverse().find(n)},Mn.prototype.invokeMap=lr(function(n,t){return typeof n=="function"?new Mn(this):this.map(function(r){return Dt(r,n,t)})}),Mn.prototype.reject=function(n){return this.filter(su(je(n)))},Mn.prototype.slice=function(n,t){n=Ou(n);var r=this;return r.__filtered__&&(0<n||0>t)?new Mn(r):(0>n?r=r.takeRight(-n):n&&(r=r.drop(n)),
t!==F&&(t=Ou(t),r=0>t?r.dropRight(-t):r.take(t-n)),r)},Mn.prototype.takeRightWhile=function(n){return this.reverse().takeWhile(n).reverse()},Mn.prototype.toArray=function(){return this.take(4294967295)},Et(Mn.prototype,function(n,t){var r=/^(?:filter|find|map|reject)|While$/.test(t),e=/^(?:head|last)$/.test(t),u=On[e?"take"+("last"==t?"Right":""):t],i=e||/^find/.test(t);u&&(On.prototype[t]=function(){function t(n){return n=u.apply(On,s([n],f)),e&&h?n[0]:n}var o=this.__wrapped__,f=e?[1]:arguments,c=o instanceof Mn,a=f[0],l=c||af(o);
l&&r&&typeof a=="function"&&1!=a.length&&(c=l=false);var h=this.__chain__,p=!!this.__actions__.length,a=i&&!h,c=c&&!p;return!i&&l?(o=c?o:new Mn(this),o=n.apply(o,f),o.__actions__.push({func:nu,args:[t],thisArg:F}),new zn(o,h)):a&&c?n.apply(this,f):(o=this.thru(t),a?e?o.value()[0]:o.value():o)})}),u("pop push shift sort splice unshift".split(" "),function(n){var t=ui[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:pop|shift)$/.test(n);On.prototype[n]=function(){var n=arguments;if(e&&!this.__chain__){
var u=this.value();return t.apply(af(u)?u:[],n)}return this[r](function(r){return t.apply(af(r)?r:[],n)})}}),Et(Mn.prototype,function(n,t){var r=On[t];if(r){var e=r.name+"";(Ji[e]||(Ji[e]=[])).push({name:t,func:r})}}),Ji[Xr(F,2).name]=[{name:"wrapper",func:F}],Mn.prototype.clone=function(){var n=new Mn(this.__wrapped__);return n.__actions__=Mr(this.__actions__),n.__dir__=this.__dir__,n.__filtered__=this.__filtered__,n.__iteratees__=Mr(this.__iteratees__),n.__takeCount__=this.__takeCount__,n.__views__=Mr(this.__views__),
n},Mn.prototype.reverse=function(){if(this.__filtered__){var n=new Mn(this);n.__dir__=-1,n.__filtered__=true}else n=this.clone(),n.__dir__*=-1;return n},Mn.prototype.value=function(){var n,t=this.__wrapped__.value(),r=this.__dir__,e=af(t),u=0>r,i=e?t.length:0;n=i;for(var o=this.__views__,f=0,c=-1,a=o.length;++c<a;){var l=o[c],s=l.size;switch(l.type){case"drop":f+=s;break;case"dropRight":n-=s;break;case"take":n=Mi(n,f+s);break;case"takeRight":f=Di(f,n-s)}}if(n={start:f,end:n},o=n.start,f=n.end,n=f-o,
o=u?f:o-1,f=this.__iteratees__,c=f.length,a=0,l=Mi(n,this.__takeCount__),!e||!u&&i==n&&l==n)return kr(t,this.__actions__);e=[];n:for(;n--&&a<l;){for(o+=r,u=-1,i=t[o];++u<c;){var h=f[u],s=h.type,h=(0,h.iteratee)(i);if(2==s)i=h;else if(!h){if(1==s)continue n;break n}}e[a++]=i}return e},On.prototype.at=Fo,On.prototype.chain=function(){return Xe(this)},On.prototype.commit=function(){return new zn(this.value(),this.__chain__)},On.prototype.next=function(){this.__values__===F&&(this.__values__=ku(this.value()));
var n=this.__index__>=this.__values__.length;return{done:n,value:n?F:this.__values__[this.__index__++]}},On.prototype.plant=function(n){for(var t,r=this;r instanceof Sn;){var e=Pe(r);e.__index__=0,e.__values__=F,t?u.__wrapped__=e:t=e;var u=e,r=r.__wrapped__}return u.__wrapped__=n,t},On.prototype.reverse=function(){var n=this.__wrapped__;return n instanceof Mn?(this.__actions__.length&&(n=new Mn(this)),n=n.reverse(),n.__actions__.push({func:nu,args:[Je],thisArg:F}),new zn(n,this.__chain__)):this.thru(Je);
},On.prototype.toJSON=On.prototype.valueOf=On.prototype.value=function(){return kr(this.__wrapped__,this.__actions__)},On.prototype.first=On.prototype.head,Ai&&(On.prototype[Ai]=tu),On}();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(Zn._=it, define(function(){return it})):Vn?((Vn.exports=it)._=it,qn._=it):Zn._=it}).call(this);(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.d3 = global.d3 || {})));
}(this, (function (exports) { 'use strict';
var version = "4.10.0";
var ascending = function(a, b) {
return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
};
var bisector = function(compare) {
if (compare.length === 1) compare = ascendingComparator(compare);
return {
left: function(a, x, lo, hi) {
if (lo == null) lo = 0;
if (hi == null) 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 (lo == null) lo = 0;
if (hi == null) 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;
}
};
};
function ascendingComparator(f) {
return function(d, x) {
return ascending(f(d), x);
};
}
var ascendingBisect = bisector(ascending);
var bisectRight = ascendingBisect.right;
var bisectLeft = ascendingBisect.left;
var pairs = function(array, f) {
if (f == null) f = pair;
var i = 0, n = array.length - 1, p = array[0], pairs = new Array(n < 0 ? 0 : n);
while (i < n) pairs[i] = f(p, p = array[++i]);
return pairs;
};
function pair(a, b) {
return [a, b];
}
var cross = function(values0, values1, reduce) {
var n0 = values0.length,
n1 = values1.length,
values = new Array(n0 * n1),
i0,
i1,
i,
value0;
if (reduce == null) reduce = pair;
for (i0 = i = 0; i0 < n0; ++i0) {
for (value0 = values0[i0], i1 = 0; i1 < n1; ++i1, ++i) {
values[i] = reduce(value0, values1[i1]);
}
}
return values;
};
var descending = function(a, b) {
return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
};
var number = function(x) {
return x === null ? NaN : +x;
};
var variance = function(values, valueof) {
var n = values.length,
m = 0,
i = -1,
mean = 0,
value,
delta,
sum = 0;
if (valueof == null) {
while (++i < n) {
if (!isNaN(value = number(values[i]))) {
delta = value - mean;
mean += delta / ++m;
sum += delta * (value - mean);
}
}
}
else {
while (++i < n) {
if (!isNaN(value = number(valueof(values[i], i, values)))) {
delta = value - mean;
mean += delta / ++m;
sum += delta * (value - mean);
}
}
}
if (m > 1) return sum / (m - 1);
};
var deviation = function(array, f) {
var v = variance(array, f);
return v ? Math.sqrt(v) : v;
};
var extent = function(values, valueof) {
var n = values.length,
i = -1,
value,
min,
max;
if (valueof == null) {
while (++i < n) { // Find the first comparable value.
if ((value = values[i]) != null && value >= value) {
min = max = value;
while (++i < n) { // Compare the remaining values.
if ((value = values[i]) != null) {
if (min > value) min = value;
if (max < value) max = value;
}
}
}
}
}
else {
while (++i < n) { // Find the first comparable value.
if ((value = valueof(values[i], i, values)) != null && value >= value) {
min = max = value;
while (++i < n) { // Compare the remaining values.
if ((value = valueof(values[i], i, values)) != null) {
if (min > value) min = value;
if (max < value) max = value;
}
}
}
}
}
return [min, max];
};
var array = Array.prototype;
var slice = array.slice;
var map = array.map;
var constant = function(x) {
return function() {
return x;
};
};
var identity = function(x) {
return x;
};
var sequence = function(start, stop, step) {
start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step;
var i = -1,
n = Math.max(0, Math.ceil((stop - start) / step)) | 0,
range = new Array(n);
while (++i < n) {
range[i] = start + i * step;
}
return range;
};
var e10 = Math.sqrt(50);
var e5 = Math.sqrt(10);
var e2 = Math.sqrt(2);
var ticks = function(start, stop, count) {
var reverse = stop < start,
i = -1,
n,
ticks,
step;
if (reverse) n = start, start = stop, stop = n;
if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) return [];
if (step > 0) {
start = Math.ceil(start / step);
stop = Math.floor(stop / step);
ticks = new Array(n = Math.ceil(stop - start + 1));
while (++i < n) ticks[i] = (start + i) * step;
} else {
start = Math.floor(start * step);
stop = Math.ceil(stop * step);
ticks = new Array(n = Math.ceil(start - stop + 1));
while (++i < n) ticks[i] = (start - i) / step;
}
if (reverse) ticks.reverse();
return ticks;
};
function tickIncrement(start, stop, count) {
var step = (stop - start) / Math.max(0, count),
power = Math.floor(Math.log(step) / Math.LN10),
error = step / Math.pow(10, power);
return power >= 0
? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power)
: -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1);
}
function tickStep(start, stop, count) {
var step0 = Math.abs(stop - start) / Math.max(0, count),
step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)),
error = step0 / step1;
if (error >= e10) step1 *= 10;
else if (error >= e5) step1 *= 5;
else if (error >= e2) step1 *= 2;
return stop < start ? -step1 : step1;
}
var sturges = function(values) {
return Math.ceil(Math.log(values.length) / Math.LN2) + 1;
};
var histogram = function() {
var value = identity,
domain = extent,
threshold = sturges;
function histogram(data) {
var i,
n = data.length,
x,
values = new Array(n);
for (i = 0; i < n; ++i) {
values[i] = value(data[i], i, data);
}
var xz = domain(values),
x0 = xz[0],
x1 = xz[1],
tz = threshold(values, x0, x1);
// Convert number of thresholds into uniform thresholds.
if (!Array.isArray(tz)) {
tz = tickStep(x0, x1, tz);
tz = sequence(Math.ceil(x0 / tz) * tz, Math.floor(x1 / tz) * tz, tz); // exclusive
}
// Remove any thresholds outside the domain.
var m = tz.length;
while (tz[0] <= x0) tz.shift(), --m;
while (tz[m - 1] > x1) tz.pop(), --m;
var bins = new Array(m + 1),
bin;
// Initialize bins.
for (i = 0; i <= m; ++i) {
bin = bins[i] = [];
bin.x0 = i > 0 ? tz[i - 1] : x0;
bin.x1 = i < m ? tz[i] : x1;
}
// Assign data to bins by value, ignoring any outside the domain.
for (i = 0; i < n; ++i) {
x = values[i];
if (x0 <= x && x <= x1) {
bins[bisectRight(tz, x, 0, m)].push(data[i]);
}
}
return bins;
}
histogram.value = function(_) {
return arguments.length ? (value = typeof _ === "function" ? _ : constant(_), histogram) : value;
};
histogram.domain = function(_) {
return arguments.length ? (domain = typeof _ === "function" ? _ : constant([_[0], _[1]]), histogram) : domain;
};
histogram.thresholds = function(_) {
return arguments.length ? (threshold = typeof _ === "function" ? _ : Array.isArray(_) ? constant(slice.call(_)) : constant(_), histogram) : threshold;
};
return histogram;
};
var threshold = function(values, p, valueof) {
if (valueof == null) valueof = number;
if (!(n = values.length)) return;
if ((p = +p) <= 0 || n < 2) return +valueof(values[0], 0, values);
if (p >= 1) return +valueof(values[n - 1], n - 1, values);
var n,
i = (n - 1) * p,
i0 = Math.floor(i),
value0 = +valueof(values[i0], i0, values),
value1 = +valueof(values[i0 + 1], i0 + 1, values);
return value0 + (value1 - value0) * (i - i0);
};
var freedmanDiaconis = function(values, min, max) {
values = map.call(values, number).sort(ascending);
return Math.ceil((max - min) / (2 * (threshold(values, 0.75) - threshold(values, 0.25)) * Math.pow(values.length, -1 / 3)));
};
var scott = function(values, min, max) {
return Math.ceil((max - min) / (3.5 * deviation(values) * Math.pow(values.length, -1 / 3)));
};
var max = function(values, valueof) {
var n = values.length,
i = -1,
value,
max;
if (valueof == null) {
while (++i < n) { // Find the first comparable value.
if ((value = values[i]) != null && value >= value) {
max = value;
while (++i < n) { // Compare the remaining values.
if ((value = values[i]) != null && value > max) {
max = value;
}
}
}
}
}
else {
while (++i < n) { // Find the first comparable value.
if ((value = valueof(values[i], i, values)) != null && value >= value) {
max = value;
while (++i < n) { // Compare the remaining values.
if ((value = valueof(values[i], i, values)) != null && value > max) {
max = value;
}
}
}
}
}
return max;
};
var mean = function(values, valueof) {
var n = values.length,
m = n,
i = -1,
value,
sum = 0;
if (valueof == null) {
while (++i < n) {
if (!isNaN(value = number(values[i]))) sum += value;
else --m;
}
}
else {
while (++i < n) {
if (!isNaN(value = number(valueof(values[i], i, values)))) sum += value;
else --m;
}
}
if (m) return sum / m;
};
var median = function(values, valueof) {
var n = values.length,
i = -1,
value,
numbers = [];
if (valueof == null) {
while (++i < n) {
if (!isNaN(value = number(values[i]))) {
numbers.push(value);
}
}
}
else {
while (++i < n) {
if (!isNaN(value = number(valueof(values[i], i, values)))) {
numbers.push(value);
}
}
}
return threshold(numbers.sort(ascending), 0.5);
};
var 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 min = function(values, valueof) {
var n = values.length,
i = -1,
value,
min;
if (valueof == null) {
while (++i < n) { // Find the first comparable value.
if ((value = values[i]) != null && value >= value) {
min = value;
while (++i < n) { // Compare the remaining values.
if ((value = values[i]) != null && min > value) {
min = value;
}
}
}
}
}
else {
while (++i < n) { // Find the first comparable value.
if ((value = valueof(values[i], i, values)) != null && value >= value) {
min = value;
while (++i < n) { // Compare the remaining values.
if ((value = valueof(values[i], i, values)) != null && min > value) {
min = value;
}
}
}
}
}
return min;
};
var permute = function(array, indexes) {
var i = indexes.length, permutes = new Array(i);
while (i--) permutes[i] = array[indexes[i]];
return permutes;
};
var scan = function(values, compare) {
if (!(n = values.length)) return;
var n,
i = 0,
j = 0,
xi,
xj = values[j];
if (compare == null) compare = ascending;
while (++i < n) {
if (compare(xi = values[i], xj) < 0 || compare(xj, xj) !== 0) {
xj = xi, j = i;
}
}
if (compare(xj, xj) === 0) return j;
};
var shuffle = function(array, i0, i1) {
var m = (i1 == null ? array.length : i1) - (i0 = i0 == null ? 0 : +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;
};
var sum = function(values, valueof) {
var n = values.length,
i = -1,
value,
sum = 0;
if (valueof == null) {
while (++i < n) {
if (value = +values[i]) sum += value; // Note: zero and null are equivalent.
}
}
else {
while (++i < n) {
if (value = +valueof(values[i], i, values)) sum += value;
}
}
return sum;
};
var transpose = function(matrix) {
if (!(n = matrix.length)) return [];
for (var i = -1, m = min(matrix, length), transpose = new Array(m); ++i < m;) {
for (var j = -1, n, row = transpose[i] = new Array(n); ++j < n;) {
row[j] = matrix[j][i];
}
}
return transpose;
};
function length(d) {
return d.length;
}
var zip = function() {
return transpose(arguments);
};
var slice$1 = Array.prototype.slice;
var identity$1 = function(x) {
return x;
};
var top = 1;
var right = 2;
var bottom = 3;
var left = 4;
var epsilon = 1e-6;
function translateX(x) {
return "translate(" + (x + 0.5) + ",0)";
}
function translateY(y) {
return "translate(0," + (y + 0.5) + ")";
}
function number$1(scale) {
return function(d) {
return +scale(d);
};
}
function center(scale) {
var offset = Math.max(0, scale.bandwidth() - 1) / 2; // Adjust for 0.5px offset.
if (scale.round()) offset = Math.round(offset);
return function(d) {
return +scale(d) + offset;
};
}
function entering() {
return !this.__axis;
}
function axis(orient, scale) {
var tickArguments = [],
tickValues = null,
tickFormat = null,
tickSizeInner = 6,
tickSizeOuter = 6,
tickPadding = 3,
k = orient === top || orient === left ? -1 : 1,
x = orient === left || orient === right ? "x" : "y",
transform = orient === top || orient === bottom ? translateX : translateY;
function axis(context) {
var values = tickValues == null ? (scale.ticks ? scale.ticks.apply(scale, tickArguments) : scale.domain()) : tickValues,
format = tickFormat == null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : identity$1) : tickFormat,
spacing = Math.max(tickSizeInner, 0) + tickPadding,
range = scale.range(),
range0 = +range[0] + 0.5,
range1 = +range[range.length - 1] + 0.5,
position = (scale.bandwidth ? center : number$1)(scale.copy()),
selection = context.selection ? context.selection() : context,
path = selection.selectAll(".domain").data([null]),
tick = selection.selectAll(".tick").data(values, scale).order(),
tickExit = tick.exit(),
tickEnter = tick.enter().append("g").attr("class", "tick"),
line = tick.select("line"),
text = tick.select("text");
path = path.merge(path.enter().insert("path", ".tick")
.attr("class", "domain")
.attr("stroke", "#000"));
tick = tick.merge(tickEnter);
line = line.merge(tickEnter.append("line")
.attr("stroke", "#000")
.attr(x + "2", k * tickSizeInner));
text = text.merge(tickEnter.append("text")
.attr("fill", "#000")
.attr(x, k * spacing)
.attr("dy", orient === top ? "0em" : orient === bottom ? "0.71em" : "0.32em"));
if (context !== selection) {
path = path.transition(context);
tick = tick.transition(context);
line = line.transition(context);
text = text.transition(context);
tickExit = tickExit.transition(context)
.attr("opacity", epsilon)
.attr("transform", function(d) { return isFinite(d = position(d)) ? transform(d) : this.getAttribute("transform"); });
tickEnter
.attr("opacity", epsilon)
.attr("transform", function(d) { var p = this.parentNode.__axis; return transform(p && isFinite(p = p(d)) ? p : position(d)); });
}
tickExit.remove();
path
.attr("d", orient === left || orient == right
? "M" + k * tickSizeOuter + "," + range0 + "H0.5V" + range1 + "H" + k * tickSizeOuter
: "M" + range0 + "," + k * tickSizeOuter + "V0.5H" + range1 + "V" + k * tickSizeOuter);
tick
.attr("opacity", 1)
.attr("transform", function(d) { return transform(position(d)); });
line
.attr(x + "2", k * tickSizeInner);
text
.attr(x, k * spacing)
.text(format);
selection.filter(entering)
.attr("fill", "none")
.attr("font-size", 10)
.attr("font-family", "sans-serif")
.attr("text-anchor", orient === right ? "start" : orient === left ? "end" : "middle");
selection
.each(function() { this.__axis = position; });
}
axis.scale = function(_) {
return arguments.length ? (scale = _, axis) : scale;
};
axis.ticks = function() {
return tickArguments = slice$1.call(arguments), axis;
};
axis.tickArguments = function(_) {
return arguments.length ? (tickArguments = _ == null ? [] : slice$1.call(_), axis) : tickArguments.slice();
};
axis.tickValues = function(_) {
return arguments.length ? (tickValues = _ == null ? null : slice$1.call(_), axis) : tickValues && tickValues.slice();
};
axis.tickFormat = function(_) {
return arguments.length ? (tickFormat = _, axis) : tickFormat;
};
axis.tickSize = function(_) {
return arguments.length ? (tickSizeInner = tickSizeOuter = +_, axis) : tickSizeInner;
};
axis.tickSizeInner = function(_) {
return arguments.length ? (tickSizeInner = +_, axis) : tickSizeInner;
};
axis.tickSizeOuter = function(_) {
return arguments.length ? (tickSizeOuter = +_, axis) : tickSizeOuter;
};
axis.tickPadding = function(_) {
return arguments.length ? (tickPadding = +_, axis) : tickPadding;
};
return axis;
}
function axisTop(scale) {
return axis(top, scale);
}
function axisRight(scale) {
return axis(right, scale);
}
function axisBottom(scale) {
return axis(bottom, scale);
}
function axisLeft(scale) {
return axis(left, scale);
}
var noop = {value: function() {}};
function dispatch() {
for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) {
if (!(t = arguments[i] + "") || (t in _)) throw new Error("illegal type: " + t);
_[t] = [];
}
return new Dispatch(_);
}
function Dispatch(_) {
this._ = _;
}
function parseTypenames(typenames, types) {
return typenames.trim().split(/^|\s+/).map(function(t) {
var name = "", i = t.indexOf(".");
if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t);
return {type: t, name: name};
});
}
Dispatch.prototype = dispatch.prototype = {
constructor: Dispatch,
on: function(typename, callback) {
var _ = this._,
T = parseTypenames(typename + "", _),
t,
i = -1,
n = T.length;
// If no callback was specified, return the callback of the given type and name.
if (arguments.length < 2) {
while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t;
return;
}
// If a type was specified, set the callback for the given type and name.
// Otherwise, if a null callback was specified, remove callbacks of the given name.
if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback);
while (++i < n) {
if (t = (typename = T[i]).type) _[t] = set(_[t], typename.name, callback);
else if (callback == null) for (t in _) _[t] = set(_[t], typename.name, null);
}
return this;
},
copy: function() {
var copy = {}, _ = this._;
for (var t in _) copy[t] = _[t].slice();
return new Dispatch(copy);
},
call: function(type, that) {
if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2];
if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
},
apply: function(type, that, args) {
if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
}
};
function get(type, name) {
for (var i = 0, n = type.length, c; i < n; ++i) {
if ((c = type[i]).name === name) {
return c.value;
}
}
}
function set(type, name, callback) {
for (var i = 0, n = type.length; i < n; ++i) {
if (type[i].name === name) {
type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1));
break;
}
}
if (callback != null) type.push({name: name, value: callback});
return type;
}
var xhtml = "http://www.w3.org/1999/xhtml";
var namespaces = {
svg: "http://www.w3.org/2000/svg",
xhtml: xhtml,
xlink: "http://www.w3.org/1999/xlink",
xml: "http://www.w3.org/XML/1998/namespace",
xmlns: "http://www.w3.org/2000/xmlns/"
};
var namespace = function(name) {
var prefix = name += "", i = prefix.indexOf(":");
if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1);
return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name;
};
function creatorInherit(name) {
return function() {
var document = this.ownerDocument,
uri = this.namespaceURI;
return uri === xhtml && document.documentElement.namespaceURI === xhtml
? document.createElement(name)
: document.createElementNS(uri, name);
};
}
function creatorFixed(fullname) {
return function() {
return this.ownerDocument.createElementNS(fullname.space, fullname.local);
};
}
var creator = function(name) {
var fullname = namespace(name);
return (fullname.local
? creatorFixed
: creatorInherit)(fullname);
};
var nextId = 0;
function local$1() {
return new Local;
}
function Local() {
this._ = "@" + (++nextId).toString(36);
}
Local.prototype = local$1.prototype = {
constructor: Local,
get: function(node) {
var id = this._;
while (!(id in node)) if (!(node = node.parentNode)) return;
return node[id];
},
set: function(node, value) {
return node[this._] = value;
},
remove: function(node) {
return this._ in node && delete node[this._];
},
toString: function() {
return this._;
}
};
var matcher = function(selector) {
return function() {
return this.matches(selector);
};
};
if (typeof document !== "undefined") {
var element = document.documentElement;
if (!element.matches) {
var vendorMatches = element.webkitMatchesSelector
|| element.msMatchesSelector
|| element.mozMatchesSelector
|| element.oMatchesSelector;
matcher = function(selector) {
return function() {
return vendorMatches.call(this, selector);
};
};
}
}
var matcher$1 = matcher;
var filterEvents = {};
exports.event = null;
if (typeof document !== "undefined") {
var element$1 = document.documentElement;
if (!("onmouseenter" in element$1)) {
filterEvents = {mouseenter: "mouseover", mouseleave: "mouseout"};
}
}
function filterContextListener(listener, index, group) {
listener = contextListener(listener, index, group);
return function(event) {
var related = event.relatedTarget;
if (!related || (related !== this && !(related.compareDocumentPosition(this) & 8))) {
listener.call(this, event);
}
};
}
function contextListener(listener, index, group) {
return function(event1) {
var event0 = exports.event; // Events can be reentrant (e.g., focus).
exports.event = event1;
try {
listener.call(this, this.__data__, index, group);
} finally {
exports.event = event0;
}
};
}
function parseTypenames$1(typenames) {
return typenames.trim().split(/^|\s+/).map(function(t) {
var name = "", i = t.indexOf(".");
if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
return {type: t, name: name};
});
}
function onRemove(typename) {
return function() {
var on = this.__on;
if (!on) return;
for (var j = 0, i = -1, m = on.length, o; j < m; ++j) {
if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) {
this.removeEventListener(o.type, o.listener, o.capture);
} else {
on[++i] = o;
}
}
if (++i) on.length = i;
else delete this.__on;
};
}
function onAdd(typename, value, capture) {
var wrap = filterEvents.hasOwnProperty(typename.type) ? filterContextListener : contextListener;
return function(d, i, group) {
var on = this.__on, o, listener = wrap(value, i, group);
if (on) for (var j = 0, m = on.length; j < m; ++j) {
if ((o = on[j]).type === typename.type && o.name === typename.name) {
this.removeEventListener(o.type, o.listener, o.capture);
this.addEventListener(o.type, o.listener = listener, o.capture = capture);
o.value = value;
return;
}
}
this.addEventListener(typename.type, listener, capture);
o = {type: typename.type, name: typename.name, value: value, listener: listener, capture: capture};
if (!on) this.__on = [o];
else on.push(o);
};
}
var selection_on = function(typename, value, capture) {
var typenames = parseTypenames$1(typename + ""), i, n = typenames.length, t;
if (arguments.length < 2) {
var on = this.node().__on;
if (on) for (var j = 0, m = on.length, o; j < m; ++j) {
for (i = 0, o = on[j]; i < n; ++i) {
if ((t = typenames[i]).type === o.type && t.name === o.name) {
return o.value;
}
}
}
return;
}
on = value ? onAdd : onRemove;
if (capture == null) capture = false;
for (i = 0; i < n; ++i) this.each(on(typenames[i], value, capture));
return this;
};
function customEvent(event1, listener, that, args) {
var event0 = exports.event;
event1.sourceEvent = exports.event;
exports.event = event1;
try {
return listener.apply(that, args);
} finally {
exports.event = event0;
}
}
var sourceEvent = function() {
var current = exports.event, source;
while (source = current.sourceEvent) current = source;
return current;
};
var point = function(node, event) {
var svg = node.ownerSVGElement || node;
if (svg.createSVGPoint) {
var point = svg.createSVGPoint();
point.x = event.clientX, point.y = event.clientY;
point = point.matrixTransform(node.getScreenCTM().inverse());
return [point.x, point.y];
}
var rect = node.getBoundingClientRect();
return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop];
};
var mouse = function(node) {
var event = sourceEvent();
if (event.changedTouches) event = event.changedTouches[0];
return point(node, event);
};
function none() {}
var selector = function(selector) {
return selector == null ? none : function() {
return this.querySelector(selector);
};
};
var selection_select = function(select) {
if (typeof select !== "function") select = selector(select);
for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {
if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {
if ("__data__" in node) subnode.__data__ = node.__data__;
subgroup[i] = subnode;
}
}
}
return new Selection(subgroups, this._parents);
};
function empty$1() {
return [];
}
var selectorAll = function(selector) {
return selector == null ? empty$1 : function() {
return this.querySelectorAll(selector);
};
};
var selection_selectAll = function(select) {
if (typeof select !== "function") select = selectorAll(select);
for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {
for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
if (node = group[i]) {
subgroups.push(select.call(node, node.__data__, i, group));
parents.push(node);
}
}
}
return new Selection(subgroups, parents);
};
var selection_filter = function(match) {
if (typeof match !== "function") match = matcher$1(match);
for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {
if ((node = group[i]) && match.call(node, node.__data__, i, group)) {
subgroup.push(node);
}
}
}
return new Selection(subgroups, this._parents);
};
var sparse = function(update) {
return new Array(update.length);
};
var selection_enter = function() {
return new Selection(this._enter || this._groups.map(sparse), this._parents);
};
function EnterNode(parent, datum) {
this.ownerDocument = parent.ownerDocument;
this.namespaceURI = parent.namespaceURI;
this._next = null;
this._parent = parent;
this.__data__ = datum;
}
EnterNode.prototype = {
constructor: EnterNode,
appendChild: function(child) { return this._parent.insertBefore(child, this._next); },
insertBefore: function(child, next) { return this._parent.insertBefore(child, next); },
querySelector: function(selector) { return this._parent.querySelector(selector); },
querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); }
};
var constant$1 = function(x) {
return function() {
return x;
};
};
var keyPrefix = "$"; // Protect against keys like “__proto__”.
function bindIndex(parent, group, enter, update, exit, data) {
var i = 0,
node,
groupLength = group.length,
dataLength = data.length;
// Put any non-null nodes that fit into update.
// Put any null nodes into enter.
// Put any remaining data into enter.
for (; i < dataLength; ++i) {
if (node = group[i]) {
node.__data__ = data[i];
update[i] = node;
} else {
enter[i] = new EnterNode(parent, data[i]);
}
}
// Put any non-null nodes that don’t fit into exit.
for (; i < groupLength; ++i) {
if (node = group[i]) {
exit[i] = node;
}
}
}
function bindKey(parent, group, enter, update, exit, data, key) {
var i,
node,
nodeByKeyValue = {},
groupLength = group.length,
dataLength = data.length,
keyValues = new Array(groupLength),
keyValue;
// Compute the key for each node.
// If multiple nodes have the same key, the duplicates are added to exit.
for (i = 0; i < groupLength; ++i) {
if (node = group[i]) {
keyValues[i] = keyValue = keyPrefix + key.call(node, node.__data__, i, group);
if (keyValue in nodeByKeyValue) {
exit[i] = node;
} else {
nodeByKeyValue[keyValue] = node;
}
}
}
// Compute the key for each datum.
// If there a node associated with this key, join and add it to update.
// If there is not (or the key is a duplicate), add it to enter.
for (i = 0; i < dataLength; ++i) {
keyValue = keyPrefix + key.call(parent, data[i], i, data);
if (node = nodeByKeyValue[keyValue]) {
update[i] = node;
node.__data__ = data[i];
nodeByKeyValue[keyValue] = null;
} else {
enter[i] = new EnterNode(parent, data[i]);
}
}
// Add any remaining nodes that were not bound to data to exit.
for (i = 0; i < groupLength; ++i) {
if ((node = group[i]) && (nodeByKeyValue[keyValues[i]] === node)) {
exit[i] = node;
}
}
}
var selection_data = function(value, key) {
if (!value) {
data = new Array(this.size()), j = -1;
this.each(function(d) { data[++j] = d; });
return data;
}
var bind = key ? bindKey : bindIndex,
parents = this._parents,
groups = this._groups;
if (typeof value !== "function") value = constant$1(value);
for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) {
var parent = parents[j],
group = groups[j],
groupLength = group.length,
data = value.call(parent, parent && parent.__data__, j, parents),
dataLength = data.length,
enterGroup = enter[j] = new Array(dataLength),
updateGroup = update[j] = new Array(dataLength),
exitGroup = exit[j] = new Array(groupLength);
bind(parent, group, enterGroup, updateGroup, exitGroup, data, key);
// Now connect the enter nodes to their following update node, such that
// appendChild can insert the materialized enter node before this node,
// rather than at the end of the parent node.
for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) {
if (previous = enterGroup[i0]) {
if (i0 >= i1) i1 = i0 + 1;
while (!(next = updateGroup[i1]) && ++i1 < dataLength);
previous._next = next || null;
}
}
}
update = new Selection(update, parents);
update._enter = enter;
update._exit = exit;
return update;
};
var selection_exit = function() {
return new Selection(this._exit || this._groups.map(sparse), this._parents);
};
var selection_merge = function(selection) {
for (var groups0 = this._groups, groups1 = selection._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {
for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {
if (node = group0[i] || group1[i]) {
merge[i] = node;
}
}
}
for (; j < m0; ++j) {
merges[j] = groups0[j];
}
return new Selection(merges, this._parents);
};
var selection_order = function() {
for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) {
for (var group = groups[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;
};
var selection_sort = function(compare) {
if (!compare) compare = ascending$1;
function compareNode(a, b) {
return a && b ? compare(a.__data__, b.__data__) : !a - !b;
}
for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) {
for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) {
if (node = group[i]) {
sortgroup[i] = node;
}
}
sortgroup.sort(compareNode);
}
return new Selection(sortgroups, this._parents).order();
};
function ascending$1(a, b) {
return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
}
var selection_call = function() {
var callback = arguments[0];
arguments[0] = this;
callback.apply(null, arguments);
return this;
};
var selection_nodes = function() {
var nodes = new Array(this.size()), i = -1;
this.each(function() { nodes[++i] = this; });
return nodes;
};
var selection_node = function() {
for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
for (var group = groups[j], i = 0, n = group.length; i < n; ++i) {
var node = group[i];
if (node) return node;
}
}
return null;
};
var selection_size = function() {
var size = 0;
this.each(function() { ++size; });
return size;
};
var selection_empty = function() {
return !this.node();
};
var selection_each = function(callback) {
for (var groups = this._groups, 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.call(node, node.__data__, i, group);
}
}
return this;
};
function attrRemove(name) {
return function() {
this.removeAttribute(name);
};
}
function attrRemoveNS(fullname) {
return function() {
this.removeAttributeNS(fullname.space, fullname.local);
};
}
function attrConstant(name, value) {
return function() {
this.setAttribute(name, value);
};
}
function attrConstantNS(fullname, value) {
return function() {
this.setAttributeNS(fullname.space, fullname.local, value);
};
}
function attrFunction(name, value) {
return function() {
var v = value.apply(this, arguments);
if (v == null) this.removeAttribute(name);
else this.setAttribute(name, v);
};
}
function attrFunctionNS(fullname, value) {
return function() {
var v = value.apply(this, arguments);
if (v == null) this.removeAttributeNS(fullname.space, fullname.local);
else this.setAttributeNS(fullname.space, fullname.local, v);
};
}
var selection_attr = function(name, value) {
var fullname = namespace(name);
if (arguments.length < 2) {
var node = this.node();
return fullname.local
? node.getAttributeNS(fullname.space, fullname.local)
: node.getAttribute(fullname);
}
return this.each((value == null
? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === "function"
? (fullname.local ? attrFunctionNS : attrFunction)
: (fullname.local ? attrConstantNS : attrConstant)))(fullname, value));
};
var defaultView = function(node) {
return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node
|| (node.document && node) // node is a Window
|| node.defaultView; // node is a Document
};
function styleRemove(name) {
return function() {
this.style.removeProperty(name);
};
}
function styleConstant(name, value, priority) {
return function() {
this.style.setProperty(name, value, priority);
};
}
function styleFunction(name, value, priority) {
return function() {
var v = value.apply(this, arguments);
if (v == null) this.style.removeProperty(name);
else this.style.setProperty(name, v, priority);
};
}
var selection_style = function(name, value, priority) {
return arguments.length > 1
? this.each((value == null
? styleRemove : typeof value === "function"
? styleFunction
: styleConstant)(name, value, priority == null ? "" : priority))
: styleValue(this.node(), name);
};
function styleValue(node, name) {
return node.style.getPropertyValue(name)
|| defaultView(node).getComputedStyle(node, null).getPropertyValue(name);
}
function propertyRemove(name) {
return function() {
delete this[name];
};
}
function propertyConstant(name, value) {
return function() {
this[name] = value;
};
}
function propertyFunction(name, value) {
return function() {
var v = value.apply(this, arguments);
if (v == null) delete this[name];
else this[name] = v;
};
}
var selection_property = function(name, value) {
return arguments.length > 1
? this.each((value == null
? propertyRemove : typeof value === "function"
? propertyFunction
: propertyConstant)(name, value))
: this.node()[name];
};
function classArray(string) {
return string.trim().split(/^|\s+/);
}
function classList(node) {
return node.classList || new ClassList(node);
}
function ClassList(node) {
this._node = node;
this._names = classArray(node.getAttribute("class") || "");
}
ClassList.prototype = {
add: function(name) {
var i = this._names.indexOf(name);
if (i < 0) {
this._names.push(name);
this._node.setAttribute("class", this._names.join(" "));
}
},
remove: function(name) {
var i = this._names.indexOf(name);
if (i >= 0) {
this._names.splice(i, 1);
this._node.setAttribute("class", this._names.join(" "));
}
},
contains: function(name) {
return this._names.indexOf(name) >= 0;
}
};
function classedAdd(node, names) {
var list = classList(node), i = -1, n = names.length;
while (++i < n) list.add(names[i]);
}
function classedRemove(node, names) {
var list = classList(node), i = -1, n = names.length;
while (++i < n) list.remove(names[i]);
}
function classedTrue(names) {
return function() {
classedAdd(this, names);
};
}
function classedFalse(names) {
return function() {
classedRemove(this, names);
};
}
function classedFunction(names, value) {
return function() {
(value.apply(this, arguments) ? classedAdd : classedRemove)(this, names);
};
}
var selection_classed = function(name, value) {
var names = classArray(name + "");
if (arguments.length < 2) {
var list = classList(this.node()), i = -1, n = names.length;
while (++i < n) if (!list.contains(names[i])) return false;
return true;
}
return this.each((typeof value === "function"
? classedFunction : value
? classedTrue
: classedFalse)(names, value));
};
function textRemove() {
this.textContent = "";
}
function textConstant(value) {
return function() {
this.textContent = value;
};
}
function textFunction(value) {
return function() {
var v = value.apply(this, arguments);
this.textContent = v == null ? "" : v;
};
}
var selection_text = function(value) {
return arguments.length
? this.each(value == null
? textRemove : (typeof value === "function"
? textFunction
: textConstant)(value))
: this.node().textContent;
};
function htmlRemove() {
this.innerHTML = "";
}
function htmlConstant(value) {
return function() {
this.innerHTML = value;
};
}
function htmlFunction(value) {
return function() {
var v = value.apply(this, arguments);
this.innerHTML = v == null ? "" : v;
};
}
var selection_html = function(value) {
return arguments.length
? this.each(value == null
? htmlRemove : (typeof value === "function"
? htmlFunction
: htmlConstant)(value))
: this.node().innerHTML;
};
function raise() {
if (this.nextSibling) this.parentNode.appendChild(this);
}
var selection_raise = function() {
return this.each(raise);
};
function lower() {
if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild);
}
var selection_lower = function() {
return this.each(lower);
};
var selection_append = function(name) {
var create = typeof name === "function" ? name : creator(name);
return this.select(function() {
return this.appendChild(create.apply(this, arguments));
});
};
function constantNull() {
return null;
}
var selection_insert = function(name, before) {
var create = typeof name === "function" ? name : creator(name),
select = before == null ? constantNull : typeof before === "function" ? before : selector(before);
return this.select(function() {
return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null);
});
};
function remove() {
var parent = this.parentNode;
if (parent) parent.removeChild(this);
}
var selection_remove = function() {
return this.each(remove);
};
var selection_datum = function(value) {
return arguments.length
? this.property("__data__", value)
: this.node().__data__;
};
function dispatchEvent(node, type, params) {
var window = defaultView(node),
event = window.CustomEvent;
if (typeof event === "function") {
event = new event(type, params);
} else {
event = window.document.createEvent("Event");
if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail;
else event.initEvent(type, false, false);
}
node.dispatchEvent(event);
}
function dispatchConstant(type, params) {
return function() {
return dispatchEvent(this, type, params);
};
}
function dispatchFunction(type, params) {
return function() {
return dispatchEvent(this, type, params.apply(this, arguments));
};
}
var selection_dispatch = function(type, params) {
return this.each((typeof params === "function"
? dispatchFunction
: dispatchConstant)(type, params));
};
var root = [null];
function Selection(groups, parents) {
this._groups = groups;
this._parents = parents;
}
function selection() {
return new Selection([[document.documentElement]], root);
}
Selection.prototype = selection.prototype = {
constructor: Selection,
select: selection_select,
selectAll: selection_selectAll,
filter: selection_filter,
data: selection_data,
enter: selection_enter,
exit: selection_exit,
merge: selection_merge,
order: selection_order,
sort: selection_sort,
call: selection_call,
nodes: selection_nodes,
node: selection_node,
size: selection_size,
empty: selection_empty,
each: selection_each,
attr: selection_attr,
style: selection_style,
property: selection_property,
classed: selection_classed,
text: selection_text,
html: selection_html,
raise: selection_raise,
lower: selection_lower,
append: selection_append,
insert: selection_insert,
remove: selection_remove,
datum: selection_datum,
on: selection_on,
dispatch: selection_dispatch
};
var select = function(selector) {
return typeof selector === "string"
? new Selection([[document.querySelector(selector)]], [document.documentElement])
: new Selection([[selector]], root);
};
var selectAll = function(selector) {
return typeof selector === "string"
? new Selection([document.querySelectorAll(selector)], [document.documentElement])
: new Selection([selector == null ? [] : selector], root);
};
var touch = function(node, touches, identifier) {
if (arguments.length < 3) identifier = touches, touches = sourceEvent().changedTouches;
for (var i = 0, n = touches ? touches.length : 0, touch; i < n; ++i) {
if ((touch = touches[i]).identifier === identifier) {
return point(node, touch);
}
}
return null;
};
var touches = function(node, touches) {
if (touches == null) touches = sourceEvent().touches;
for (var i = 0, n = touches ? touches.length : 0, points = new Array(n); i < n; ++i) {
points[i] = point(node, touches[i]);
}
return points;
};
function nopropagation() {
exports.event.stopImmediatePropagation();
}
var noevent = function() {
exports.event.preventDefault();
exports.event.stopImmediatePropagation();
};
var dragDisable = function(view) {
var root = view.document.documentElement,
selection$$1 = select(view).on("dragstart.drag", noevent, true);
if ("onselectstart" in root) {
selection$$1.on("selectstart.drag", noevent, true);
} else {
root.__noselect = root.style.MozUserSelect;
root.style.MozUserSelect = "none";
}
};
function yesdrag(view, noclick) {
var root = view.document.documentElement,
selection$$1 = select(view).on("dragstart.drag", null);
if (noclick) {
selection$$1.on("click.drag", noevent, true);
setTimeout(function() { selection$$1.on("click.drag", null); }, 0);
}
if ("onselectstart" in root) {
selection$$1.on("selectstart.drag", null);
} else {
root.style.MozUserSelect = root.__noselect;
delete root.__noselect;
}
}
var constant$2 = function(x) {
return function() {
return x;
};
};
function DragEvent(target, type, subject, id, active, x, y, dx, dy, dispatch) {
this.target = target;
this.type = type;
this.subject = subject;
this.identifier = id;
this.active = active;
this.x = x;
this.y = y;
this.dx = dx;
this.dy = dy;
this._ = dispatch;
}
DragEvent.prototype.on = function() {
var value = this._.on.apply(this._, arguments);
return value === this._ ? this : value;
};
// Ignore right-click, since that should open the context menu.
function defaultFilter$1() {
return !exports.event.button;
}
function defaultContainer() {
return this.parentNode;
}
function defaultSubject(d) {
return d == null ? {x: exports.event.x, y: exports.event.y} : d;
}
function touchable() {
return "ontouchstart" in this;
}
var drag = function() {
var filter = defaultFilter$1,
container = defaultContainer,
subject = defaultSubject,
gestures = {},
listeners = dispatch("start", "drag", "end"),
active = 0,
mousedownx,
mousedowny,
mousemoving,
touchending,
clickDistance2 = 0;
function drag(selection$$1) {
selection$$1
.on("mousedown.drag", mousedowned)
.filter(touchable)
.on("touchstart.drag", touchstarted)
.on("touchmove.drag", touchmoved)
.on("touchend.drag touchcancel.drag", touchended)
.style("touch-action", "none")
.style("-webkit-tap-highlight-color", "rgba(0,0,0,0)");
}
function mousedowned() {
if (touchending || !filter.apply(this, arguments)) return;
var gesture = beforestart("mouse", container.apply(this, arguments), mouse, this, arguments);
if (!gesture) return;
select(exports.event.view).on("mousemove.drag", mousemoved, true).on("mouseup.drag", mouseupped, true);
dragDisable(exports.event.view);
nopropagation();
mousemoving = false;
mousedownx = exports.event.clientX;
mousedowny = exports.event.clientY;
gesture("start");
}
function mousemoved() {
noevent();
if (!mousemoving) {
var dx = exports.event.clientX - mousedownx, dy = exports.event.clientY - mousedowny;
mousemoving = dx * dx + dy * dy > clickDistance2;
}
gestures.mouse("drag");
}
function mouseupped() {
select(exports.event.view).on("mousemove.drag mouseup.drag", null);
yesdrag(exports.event.view, mousemoving);
noevent();
gestures.mouse("end");
}
function touchstarted() {
if (!filter.apply(this, arguments)) return;
var touches$$1 = exports.event.changedTouches,
c = container.apply(this, arguments),
n = touches$$1.length, i, gesture;
for (i = 0; i < n; ++i) {
if (gesture = beforestart(touches$$1[i].identifier, c, touch, this, arguments)) {
nopropagation();
gesture("start");
}
}
}
function touchmoved() {
var touches$$1 = exports.event.changedTouches,
n = touches$$1.length, i, gesture;
for (i = 0; i < n; ++i) {
if (gesture = gestures[touches$$1[i].identifier]) {
noevent();
gesture("drag");
}
}
}
function touchended() {
var touches$$1 = exports.event.changedTouches,
n = touches$$1.length, i, gesture;
if (touchending) clearTimeout(touchending);
touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!
for (i = 0; i < n; ++i) {
if (gesture = gestures[touches$$1[i].identifier]) {
nopropagation();
gesture("end");
}
}
}
function beforestart(id, container, point, that, args) {
var p = point(container, id), s, dx, dy,
sublisteners = listeners.copy();
if (!customEvent(new DragEvent(drag, "beforestart", s, id, active, p[0], p[1], 0, 0, sublisteners), function() {
if ((exports.event.subject = s = subject.apply(that, args)) == null) return false;
dx = s.x - p[0] || 0;
dy = s.y - p[1] || 0;
return true;
})) return;
return function gesture(type) {
var p0 = p, n;
switch (type) {
case "start": gestures[id] = gesture, n = active++; break;
case "end": delete gestures[id], --active; // nobreak
case "drag": p = point(container, id), n = active; break;
}
customEvent(new DragEvent(drag, type, s, id, n, p[0] + dx, p[1] + dy, p[0] - p0[0], p[1] - p0[1], sublisteners), sublisteners.apply, sublisteners, [type, that, args]);
};
}
drag.filter = function(_) {
return arguments.length ? (filter = typeof _ === "function" ? _ : constant$2(!!_), drag) : filter;
};
drag.container = function(_) {
return arguments.length ? (container = typeof _ === "function" ? _ : constant$2(_), drag) : container;
};
drag.subject = function(_) {
return arguments.length ? (subject = typeof _ === "function" ? _ : constant$2(_), drag) : subject;
};
drag.on = function() {
var value = listeners.on.apply(listeners, arguments);
return value === listeners ? drag : value;
};
drag.clickDistance = function(_) {
return arguments.length ? (clickDistance2 = (_ = +_) * _, drag) : Math.sqrt(clickDistance2);
};
return drag;
};
var define = function(constructor, factory, prototype) {
constructor.prototype = factory.prototype = prototype;
prototype.constructor = constructor;
};
function extend(parent, definition) {
var prototype = Object.create(parent.prototype);
for (var key in definition) prototype[key] = definition[key];
return prototype;
}
function Color() {}
var darker = 0.7;
var brighter = 1 / darker;
var reI = "\\s*([+-]?\\d+)\\s*";
var reN = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*";
var reP = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*";
var reHex3 = /^#([0-9a-f]{3})$/;
var reHex6 = /^#([0-9a-f]{6})$/;
var reRgbInteger = new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$");
var reRgbPercent = new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$");
var reRgbaInteger = new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$");
var reRgbaPercent = new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$");
var reHslPercent = new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$");
var reHslaPercent = new RegExp("^hsla\\(" + [reN, reP, reP, reN] + "\\)$");
var named = {
aliceblue: 0xf0f8ff,
antiquewhite: 0xfaebd7,
aqua: 0x00ffff,
aquamarine: 0x7fffd4,
azure: 0xf0ffff,
beige: 0xf5f5dc,
bisque: 0xffe4c4,
black: 0x000000,
blanchedalmond: 0xffebcd,
blue: 0x0000ff,
blueviolet: 0x8a2be2,
brown: 0xa52a2a,
burlywood: 0xdeb887,
cadetblue: 0x5f9ea0,
chartreuse: 0x7fff00,
chocolate: 0xd2691e,
coral: 0xff7f50,
cornflowerblue: 0x6495ed,
cornsilk: 0xfff8dc,
crimson: 0xdc143c,
cyan: 0x00ffff,
darkblue: 0x00008b,
darkcyan: 0x008b8b,
darkgoldenrod: 0xb8860b,
darkgray: 0xa9a9a9,
darkgreen: 0x006400,
darkgrey: 0xa9a9a9,
darkkhaki: 0xbdb76b,
darkmagenta: 0x8b008b,
darkolivegreen: 0x556b2f,
darkorange: 0xff8c00,
darkorchid: 0x9932cc,
darkred: 0x8b0000,
darksalmon: 0xe9967a,
darkseagreen: 0x8fbc8f,
darkslateblue: 0x483d8b,
darkslategray: 0x2f4f4f,
darkslategrey: 0x2f4f4f,
darkturquoise: 0x00ced1,
darkviolet: 0x9400d3,
deeppink: 0xff1493,
deepskyblue: 0x00bfff,
dimgray: 0x696969,
dimgrey: 0x696969,
dodgerblue: 0x1e90ff,
firebrick: 0xb22222,
floralwhite: 0xfffaf0,
forestgreen: 0x228b22,
fuchsia: 0xff00ff,
gainsboro: 0xdcdcdc,
ghostwhite: 0xf8f8ff,
gold: 0xffd700,
goldenrod: 0xdaa520,
gray: 0x808080,
green: 0x008000,
greenyellow: 0xadff2f,
grey: 0x808080,
honeydew: 0xf0fff0,
hotpink: 0xff69b4,
indianred: 0xcd5c5c,
indigo: 0x4b0082,
ivory: 0xfffff0,
khaki: 0xf0e68c,
lavender: 0xe6e6fa,
lavenderblush: 0xfff0f5,
lawngreen: 0x7cfc00,
lemonchiffon: 0xfffacd,
lightblue: 0xadd8e6,
lightcoral: 0xf08080,
lightcyan: 0xe0ffff,
lightgoldenrodyellow: 0xfafad2,
lightgray: 0xd3d3d3,
lightgreen: 0x90ee90,
lightgrey: 0xd3d3d3,
lightpink: 0xffb6c1,
lightsalmon: 0xffa07a,
lightseagreen: 0x20b2aa,
lightskyblue: 0x87cefa,
lightslategray: 0x778899,
lightslategrey: 0x778899,
lightsteelblue: 0xb0c4de,
lightyellow: 0xffffe0,
lime: 0x00ff00,
limegreen: 0x32cd32,
linen: 0xfaf0e6,
magenta: 0xff00ff,
maroon: 0x800000,
mediumaquamarine: 0x66cdaa,
mediumblue: 0x0000cd,
mediumorchid: 0xba55d3,
mediumpurple: 0x9370db,
mediumseagreen: 0x3cb371,
mediumslateblue: 0x7b68ee,
mediumspringgreen: 0x00fa9a,
mediumturquoise: 0x48d1cc,
mediumvioletred: 0xc71585,
midnightblue: 0x191970,
mintcream: 0xf5fffa,
mistyrose: 0xffe4e1,
moccasin: 0xffe4b5,
navajowhite: 0xffdead,
navy: 0x000080,
oldlace: 0xfdf5e6,
olive: 0x808000,
olivedrab: 0x6b8e23,
orange: 0xffa500,
orangered: 0xff4500,
orchid: 0xda70d6,
palegoldenrod: 0xeee8aa,
palegreen: 0x98fb98,
paleturquoise: 0xafeeee,
palevioletred: 0xdb7093,
papayawhip: 0xffefd5,
peachpuff: 0xffdab9,
peru: 0xcd853f,
pink: 0xffc0cb,
plum: 0xdda0dd,
powderblue: 0xb0e0e6,
purple: 0x800080,
rebeccapurple: 0x663399,
red: 0xff0000,
rosybrown: 0xbc8f8f,
royalblue: 0x4169e1,
saddlebrown: 0x8b4513,
salmon: 0xfa8072,
sandybrown: 0xf4a460,
seagreen: 0x2e8b57,
seashell: 0xfff5ee,
sienna: 0xa0522d,
silver: 0xc0c0c0,
skyblue: 0x87ceeb,
slateblue: 0x6a5acd,
slategray: 0x708090,
slategrey: 0x708090,
snow: 0xfffafa,
springgreen: 0x00ff7f,
steelblue: 0x4682b4,
tan: 0xd2b48c,
teal: 0x008080,
thistle: 0xd8bfd8,
tomato: 0xff6347,
turquoise: 0x40e0d0,
violet: 0xee82ee,
wheat: 0xf5deb3,
white: 0xffffff,
whitesmoke: 0xf5f5f5,
yellow: 0xffff00,
yellowgreen: 0x9acd32
};
define(Color, color, {
displayable: function() {
return this.rgb().displayable();
},
toString: function() {
return this.rgb() + "";
}
});
function color(format) {
var m;
format = (format + "").trim().toLowerCase();
return (m = reHex3.exec(format)) ? (m = parseInt(m[1], 16), new Rgb((m >> 8 & 0xf) | (m >> 4 & 0x0f0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1)) // #f00
: (m = reHex6.exec(format)) ? rgbn(parseInt(m[1], 16)) // #ff0000
: (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0)
: (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%)
: (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1)
: (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1)
: (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%)
: (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1)
: named.hasOwnProperty(format) ? rgbn(named[format])
: format === "transparent" ? new Rgb(NaN, NaN, NaN, 0)
: null;
}
function rgbn(n) {
return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1);
}
function rgba(r, g, b, a) {
if (a <= 0) r = g = b = NaN;
return new Rgb(r, g, b, a);
}
function rgbConvert(o) {
if (!(o instanceof Color)) o = color(o);
if (!o) return new Rgb;
o = o.rgb();
return new Rgb(o.r, o.g, o.b, o.opacity);
}
function rgb(r, g, b, opacity) {
return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity);
}
function Rgb(r, g, b, opacity) {
this.r = +r;
this.g = +g;
this.b = +b;
this.opacity = +opacity;
}
define(Rgb, rgb, extend(Color, {
brighter: function(k) {
k = k == null ? brighter : Math.pow(brighter, k);
return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
},
darker: function(k) {
k = k == null ? darker : Math.pow(darker, k);
return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
},
rgb: function() {
return this;
},
displayable: function() {
return (0 <= this.r && this.r <= 255)
&& (0 <= this.g && this.g <= 255)
&& (0 <= this.b && this.b <= 255)
&& (0 <= this.opacity && this.opacity <= 1);
},
toString: function() {
var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a));
return (a === 1 ? "rgb(" : "rgba(")
+ Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", "
+ Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", "
+ Math.max(0, Math.min(255, Math.round(this.b) || 0))
+ (a === 1 ? ")" : ", " + a + ")");
}
}));
function hsla(h, s, l, a) {
if (a <= 0) h = s = l = NaN;
else if (l <= 0 || l >= 1) h = s = NaN;
else if (s <= 0) h = NaN;
return new Hsl(h, s, l, a);
}
function hslConvert(o) {
if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity);
if (!(o instanceof Color)) o = color(o);
if (!o) return new Hsl;
if (o instanceof Hsl) return o;
o = o.rgb();
var r = o.r / 255,
g = o.g / 255,
b = o.b / 255,
min = Math.min(r, g, b),
max = Math.max(r, g, b),
h = NaN,
s = max - min,
l = (max + min) / 2;
if (s) {
if (r === max) h = (g - b) / s + (g < b) * 6;
else if (g === max) h = (b - r) / s + 2;
else h = (r - g) / s + 4;
s /= l < 0.5 ? max + min : 2 - max - min;
h *= 60;
} else {
s = l > 0 && l < 1 ? 0 : h;
}
return new Hsl(h, s, l, o.opacity);
}
function hsl(h, s, l, opacity) {
return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity);
}
function Hsl(h, s, l, opacity) {
this.h = +h;
this.s = +s;
this.l = +l;
this.opacity = +opacity;
}
define(Hsl, hsl, extend(Color, {
brighter: function(k) {
k = k == null ? brighter : Math.pow(brighter, k);
return new Hsl(this.h, this.s, this.l * k, this.opacity);
},
darker: function(k) {
k = k == null ? darker : Math.pow(darker, k);
return new Hsl(this.h, this.s, this.l * k, this.opacity);
},
rgb: function() {
var h = this.h % 360 + (this.h < 0) * 360,
s = isNaN(h) || isNaN(this.s) ? 0 : this.s,
l = this.l,
m2 = l + (l < 0.5 ? l : 1 - l) * s,
m1 = 2 * l - m2;
return new Rgb(
hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2),
hsl2rgb(h, m1, m2),
hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2),
this.opacity
);
},
displayable: function() {
return (0 <= this.s && this.s <= 1 || isNaN(this.s))
&& (0 <= this.l && this.l <= 1)
&& (0 <= this.opacity && this.opacity <= 1);
}
}));
/* From FvD 13.37, CSS Color Module Level 3 */
function hsl2rgb(h, m1, m2) {
return (h < 60 ? m1 + (m2 - m1) * h / 60
: h < 180 ? m2
: h < 240 ? m1 + (m2 - m1) * (240 - h) / 60
: m1) * 255;
}
var deg2rad = Math.PI / 180;
var rad2deg = 180 / Math.PI;
var Kn = 18;
var Xn = 0.950470;
var Yn = 1;
var Zn = 1.088830;
var t0 = 4 / 29;
var t1 = 6 / 29;
var t2 = 3 * t1 * t1;
var t3 = t1 * t1 * t1;
function labConvert(o) {
if (o instanceof Lab) return new Lab(o.l, o.a, o.b, o.opacity);
if (o instanceof Hcl) {
var h = o.h * deg2rad;
return new Lab(o.l, Math.cos(h) * o.c, Math.sin(h) * o.c, o.opacity);
}
if (!(o instanceof Rgb)) o = rgbConvert(o);
var b = rgb2xyz(o.r),
a = rgb2xyz(o.g),
l = rgb2xyz(o.b),
x = xyz2lab((0.4124564 * b + 0.3575761 * a + 0.1804375 * l) / Xn),
y = xyz2lab((0.2126729 * b + 0.7151522 * a + 0.0721750 * l) / Yn),
z = xyz2lab((0.0193339 * b + 0.1191920 * a + 0.9503041 * l) / Zn);
return new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity);
}
function lab(l, a, b, opacity) {
return arguments.length === 1 ? labConvert(l) : new Lab(l, a, b, opacity == null ? 1 : opacity);
}
function Lab(l, a, b, opacity) {
this.l = +l;
this.a = +a;
this.b = +b;
this.opacity = +opacity;
}
define(Lab, lab, extend(Color, {
brighter: function(k) {
return new Lab(this.l + Kn * (k == null ? 1 : k), this.a, this.b, this.opacity);
},
darker: function(k) {
return new Lab(this.l - Kn * (k == null ? 1 : k), this.a, this.b, this.opacity);
},
rgb: function() {
var y = (this.l + 16) / 116,
x = isNaN(this.a) ? y : y + this.a / 500,
z = isNaN(this.b) ? y : y - this.b / 200;
y = Yn * lab2xyz(y);
x = Xn * lab2xyz(x);
z = Zn * lab2xyz(z);
return new Rgb(
xyz2rgb( 3.2404542 * x - 1.5371385 * y - 0.4985314 * z), // D65 -> sRGB
xyz2rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z),
xyz2rgb( 0.0556434 * x - 0.2040259 * y + 1.0572252 * z),
this.opacity
);
}
}));
function xyz2lab(t) {
return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0;
}
function lab2xyz(t) {
return t > t1 ? t * t * t : t2 * (t - t0);
}
function xyz2rgb(x) {
return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055);
}
function rgb2xyz(x) {
return (x /= 255) <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);
}
function hclConvert(o) {
if (o instanceof Hcl) return new Hcl(o.h, o.c, o.l, o.opacity);
if (!(o instanceof Lab)) o = labConvert(o);
var h = Math.atan2(o.b, o.a) * rad2deg;
return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l, o.opacity);
}
function hcl(h, c, l, opacity) {
return arguments.length === 1 ? hclConvert(h) : new Hcl(h, c, l, opacity == null ? 1 : opacity);
}
function Hcl(h, c, l, opacity) {
this.h = +h;
this.c = +c;
this.l = +l;
this.opacity = +opacity;
}
define(Hcl, hcl, extend(Color, {
brighter: function(k) {
return new Hcl(this.h, this.c, this.l + Kn * (k == null ? 1 : k), this.opacity);
},
darker: function(k) {
return new Hcl(this.h, this.c, this.l - Kn * (k == null ? 1 : k), this.opacity);
},
rgb: function() {
return labConvert(this).rgb();
}
}));
var A = -0.14861;
var B = +1.78277;
var C = -0.29227;
var D = -0.90649;
var E = +1.97294;
var ED = E * D;
var EB = E * B;
var BC_DA = B * C - D * A;
function cubehelixConvert(o) {
if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity);
if (!(o instanceof Rgb)) o = rgbConvert(o);
var r = o.r / 255,
g = o.g / 255,
b = o.b / 255,
l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB),
bl = b - l,
k = (E * (g - l) - C * bl) / D,
s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1
h = s ? Math.atan2(k, bl) * rad2deg - 120 : NaN;
return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity);
}
function cubehelix(h, s, l, opacity) {
return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity);
}
function Cubehelix(h, s, l, opacity) {
this.h = +h;
this.s = +s;
this.l = +l;
this.opacity = +opacity;
}
define(Cubehelix, cubehelix, extend(Color, {
brighter: function(k) {
k = k == null ? brighter : Math.pow(brighter, k);
return new Cubehelix(this.h, this.s, this.l * k, this.opacity);
},
darker: function(k) {
k = k == null ? darker : Math.pow(darker, k);
return new Cubehelix(this.h, this.s, this.l * k, this.opacity);
},
rgb: function() {
var h = isNaN(this.h) ? 0 : (this.h + 120) * deg2rad,
l = +this.l,
a = isNaN(this.s) ? 0 : this.s * l * (1 - l),
cosh = Math.cos(h),
sinh = Math.sin(h);
return new Rgb(
255 * (l + a * (A * cosh + B * sinh)),
255 * (l + a * (C * cosh + D * sinh)),
255 * (l + a * (E * cosh)),
this.opacity
);
}
}));
function basis(t1, v0, v1, v2, v3) {
var t2 = t1 * t1, t3 = t2 * t1;
return ((1 - 3 * t1 + 3 * t2 - t3) * v0
+ (4 - 6 * t2 + 3 * t3) * v1
+ (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2
+ t3 * v3) / 6;
}
var basis$1 = function(values) {
var n = values.length - 1;
return function(t) {
var i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n),
v1 = values[i],
v2 = values[i + 1],
v0 = i > 0 ? values[i - 1] : 2 * v1 - v2,
v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1;
return basis((t - i / n) * n, v0, v1, v2, v3);
};
};
var basisClosed = function(values) {
var n = values.length;
return function(t) {
var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n),
v0 = values[(i + n - 1) % n],
v1 = values[i % n],
v2 = values[(i + 1) % n],
v3 = values[(i + 2) % n];
return basis((t - i / n) * n, v0, v1, v2, v3);
};
};
var constant$3 = function(x) {
return function() {
return x;
};
};
function linear(a, d) {
return function(t) {
return a + t * d;
};
}
function exponential(a, b, y) {
return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) {
return Math.pow(a + t * b, y);
};
}
function hue(a, b) {
var d = b - a;
return d ? linear(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant$3(isNaN(a) ? b : a);
}
function gamma(y) {
return (y = +y) === 1 ? nogamma : function(a, b) {
return b - a ? exponential(a, b, y) : constant$3(isNaN(a) ? b : a);
};
}
function nogamma(a, b) {
var d = b - a;
return d ? linear(a, d) : constant$3(isNaN(a) ? b : a);
}
var interpolateRgb = ((function rgbGamma(y) {
var color$$1 = gamma(y);
function rgb$$1(start, end) {
var r = color$$1((start = rgb(start)).r, (end = rgb(end)).r),
g = color$$1(start.g, end.g),
b = color$$1(start.b, end.b),
opacity = nogamma(start.opacity, end.opacity);
return function(t) {
start.r = r(t);
start.g = g(t);
start.b = b(t);
start.opacity = opacity(t);
return start + "";
};
}
rgb$$1.gamma = rgbGamma;
return rgb$$1;
}))(1);
function rgbSpline(spline) {
return function(colors) {
var n = colors.length,
r = new Array(n),
g = new Array(n),
b = new Array(n),
i, color$$1;
for (i = 0; i < n; ++i) {
color$$1 = rgb(colors[i]);
r[i] = color$$1.r || 0;
g[i] = color$$1.g || 0;
b[i] = color$$1.b || 0;
}
r = spline(r);
g = spline(g);
b = spline(b);
color$$1.opacity = 1;
return function(t) {
color$$1.r = r(t);
color$$1.g = g(t);
color$$1.b = b(t);
return color$$1 + "";
};
};
}
var rgbBasis = rgbSpline(basis$1);
var rgbBasisClosed = rgbSpline(basisClosed);
var array$1 = function(a, b) {
var nb = b ? b.length : 0,
na = a ? Math.min(nb, a.length) : 0,
x = new Array(nb),
c = new Array(nb),
i;
for (i = 0; i < na; ++i) x[i] = interpolateValue(a[i], b[i]);
for (; i < nb; ++i) c[i] = b[i];
return function(t) {
for (i = 0; i < na; ++i) c[i] = x[i](t);
return c;
};
};
var date = function(a, b) {
var d = new Date;
return a = +a, b -= a, function(t) {
return d.setTime(a + b * t), d;
};
};
var reinterpolate = function(a, b) {
return a = +a, b -= a, function(t) {
return a + b * t;
};
};
var object = function(a, b) {
var i = {},
c = {},
k;
if (a === null || typeof a !== "object") a = {};
if (b === null || typeof b !== "object") b = {};
for (k in b) {
if (k in a) {
i[k] = interpolateValue(a[k], b[k]);
} else {
c[k] = b[k];
}
}
return function(t) {
for (k in i) c[k] = i[k](t);
return c;
};
};
var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g;
var reB = new RegExp(reA.source, "g");
function zero(b) {
return function() {
return b;
};
}
function one(b) {
return function(t) {
return b(t) + "";
};
}
var interpolateString = function(a, b) {
var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b
am, // current match in a
bm, // current match in b
bs, // string preceding current number in b, if any
i = -1, // index in s
s = [], // string constants and placeholders
q = []; // number interpolators
// Coerce inputs to strings.
a = a + "", b = b + "";
// Interpolate pairs of numbers in a & b.
while ((am = reA.exec(a))
&& (bm = reB.exec(b))) {
if ((bs = bm.index) > bi) { // a string precedes the next number in b
bs = b.slice(bi, bs);
if (s[i]) s[i] += bs; // coalesce with previous string
else s[++i] = bs;
}
if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match
if (s[i]) s[i] += bm; // coalesce with previous string
else s[++i] = bm;
} else { // interpolate non-matching numbers
s[++i] = null;
q.push({i: i, x: reinterpolate(am, bm)});
}
bi = reB.lastIndex;
}
// Add remains of b.
if (bi < b.length) {
bs = b.slice(bi);
if (s[i]) s[i] += bs; // coalesce with previous string
else s[++i] = bs;
}
// Special optimization for only a single match.
// Otherwise, interpolate each of the numbers and rejoin the string.
return s.length < 2 ? (q[0]
? one(q[0].x)
: zero(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 interpolateValue = function(a, b) {
var t = typeof b, c;
return b == null || t === "boolean" ? constant$3(b)
: (t === "number" ? reinterpolate
: t === "string" ? ((c = color(b)) ? (b = c, interpolateRgb) : interpolateString)
: b instanceof color ? interpolateRgb
: b instanceof Date ? date
: Array.isArray(b) ? array$1
: typeof b.valueOf !== "function" && typeof b.toString !== "function" || isNaN(b) ? object
: reinterpolate)(a, b);
};
var interpolateRound = function(a, b) {
return a = +a, b -= a, function(t) {
return Math.round(a + b * t);
};
};
var degrees = 180 / Math.PI;
var identity$2 = {
translateX: 0,
translateY: 0,
rotate: 0,
skewX: 0,
scaleX: 1,
scaleY: 1
};
var decompose = function(a, b, c, d, e, f) {
var scaleX, scaleY, skewX;
if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX;
if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX;
if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY;
if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX;
return {
translateX: e,
translateY: f,
rotate: Math.atan2(b, a) * degrees,
skewX: Math.atan(skewX) * degrees,
scaleX: scaleX,
scaleY: scaleY
};
};
var cssNode;
var cssRoot;
var cssView;
var svgNode;
function parseCss(value) {
if (value === "none") return identity$2;
if (!cssNode) cssNode = document.createElement("DIV"), cssRoot = document.documentElement, cssView = document.defaultView;
cssNode.style.transform = value;
value = cssView.getComputedStyle(cssRoot.appendChild(cssNode), null).getPropertyValue("transform");
cssRoot.removeChild(cssNode);
value = value.slice(7, -1).split(",");
return decompose(+value[0], +value[1], +value[2], +value[3], +value[4], +value[5]);
}
function parseSvg(value) {
if (value == null) return identity$2;
if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g");
svgNode.setAttribute("transform", value);
if (!(value = svgNode.transform.baseVal.consolidate())) return identity$2;
value = value.matrix;
return decompose(value.a, value.b, value.c, value.d, value.e, value.f);
}
function interpolateTransform(parse, pxComma, pxParen, degParen) {
function pop(s) {
return s.length ? s.pop() + " " : "";
}
function translate(xa, ya, xb, yb, s, q) {
if (xa !== xb || ya !== yb) {
var i = s.push("translate(", null, pxComma, null, pxParen);
q.push({i: i - 4, x: reinterpolate(xa, xb)}, {i: i - 2, x: reinterpolate(ya, yb)});
} else if (xb || yb) {
s.push("translate(" + xb + pxComma + yb + pxParen);
}
}
function rotate(a, b, s, q) {
if (a !== b) {
if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path
q.push({i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: reinterpolate(a, b)});
} else if (b) {
s.push(pop(s) + "rotate(" + b + degParen);
}
}
function skewX(a, b, s, q) {
if (a !== b) {
q.push({i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: reinterpolate(a, b)});
} else if (b) {
s.push(pop(s) + "skewX(" + b + degParen);
}
}
function scale(xa, ya, xb, yb, s, q) {
if (xa !== xb || ya !== yb) {
var i = s.push(pop(s) + "scale(", null, ",", null, ")");
q.push({i: i - 4, x: reinterpolate(xa, xb)}, {i: i - 2, x: reinterpolate(ya, yb)});
} else if (xb !== 1 || yb !== 1) {
s.push(pop(s) + "scale(" + xb + "," + yb + ")");
}
}
return function(a, b) {
var s = [], // string constants and placeholders
q = []; // number interpolators
a = parse(a), b = parse(b);
translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q);
rotate(a.rotate, b.rotate, s, q);
skewX(a.skewX, b.skewX, s, q);
scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q);
a = b = null; // gc
return function(t) {
var i = -1, n = q.length, o;
while (++i < n) s[(o = q[i]).i] = o.x(t);
return s.join("");
};
};
}
var interpolateTransformCss = interpolateTransform(parseCss, "px, ", "px)", "deg)");
var interpolateTransformSvg = interpolateTransform(parseSvg, ", ", ")", ")");
var rho = Math.SQRT2;
var rho2 = 2;
var rho4 = 4;
var epsilon2 = 1e-12;
function cosh(x) {
return ((x = Math.exp(x)) + 1 / x) / 2;
}
function sinh(x) {
return ((x = Math.exp(x)) - 1 / x) / 2;
}
function tanh(x) {
return ((x = Math.exp(2 * x)) - 1) / (x + 1);
}
// p0 = [ux0, uy0, w0]
// p1 = [ux1, uy1, w1]
var interpolateZoom = function(p0, p1) {
var ux0 = p0[0], uy0 = p0[1], w0 = p0[2],
ux1 = p1[0], uy1 = p1[1], w1 = p1[2],
dx = ux1 - ux0,
dy = uy1 - uy0,
d2 = dx * dx + dy * dy,
i,
S;
// Special case for u0 ≅ u1.
if (d2 < epsilon2) {
S = Math.log(w1 / w0) / rho;
i = function(t) {
return [
ux0 + t * dx,
uy0 + t * dy,
w0 * Math.exp(rho * t * S)
];
};
}
// General case.
else {
var d1 = Math.sqrt(d2),
b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1),
b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1),
r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0),
r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1);
S = (r1 - r0) / rho;
i = function(t) {
var s = t * S,
coshr0 = cosh(r0),
u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0));
return [
ux0 + u * dx,
uy0 + u * dy,
w0 * coshr0 / cosh(rho * s + r0)
];
};
}
i.duration = S * 1000;
return i;
};
function hsl$1(hue$$1) {
return function(start, end) {
var h = hue$$1((start = hsl(start)).h, (end = hsl(end)).h),
s = nogamma(start.s, end.s),
l = nogamma(start.l, end.l),
opacity = nogamma(start.opacity, end.opacity);
return function(t) {
start.h = h(t);
start.s = s(t);
start.l = l(t);
start.opacity = opacity(t);
return start + "";
};
}
}
var hsl$2 = hsl$1(hue);
var hslLong = hsl$1(nogamma);
function lab$1(start, end) {
var l = nogamma((start = lab(start)).l, (end = lab(end)).l),
a = nogamma(start.a, end.a),
b = nogamma(start.b, end.b),
opacity = nogamma(start.opacity, end.opacity);
return function(t) {
start.l = l(t);
start.a = a(t);
start.b = b(t);
start.opacity = opacity(t);
return start + "";
};
}
function hcl$1(hue$$1) {
return function(start, end) {
var h = hue$$1((start = hcl(start)).h, (end = hcl(end)).h),
c = nogamma(start.c, end.c),
l = nogamma(start.l, end.l),
opacity = nogamma(start.opacity, end.opacity);
return function(t) {
start.h = h(t);
start.c = c(t);
start.l = l(t);
start.opacity = opacity(t);
return start + "";
};
}
}
var hcl$2 = hcl$1(hue);
var hclLong = hcl$1(nogamma);
function cubehelix$1(hue$$1) {
return (function cubehelixGamma(y) {
y = +y;
function cubehelix$$1(start, end) {
var h = hue$$1((start = cubehelix(start)).h, (end = cubehelix(end)).h),
s = nogamma(start.s, end.s),
l = nogamma(start.l, end.l),
opacity = nogamma(start.opacity, end.opacity);
return function(t) {
start.h = h(t);
start.s = s(t);
start.l = l(Math.pow(t, y));
start.opacity = opacity(t);
return start + "";
};
}
cubehelix$$1.gamma = cubehelixGamma;
return cubehelix$$1;
})(1);
}
var cubehelix$2 = cubehelix$1(hue);
var cubehelixLong = cubehelix$1(nogamma);
var quantize = function(interpolator, n) {
var samples = new Array(n);
for (var i = 0; i < n; ++i) samples[i] = interpolator(i / (n - 1));
return samples;
};
var frame = 0;
var timeout = 0;
var interval = 0;
var pokeDelay = 1000;
var taskHead;
var taskTail;
var clockLast = 0;
var clockNow = 0;
var clockSkew = 0;
var clock = typeof performance === "object" && performance.now ? performance : Date;
var setFrame = typeof window === "object" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) { setTimeout(f, 17); };
function now() {
return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew);
}
function clearNow() {
clockNow = 0;
}
function Timer() {
this._call =
this._time =
this._next = null;
}
Timer.prototype = timer.prototype = {
constructor: Timer,
restart: function(callback, delay, time) {
if (typeof callback !== "function") throw new TypeError("callback is not a function");
time = (time == null ? now() : +time) + (delay == null ? 0 : +delay);
if (!this._next && taskTail !== this) {
if (taskTail) taskTail._next = this;
else taskHead = this;
taskTail = this;
}
this._call = callback;
this._time = time;
sleep();
},
stop: function() {
if (this._call) {
this._call = null;
this._time = Infinity;
sleep();
}
}
};
function timer(callback, delay, time) {
var t = new Timer;
t.restart(callback, delay, time);
return t;
}
function timerFlush() {
now(); // Get the current time, if not already set.
++frame; // Pretend we’ve set an alarm, if we haven’t already.
var t = taskHead, e;
while (t) {
if ((e = clockNow - t._time) >= 0) t._call.call(null, e);
t = t._next;
}
--frame;
}
function wake() {
clockNow = (clockLast = clock.now()) + clockSkew;
frame = timeout = 0;
try {
timerFlush();
} finally {
frame = 0;
nap();
clockNow = 0;
}
}
function poke() {
var now = clock.now(), delay = now - clockLast;
if (delay > pokeDelay) clockSkew -= delay, clockLast = now;
}
function nap() {
var t0, t1 = taskHead, t2, time = Infinity;
while (t1) {
if (t1._call) {
if (time > t1._time) time = t1._time;
t0 = t1, t1 = t1._next;
} else {
t2 = t1._next, t1._next = null;
t1 = t0 ? t0._next = t2 : taskHead = t2;
}
}
taskTail = t0;
sleep(time);
}
function sleep(time) {
if (frame) return; // Soonest alarm already set, or will be.
if (timeout) timeout = clearTimeout(timeout);
var delay = time - clockNow;
if (delay > 24) {
if (time < Infinity) timeout = setTimeout(wake, delay);
if (interval) interval = clearInterval(interval);
} else {
if (!interval) clockLast = clockNow, interval = setInterval(poke, pokeDelay);
frame = 1, setFrame(wake);
}
}
var timeout$1 = function(callback, delay, time) {
var t = new Timer;
delay = delay == null ? 0 : +delay;
t.restart(function(elapsed) {
t.stop();
callback(elapsed + delay);
}, delay, time);
return t;
};
var interval$1 = function(callback, delay, time) {
var t = new Timer, total = delay;
if (delay == null) return t.restart(callback, delay, time), t;
delay = +delay, time = time == null ? now() : +time;
t.restart(function tick(elapsed) {
elapsed += total;
t.restart(tick, total += delay, time);
callback(elapsed);
}, delay, time);
return t;
};
var emptyOn = dispatch("start", "end", "interrupt");
var emptyTween = [];
var CREATED = 0;
var SCHEDULED = 1;
var STARTING = 2;
var STARTED = 3;
var RUNNING = 4;
var ENDING = 5;
var ENDED = 6;
var schedule = function(node, name, id, index, group, timing) {
var schedules = node.__transition;
if (!schedules) node.__transition = {};
else if (id in schedules) return;
create(node, id, {
name: name,
index: index, // For context during callback.
group: group, // For context during callback.
on: emptyOn,
tween: emptyTween,
time: timing.time,
delay: timing.delay,
duration: timing.duration,
ease: timing.ease,
timer: null,
state: CREATED
});
};
function init(node, id) {
var schedule = node.__transition;
if (!schedule || !(schedule = schedule[id]) || schedule.state > CREATED) throw new Error("too late");
return schedule;
}
function set$1(node, id) {
var schedule = node.__transition;
if (!schedule || !(schedule = schedule[id]) || schedule.state > STARTING) throw new Error("too late");
return schedule;
}
function get$1(node, id) {
var schedule = node.__transition;
if (!schedule || !(schedule = schedule[id])) throw new Error("too late");
return schedule;
}
function create(node, id, self) {
var schedules = node.__transition,
tween;
// Initialize the self timer when the transition is created.
// Note the actual delay is not known until the first callback!
schedules[id] = self;
self.timer = timer(schedule, 0, self.time);
function schedule(elapsed) {
self.state = SCHEDULED;
self.timer.restart(start, self.delay, self.time);
// If the elapsed delay is less than our first sleep, start immediately.
if (self.delay <= elapsed) start(elapsed - self.delay);
}
function start(elapsed) {
var i, j, n, o;
// If the state is not SCHEDULED, then we previously errored on start.
if (self.state !== SCHEDULED) return stop();
for (i in schedules) {
o = schedules[i];
if (o.name !== self.name) continue;
// While this element already has a starting transition during this frame,
// defer starting an interrupting transition until that transition has a
// chance to tick (and possibly end); see d3/d3-transition#54!
if (o.state === STARTED) return timeout$1(start);
// Interrupt the active transition, if any.
// Dispatch the interrupt event.
if (o.state === RUNNING) {
o.state = ENDED;
o.timer.stop();
o.on.call("interrupt", node, node.__data__, o.index, o.group);
delete schedules[i];
}
// Cancel any pre-empted transitions. No interrupt event is dispatched
// because the cancelled transitions never started. Note that this also
// removes this transition from the pending list!
else if (+i < id) {
o.state = ENDED;
o.timer.stop();
delete schedules[i];
}
}
// Defer the first tick to end of the current frame; see d3/d3#1576.
// Note the transition may be canceled after start and before the first tick!
// Note this must be scheduled before the start event; see d3/d3-transition#16!
// Assuming this is successful, subsequent callbacks go straight to tick.
timeout$1(function() {
if (self.state === STARTED) {
self.state = RUNNING;
self.timer.restart(tick, self.delay, self.time);
tick(elapsed);
}
});
// Dispatch the start event.
// Note this must be done before the tween are initialized.
self.state = STARTING;
self.on.call("start", node, node.__data__, self.index, self.group);
if (self.state !== STARTING) return; // interrupted
self.state = STARTED;
// Initialize the tween, deleting null tween.
tween = new Array(n = self.tween.length);
for (i = 0, j = -1; i < n; ++i) {
if (o = self.tween[i].value.call(node, node.__data__, self.index, self.group)) {
tween[++j] = o;
}
}
tween.length = j + 1;
}
function tick(elapsed) {
var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1),
i = -1,
n = tween.length;
while (++i < n) {
tween[i].call(null, t);
}
// Dispatch the end event.
if (self.state === ENDING) {
self.on.call("end", node, node.__data__, self.index, self.group);
stop();
}
}
function stop() {
self.state = ENDED;
self.timer.stop();
delete schedules[id];
for (var i in schedules) return; // eslint-disable-line no-unused-vars
delete node.__transition;
}
}
var interrupt = function(node, name) {
var schedules = node.__transition,
schedule,
active,
empty = true,
i;
if (!schedules) return;
name = name == null ? null : name + "";
for (i in schedules) {
if ((schedule = schedules[i]).name !== name) { empty = false; continue; }
active = schedule.state > STARTING && schedule.state < ENDING;
schedule.state = ENDED;
schedule.timer.stop();
if (active) schedule.on.call("interrupt", node, node.__data__, schedule.index, schedule.group);
delete schedules[i];
}
if (empty) delete node.__transition;
};
var selection_interrupt = function(name) {
return this.each(function() {
interrupt(this, name);
});
};
function tweenRemove(id, name) {
var tween0, tween1;
return function() {
var schedule = set$1(this, id),
tween = schedule.tween;
// If this node shared tween with the previous node,
// just assign the updated shared tween and we’re done!
// Otherwise, copy-on-write.
if (tween !== tween0) {
tween1 = tween0 = tween;
for (var i = 0, n = tween1.length; i < n; ++i) {
if (tween1[i].name === name) {
tween1 = tween1.slice();
tween1.splice(i, 1);
break;
}
}
}
schedule.tween = tween1;
};
}
function tweenFunction(id, name, value) {
var tween0, tween1;
if (typeof value !== "function") throw new Error;
return function() {
var schedule = set$1(this, id),
tween = schedule.tween;
// If this node shared tween with the previous node,
// just assign the updated shared tween and we’re done!
// Otherwise, copy-on-write.
if (tween !== tween0) {
tween1 = (tween0 = tween).slice();
for (var t = {name: name, value: value}, i = 0, n = tween1.length; i < n; ++i) {
if (tween1[i].name === name) {
tween1[i] = t;
break;
}
}
if (i === n) tween1.push(t);
}
schedule.tween = tween1;
};
}
var transition_tween = function(name, value) {
var id = this._id;
name += "";
if (arguments.length < 2) {
var tween = get$1(this.node(), id).tween;
for (var i = 0, n = tween.length, t; i < n; ++i) {
if ((t = tween[i]).name === name) {
return t.value;
}
}
return null;
}
return this.each((value == null ? tweenRemove : tweenFunction)(id, name, value));
};
function tweenValue(transition, name, value) {
var id = transition._id;
transition.each(function() {
var schedule = set$1(this, id);
(schedule.value || (schedule.value = {}))[name] = value.apply(this, arguments);
});
return function(node) {
return get$1(node, id).value[name];
};
}
var interpolate$$1 = function(a, b) {
var c;
return (typeof b === "number" ? reinterpolate
: b instanceof color ? interpolateRgb
: (c = color(b)) ? (b = c, interpolateRgb)
: interpolateString)(a, b);
};
function attrRemove$1(name) {
return function() {
this.removeAttribute(name);
};
}
function attrRemoveNS$1(fullname) {
return function() {
this.removeAttributeNS(fullname.space, fullname.local);
};
}
function attrConstant$1(name, interpolate$$1, value1) {
var value00,
interpolate0;
return function() {
var value0 = this.getAttribute(name);
return value0 === value1 ? null
: value0 === value00 ? interpolate0
: interpolate0 = interpolate$$1(value00 = value0, value1);
};
}
function attrConstantNS$1(fullname, interpolate$$1, value1) {
var value00,
interpolate0;
return function() {
var value0 = this.getAttributeNS(fullname.space, fullname.local);
return value0 === value1 ? null
: value0 === value00 ? interpolate0
: interpolate0 = interpolate$$1(value00 = value0, value1);
};
}
function attrFunction$1(name, interpolate$$1, value) {
var value00,
value10,
interpolate0;
return function() {
var value0, value1 = value(this);
if (value1 == null) return void this.removeAttribute(name);
value0 = this.getAttribute(name);
return value0 === value1 ? null
: value0 === value00 && value1 === value10 ? interpolate0
: interpolate0 = interpolate$$1(value00 = value0, value10 = value1);
};
}
function attrFunctionNS$1(fullname, interpolate$$1, value) {
var value00,
value10,
interpolate0;
return function() {
var value0, value1 = value(this);
if (value1 == null) return void this.removeAttributeNS(fullname.space, fullname.local);
value0 = this.getAttributeNS(fullname.space, fullname.local);
return value0 === value1 ? null
: value0 === value00 && value1 === value10 ? interpolate0
: interpolate0 = interpolate$$1(value00 = value0, value10 = value1);
};
}
var transition_attr = function(name, value) {
var fullname = namespace(name), i = fullname === "transform" ? interpolateTransformSvg : interpolate$$1;
return this.attrTween(name, typeof value === "function"
? (fullname.local ? attrFunctionNS$1 : attrFunction$1)(fullname, i, tweenValue(this, "attr." + name, value))
: value == null ? (fullname.local ? attrRemoveNS$1 : attrRemove$1)(fullname)
: (fullname.local ? attrConstantNS$1 : attrConstant$1)(fullname, i, value + ""));
};
function attrTweenNS(fullname, value) {
function tween() {
var node = this, i = value.apply(node, arguments);
return i && function(t) {
node.setAttributeNS(fullname.space, fullname.local, i(t));
};
}
tween._value = value;
return tween;
}
function attrTween(name, value) {
function tween() {
var node = this, i = value.apply(node, arguments);
return i && function(t) {
node.setAttribute(name, i(t));
};
}
tween._value = value;
return tween;
}
var transition_attrTween = function(name, value) {
var key = "attr." + name;
if (arguments.length < 2) return (key = this.tween(key)) && key._value;
if (value == null) return this.tween(key, null);
if (typeof value !== "function") throw new Error;
var fullname = namespace(name);
return this.tween(key, (fullname.local ? attrTweenNS : attrTween)(fullname, value));
};
function delayFunction(id, value) {
return function() {
init(this, id).delay = +value.apply(this, arguments);
};
}
function delayConstant(id, value) {
return value = +value, function() {
init(this, id).delay = value;
};
}
var transition_delay = function(value) {
var id = this._id;
return arguments.length
? this.each((typeof value === "function"
? delayFunction
: delayConstant)(id, value))
: get$1(this.node(), id).delay;
};
function durationFunction(id, value) {
return function() {
set$1(this, id).duration = +value.apply(this, arguments);
};
}
function durationConstant(id, value) {
return value = +value, function() {
set$1(this, id).duration = value;
};
}
var transition_duration = function(value) {
var id = this._id;
return arguments.length
? this.each((typeof value === "function"
? durationFunction
: durationConstant)(id, value))
: get$1(this.node(), id).duration;
};
function easeConstant(id, value) {
if (typeof value !== "function") throw new Error;
return function() {
set$1(this, id).ease = value;
};
}
var transition_ease = function(value) {
var id = this._id;
return arguments.length
? this.each(easeConstant(id, value))
: get$1(this.node(), id).ease;
};
var transition_filter = function(match) {
if (typeof match !== "function") match = matcher$1(match);
for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {
if ((node = group[i]) && match.call(node, node.__data__, i, group)) {
subgroup.push(node);
}
}
}
return new Transition(subgroups, this._parents, this._name, this._id);
};
var transition_merge = function(transition) {
if (transition._id !== this._id) throw new Error;
for (var groups0 = this._groups, groups1 = transition._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {
for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {
if (node = group0[i] || group1[i]) {
merge[i] = node;
}
}
}
for (; j < m0; ++j) {
merges[j] = groups0[j];
}
return new Transition(merges, this._parents, this._name, this._id);
};
function start(name) {
return (name + "").trim().split(/^|\s+/).every(function(t) {
var i = t.indexOf(".");
if (i >= 0) t = t.slice(0, i);
return !t || t === "start";
});
}
function onFunction(id, name, listener) {
var on0, on1, sit = start(name) ? init : set$1;
return function() {
var schedule = sit(this, id),
on = schedule.on;
// If this node shared a dispatch with the previous node,
// just assign the updated shared dispatch and we’re done!
// Otherwise, copy-on-write.
if (on !== on0) (on1 = (on0 = on).copy()).on(name, listener);
schedule.on = on1;
};
}
var transition_on = function(name, listener) {
var id = this._id;
return arguments.length < 2
? get$1(this.node(), id).on.on(name)
: this.each(onFunction(id, name, listener));
};
function removeFunction(id) {
return function() {
var parent = this.parentNode;
for (var i in this.__transition) if (+i !== id) return;
if (parent) parent.removeChild(this);
};
}
var transition_remove = function() {
return this.on("end.remove", removeFunction(this._id));
};
var transition_select = function(select$$1) {
var name = this._name,
id = this._id;
if (typeof select$$1 !== "function") select$$1 = selector(select$$1);
for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {
if ((node = group[i]) && (subnode = select$$1.call(node, node.__data__, i, group))) {
if ("__data__" in node) subnode.__data__ = node.__data__;
subgroup[i] = subnode;
schedule(subgroup[i], name, id, i, subgroup, get$1(node, id));
}
}
}
return new Transition(subgroups, this._parents, name, id);
};
var transition_selectAll = function(select$$1) {
var name = this._name,
id = this._id;
if (typeof select$$1 !== "function") select$$1 = selectorAll(select$$1);
for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {
for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
if (node = group[i]) {
for (var children = select$$1.call(node, node.__data__, i, group), child, inherit = get$1(node, id), k = 0, l = children.length; k < l; ++k) {
if (child = children[k]) {
schedule(child, name, id, k, children, inherit);
}
}
subgroups.push(children);
parents.push(node);
}
}
}
return new Transition(subgroups, parents, name, id);
};
var Selection$1 = selection.prototype.constructor;
var transition_selection = function() {
return new Selection$1(this._groups, this._parents);
};
function styleRemove$1(name, interpolate$$2) {
var value00,
value10,
interpolate0;
return function() {
var value0 = styleValue(this, name),
value1 = (this.style.removeProperty(name), styleValue(this, name));
return value0 === value1 ? null
: value0 === value00 && value1 === value10 ? interpolate0
: interpolate0 = interpolate$$2(value00 = value0, value10 = value1);
};
}
function styleRemoveEnd(name) {
return function() {
this.style.removeProperty(name);
};
}
function styleConstant$1(name, interpolate$$2, value1) {
var value00,
interpolate0;
return function() {
var value0 = styleValue(this, name);
return value0 === value1 ? null
: value0 === value00 ? interpolate0
: interpolate0 = interpolate$$2(value00 = value0, value1);
};
}
function styleFunction$1(name, interpolate$$2, value) {
var value00,
value10,
interpolate0;
return function() {
var value0 = styleValue(this, name),
value1 = value(this);
if (value1 == null) value1 = (this.style.removeProperty(name), styleValue(this, name));
return value0 === value1 ? null
: value0 === value00 && value1 === value10 ? interpolate0
: interpolate0 = interpolate$$2(value00 = value0, value10 = value1);
};
}
var transition_style = function(name, value, priority) {
var i = (name += "") === "transform" ? interpolateTransformCss : interpolate$$1;
return value == null ? this
.styleTween(name, styleRemove$1(name, i))
.on("end.style." + name, styleRemoveEnd(name))
: this.styleTween(name, typeof value === "function"
? styleFunction$1(name, i, tweenValue(this, "style." + name, value))
: styleConstant$1(name, i, value + ""), priority);
};
function styleTween(name, value, priority) {
function tween() {
var node = this, i = value.apply(node, arguments);
return i && function(t) {
node.style.setProperty(name, i(t), priority);
};
}
tween._value = value;
return tween;
}
var transition_styleTween = function(name, value, priority) {
var key = "style." + (name += "");
if (arguments.length < 2) return (key = this.tween(key)) && key._value;
if (value == null) return this.tween(key, null);
if (typeof value !== "function") throw new Error;
return this.tween(key, styleTween(name, value, priority == null ? "" : priority));
};
function textConstant$1(value) {
return function() {
this.textContent = value;
};
}
function textFunction$1(value) {
return function() {
var value1 = value(this);
this.textContent = value1 == null ? "" : value1;
};
}
var transition_text = function(value) {
return this.tween("text", typeof value === "function"
? textFunction$1(tweenValue(this, "text", value))
: textConstant$1(value == null ? "" : value + ""));
};
var transition_transition = function() {
var name = this._name,
id0 = this._id,
id1 = newId();
for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {
for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
if (node = group[i]) {
var inherit = get$1(node, id0);
schedule(node, name, id1, i, group, {
time: inherit.time + inherit.delay + inherit.duration,
delay: 0,
duration: inherit.duration,
ease: inherit.ease
});
}
}
}
return new Transition(groups, this._parents, name, id1);
};
var id = 0;
function Transition(groups, parents, name, id) {
this._groups = groups;
this._parents = parents;
this._name = name;
this._id = id;
}
function transition(name) {
return selection().transition(name);
}
function newId() {
return ++id;
}
var selection_prototype = selection.prototype;
Transition.prototype = transition.prototype = {
constructor: Transition,
select: transition_select,
selectAll: transition_selectAll,
filter: transition_filter,
merge: transition_merge,
selection: transition_selection,
transition: transition_transition,
call: selection_prototype.call,
nodes: selection_prototype.nodes,
node: selection_prototype.node,
size: selection_prototype.size,
empty: selection_prototype.empty,
each: selection_prototype.each,
on: transition_on,
attr: transition_attr,
attrTween: transition_attrTween,
style: transition_style,
styleTween: transition_styleTween,
text: transition_text,
remove: transition_remove,
tween: transition_tween,
delay: transition_delay,
duration: transition_duration,
ease: transition_ease
};
function linear$1(t) {
return +t;
}
function quadIn(t) {
return t * t;
}
function quadOut(t) {
return t * (2 - t);
}
function quadInOut(t) {
return ((t *= 2) <= 1 ? t * t : --t * (2 - t) + 1) / 2;
}
function cubicIn(t) {
return t * t * t;
}
function cubicOut(t) {
return --t * t * t + 1;
}
function cubicInOut(t) {
return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;
}
var exponent = 3;
var polyIn = (function custom(e) {
e = +e;
function polyIn(t) {
return Math.pow(t, e);
}
polyIn.exponent = custom;
return polyIn;
})(exponent);
var polyOut = (function custom(e) {
e = +e;
function polyOut(t) {
return 1 - Math.pow(1 - t, e);
}
polyOut.exponent = custom;
return polyOut;
})(exponent);
var polyInOut = (function custom(e) {
e = +e;
function polyInOut(t) {
return ((t *= 2) <= 1 ? Math.pow(t, e) : 2 - Math.pow(2 - t, e)) / 2;
}
polyInOut.exponent = custom;
return polyInOut;
})(exponent);
var pi = Math.PI;
var halfPi = pi / 2;
function sinIn(t) {
return 1 - Math.cos(t * halfPi);
}
function sinOut(t) {
return Math.sin(t * halfPi);
}
function sinInOut(t) {
return (1 - Math.cos(pi * t)) / 2;
}
function expIn(t) {
return Math.pow(2, 10 * t - 10);
}
function expOut(t) {
return 1 - Math.pow(2, -10 * t);
}
function expInOut(t) {
return ((t *= 2) <= 1 ? Math.pow(2, 10 * t - 10) : 2 - Math.pow(2, 10 - 10 * t)) / 2;
}
function circleIn(t) {
return 1 - Math.sqrt(1 - t * t);
}
function circleOut(t) {
return Math.sqrt(1 - --t * t);
}
function circleInOut(t) {
return ((t *= 2) <= 1 ? 1 - Math.sqrt(1 - t * t) : Math.sqrt(1 - (t -= 2) * t) + 1) / 2;
}
var b1 = 4 / 11;
var b2 = 6 / 11;
var b3 = 8 / 11;
var b4 = 3 / 4;
var b5 = 9 / 11;
var b6 = 10 / 11;
var b7 = 15 / 16;
var b8 = 21 / 22;
var b9 = 63 / 64;
var b0 = 1 / b1 / b1;
function bounceIn(t) {
return 1 - bounceOut(1 - t);
}
function bounceOut(t) {
return (t = +t) < b1 ? b0 * t * t : t < b3 ? b0 * (t -= b2) * t + b4 : t < b6 ? b0 * (t -= b5) * t + b7 : b0 * (t -= b8) * t + b9;
}
function bounceInOut(t) {
return ((t *= 2) <= 1 ? 1 - bounceOut(1 - t) : bounceOut(t - 1) + 1) / 2;
}
var overshoot = 1.70158;
var backIn = (function custom(s) {
s = +s;
function backIn(t) {
return t * t * ((s + 1) * t - s);
}
backIn.overshoot = custom;
return backIn;
})(overshoot);
var backOut = (function custom(s) {
s = +s;
function backOut(t) {
return --t * t * ((s + 1) * t + s) + 1;
}
backOut.overshoot = custom;
return backOut;
})(overshoot);
var backInOut = (function custom(s) {
s = +s;
function backInOut(t) {
return ((t *= 2) < 1 ? t * t * ((s + 1) * t - s) : (t -= 2) * t * ((s + 1) * t + s) + 2) / 2;
}
backInOut.overshoot = custom;
return backInOut;
})(overshoot);
var tau = 2 * Math.PI;
var amplitude = 1;
var period = 0.3;
var elasticIn = (function custom(a, p) {
var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
function elasticIn(t) {
return a * Math.pow(2, 10 * --t) * Math.sin((s - t) / p);
}
elasticIn.amplitude = function(a) { return custom(a, p * tau); };
elasticIn.period = function(p) { return custom(a, p); };
return elasticIn;
})(amplitude, period);
var elasticOut = (function custom(a, p) {
var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
function elasticOut(t) {
return 1 - a * Math.pow(2, -10 * (t = +t)) * Math.sin((t + s) / p);
}
elasticOut.amplitude = function(a) { return custom(a, p * tau); };
elasticOut.period = function(p) { return custom(a, p); };
return elasticOut;
})(amplitude, period);
var elasticInOut = (function custom(a, p) {
var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
function elasticInOut(t) {
return ((t = t * 2 - 1) < 0
? a * Math.pow(2, 10 * t) * Math.sin((s - t) / p)
: 2 - a * Math.pow(2, -10 * t) * Math.sin((s + t) / p)) / 2;
}
elasticInOut.amplitude = function(a) { return custom(a, p * tau); };
elasticInOut.period = function(p) { return custom(a, p); };
return elasticInOut;
})(amplitude, period);
var defaultTiming = {
time: null, // Set on use.
delay: 0,
duration: 250,
ease: cubicInOut
};
function inherit(node, id) {
var timing;
while (!(timing = node.__transition) || !(timing = timing[id])) {
if (!(node = node.parentNode)) {
return defaultTiming.time = now(), defaultTiming;
}
}
return timing;
}
var selection_transition = function(name) {
var id,
timing;
if (name instanceof Transition) {
id = name._id, name = name._name;
} else {
id = newId(), (timing = defaultTiming).time = now(), name = name == null ? null : name + "";
}
for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {
for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
if (node = group[i]) {
schedule(node, name, id, i, group, timing || inherit(node, id));
}
}
}
return new Transition(groups, this._parents, name, id);
};
selection.prototype.interrupt = selection_interrupt;
selection.prototype.transition = selection_transition;
var root$1 = [null];
var active = function(node, name) {
var schedules = node.__transition,
schedule,
i;
if (schedules) {
name = name == null ? null : name + "";
for (i in schedules) {
if ((schedule = schedules[i]).state > SCHEDULED && schedule.name === name) {
return new Transition([[node]], root$1, name, +i);
}
}
}
return null;
};
var constant$4 = function(x) {
return function() {
return x;
};
};
var BrushEvent = function(target, type, selection) {
this.target = target;
this.type = type;
this.selection = selection;
};
function nopropagation$1() {
exports.event.stopImmediatePropagation();
}
var noevent$1 = function() {
exports.event.preventDefault();
exports.event.stopImmediatePropagation();
};
var MODE_DRAG = {name: "drag"};
var MODE_SPACE = {name: "space"};
var MODE_HANDLE = {name: "handle"};
var MODE_CENTER = {name: "center"};
var X = {
name: "x",
handles: ["e", "w"].map(type),
input: function(x, e) { return x && [[x[0], e[0][1]], [x[1], e[1][1]]]; },
output: function(xy) { return xy && [xy[0][0], xy[1][0]]; }
};
var Y = {
name: "y",
handles: ["n", "s"].map(type),
input: function(y, e) { return y && [[e[0][0], y[0]], [e[1][0], y[1]]]; },
output: function(xy) { return xy && [xy[0][1], xy[1][1]]; }
};
var XY = {
name: "xy",
handles: ["n", "e", "s", "w", "nw", "ne", "se", "sw"].map(type),
input: function(xy) { return xy; },
output: function(xy) { return xy; }
};
var cursors = {
overlay: "crosshair",
selection: "move",
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 flipX = {
e: "w",
w: "e",
nw: "ne",
ne: "nw",
se: "sw",
sw: "se"
};
var flipY = {
n: "s",
s: "n",
nw: "sw",
ne: "se",
se: "ne",
sw: "nw"
};
var signsX = {
overlay: +1,
selection: +1,
n: null,
e: +1,
s: null,
w: -1,
nw: -1,
ne: +1,
se: +1,
sw: -1
};
var signsY = {
overlay: +1,
selection: +1,
n: -1,
e: null,
s: +1,
w: null,
nw: -1,
ne: -1,
se: +1,
sw: +1
};
function type(t) {
return {type: t};
}
// Ignore right-click, since that should open the context menu.
function defaultFilter() {
return !exports.event.button;
}
function defaultExtent() {
var svg = this.ownerSVGElement || this;
return [[0, 0], [svg.width.baseVal.value, svg.height.baseVal.value]];
}
// Like d3.local, but with the name “__brush” rather than auto-generated.
function local$$1(node) {
while (!node.__brush) if (!(node = node.parentNode)) return;
return node.__brush;
}
function empty(extent) {
return extent[0][0] === extent[1][0]
|| extent[0][1] === extent[1][1];
}
function brushSelection(node) {
var state = node.__brush;
return state ? state.dim.output(state.selection) : null;
}
function brushX() {
return brush$1(X);
}
function brushY() {
return brush$1(Y);
}
var brush = function() {
return brush$1(XY);
};
function brush$1(dim) {
var extent = defaultExtent,
filter = defaultFilter,
listeners = dispatch(brush, "start", "brush", "end"),
handleSize = 6,
touchending;
function brush(group) {
var overlay = group
.property("__brush", initialize)
.selectAll(".overlay")
.data([type("overlay")]);
overlay.enter().append("rect")
.attr("class", "overlay")
.attr("pointer-events", "all")
.attr("cursor", cursors.overlay)
.merge(overlay)
.each(function() {
var extent = local$$1(this).extent;
select(this)
.attr("x", extent[0][0])
.attr("y", extent[0][1])
.attr("width", extent[1][0] - extent[0][0])
.attr("height", extent[1][1] - extent[0][1]);
});
group.selectAll(".selection")
.data([type("selection")])
.enter().append("rect")
.attr("class", "selection")
.attr("cursor", cursors.selection)
.attr("fill", "#777")
.attr("fill-opacity", 0.3)
.attr("stroke", "#fff")
.attr("shape-rendering", "crispEdges");
var handle = group.selectAll(".handle")
.data(dim.handles, function(d) { return d.type; });
handle.exit().remove();
handle.enter().append("rect")
.attr("class", function(d) { return "handle handle--" + d.type; })
.attr("cursor", function(d) { return cursors[d.type]; });
group
.each(redraw)
.attr("fill", "none")
.attr("pointer-events", "all")
.style("-webkit-tap-highlight-color", "rgba(0,0,0,0)")
.on("mousedown.brush touchstart.brush", started);
}
brush.move = function(group, selection$$1) {
if (group.selection) {
group
.on("start.brush", function() { emitter(this, arguments).beforestart().start(); })
.on("interrupt.brush end.brush", function() { emitter(this, arguments).end(); })
.tween("brush", function() {
var that = this,
state = that.__brush,
emit = emitter(that, arguments),
selection0 = state.selection,
selection1 = dim.input(typeof selection$$1 === "function" ? selection$$1.apply(this, arguments) : selection$$1, state.extent),
i = interpolateValue(selection0, selection1);
function tween(t) {
state.selection = t === 1 && empty(selection1) ? null : i(t);
redraw.call(that);
emit.brush();
}
return selection0 && selection1 ? tween : tween(1);
});
} else {
group
.each(function() {
var that = this,
args = arguments,
state = that.__brush,
selection1 = dim.input(typeof selection$$1 === "function" ? selection$$1.apply(that, args) : selection$$1, state.extent),
emit = emitter(that, args).beforestart();
interrupt(that);
state.selection = selection1 == null || empty(selection1) ? null : selection1;
redraw.call(that);
emit.start().brush().end();
});
}
};
function redraw() {
var group = select(this),
selection$$1 = local$$1(this).selection;
if (selection$$1) {
group.selectAll(".selection")
.style("display", null)
.attr("x", selection$$1[0][0])
.attr("y", selection$$1[0][1])
.attr("width", selection$$1[1][0] - selection$$1[0][0])
.attr("height", selection$$1[1][1] - selection$$1[0][1]);
group.selectAll(".handle")
.style("display", null)
.attr("x", function(d) { return d.type[d.type.length - 1] === "e" ? selection$$1[1][0] - handleSize / 2 : selection$$1[0][0] - handleSize / 2; })
.attr("y", function(d) { return d.type[0] === "s" ? selection$$1[1][1] - handleSize / 2 : selection$$1[0][1] - handleSize / 2; })
.attr("width", function(d) { return d.type === "n" || d.type === "s" ? selection$$1[1][0] - selection$$1[0][0] + handleSize : handleSize; })
.attr("height", function(d) { return d.type === "e" || d.type === "w" ? selection$$1[1][1] - selection$$1[0][1] + handleSize : handleSize; });
}
else {
group.selectAll(".selection,.handle")
.style("display", "none")
.attr("x", null)
.attr("y", null)
.attr("width", null)
.attr("height", null);
}
}
function emitter(that, args) {
return that.__brush.emitter || new Emitter(that, args);
}
function Emitter(that, args) {
this.that = that;
this.args = args;
this.state = that.__brush;
this.active = 0;
}
Emitter.prototype = {
beforestart: function() {
if (++this.active === 1) this.state.emitter = this, this.starting = true;
return this;
},
start: function() {
if (this.starting) this.starting = false, this.emit("start");
return this;
},
brush: function() {
this.emit("brush");
return this;
},
end: function() {
if (--this.active === 0) delete this.state.emitter, this.emit("end");
return this;
},
emit: function(type) {
customEvent(new BrushEvent(brush, type, dim.output(this.state.selection)), listeners.apply, listeners, [type, this.that, this.args]);
}
};
function started() {
if (exports.event.touches) { if (exports.event.changedTouches.length < exports.event.touches.length) return noevent$1(); }
else if (touchending) return;
if (!filter.apply(this, arguments)) return;
var that = this,
type = exports.event.target.__data__.type,
mode = (exports.event.metaKey ? type = "overlay" : type) === "selection" ? MODE_DRAG : (exports.event.altKey ? MODE_CENTER : MODE_HANDLE),
signX = dim === Y ? null : signsX[type],
signY = dim === X ? null : signsY[type],
state = local$$1(that),
extent = state.extent,
selection$$1 = state.selection,
W = extent[0][0], w0, w1,
N = extent[0][1], n0, n1,
E = extent[1][0], e0, e1,
S = extent[1][1], s0, s1,
dx,
dy,
moving,
shifting = signX && signY && exports.event.shiftKey,
lockX,
lockY,
point0 = mouse(that),
point = point0,
emit = emitter(that, arguments).beforestart();
if (type === "overlay") {
state.selection = selection$$1 = [
[w0 = dim === Y ? W : point0[0], n0 = dim === X ? N : point0[1]],
[e0 = dim === Y ? E : w0, s0 = dim === X ? S : n0]
];
} else {
w0 = selection$$1[0][0];
n0 = selection$$1[0][1];
e0 = selection$$1[1][0];
s0 = selection$$1[1][1];
}
w1 = w0;
n1 = n0;
e1 = e0;
s1 = s0;
var group = select(that)
.attr("pointer-events", "none");
var overlay = group.selectAll(".overlay")
.attr("cursor", cursors[type]);
if (exports.event.touches) {
group
.on("touchmove.brush", moved, true)
.on("touchend.brush touchcancel.brush", ended, true);
} else {
var view = select(exports.event.view)
.on("keydown.brush", keydowned, true)
.on("keyup.brush", keyupped, true)
.on("mousemove.brush", moved, true)
.on("mouseup.brush", ended, true);
dragDisable(exports.event.view);
}
nopropagation$1();
interrupt(that);
redraw.call(that);
emit.start();
function moved() {
var point1 = mouse(that);
if (shifting && !lockX && !lockY) {
if (Math.abs(point1[0] - point[0]) > Math.abs(point1[1] - point[1])) lockY = true;
else lockX = true;
}
point = point1;
moving = true;
noevent$1();
move();
}
function move() {
var t;
dx = point[0] - point0[0];
dy = point[1] - point0[1];
switch (mode) {
case MODE_SPACE:
case MODE_DRAG: {
if (signX) dx = Math.max(W - w0, Math.min(E - e0, dx)), w1 = w0 + dx, e1 = e0 + dx;
if (signY) dy = Math.max(N - n0, Math.min(S - s0, dy)), n1 = n0 + dy, s1 = s0 + dy;
break;
}
case MODE_HANDLE: {
if (signX < 0) dx = Math.max(W - w0, Math.min(E - w0, dx)), w1 = w0 + dx, e1 = e0;
else if (signX > 0) dx = Math.max(W - e0, Math.min(E - e0, dx)), w1 = w0, e1 = e0 + dx;
if (signY < 0) dy = Math.max(N - n0, Math.min(S - n0, dy)), n1 = n0 + dy, s1 = s0;
else if (signY > 0) dy = Math.max(N - s0, Math.min(S - s0, dy)), n1 = n0, s1 = s0 + dy;
break;
}
case MODE_CENTER: {
if (signX) w1 = Math.max(W, Math.min(E, w0 - dx * signX)), e1 = Math.max(W, Math.min(E, e0 + dx * signX));
if (signY) n1 = Math.max(N, Math.min(S, n0 - dy * signY)), s1 = Math.max(N, Math.min(S, s0 + dy * signY));
break;
}
}
if (e1 < w1) {
signX *= -1;
t = w0, w0 = e0, e0 = t;
t = w1, w1 = e1, e1 = t;
if (type in flipX) overlay.attr("cursor", cursors[type = flipX[type]]);
}
if (s1 < n1) {
signY *= -1;
t = n0, n0 = s0, s0 = t;
t = n1, n1 = s1, s1 = t;
if (type in flipY) overlay.attr("cursor", cursors[type = flipY[type]]);
}
if (state.selection) selection$$1 = state.selection; // May be set by brush.move!
if (lockX) w1 = selection$$1[0][0], e1 = selection$$1[1][0];
if (lockY) n1 = selection$$1[0][1], s1 = selection$$1[1][1];
if (selection$$1[0][0] !== w1
|| selection$$1[0][1] !== n1
|| selection$$1[1][0] !== e1
|| selection$$1[1][1] !== s1) {
state.selection = [[w1, n1], [e1, s1]];
redraw.call(that);
emit.brush();
}
}
function ended() {
nopropagation$1();
if (exports.event.touches) {
if (exports.event.touches.length) return;
if (touchending) clearTimeout(touchending);
touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!
group.on("touchmove.brush touchend.brush touchcancel.brush", null);
} else {
yesdrag(exports.event.view, moving);
view.on("keydown.brush keyup.brush mousemove.brush mouseup.brush", null);
}
group.attr("pointer-events", "all");
overlay.attr("cursor", cursors.overlay);
if (state.selection) selection$$1 = state.selection; // May be set by brush.move (on start)!
if (empty(selection$$1)) state.selection = null, redraw.call(that);
emit.end();
}
function keydowned() {
switch (exports.event.keyCode) {
case 16: { // SHIFT
shifting = signX && signY;
break;
}
case 18: { // ALT
if (mode === MODE_HANDLE) {
if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;
if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;
mode = MODE_CENTER;
move();
}
break;
}
case 32: { // SPACE; takes priority over ALT
if (mode === MODE_HANDLE || mode === MODE_CENTER) {
if (signX < 0) e0 = e1 - dx; else if (signX > 0) w0 = w1 - dx;
if (signY < 0) s0 = s1 - dy; else if (signY > 0) n0 = n1 - dy;
mode = MODE_SPACE;
overlay.attr("cursor", cursors.selection);
move();
}
break;
}
default: return;
}
noevent$1();
}
function keyupped() {
switch (exports.event.keyCode) {
case 16: { // SHIFT
if (shifting) {
lockX = lockY = shifting = false;
move();
}
break;
}
case 18: { // ALT
if (mode === MODE_CENTER) {
if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;
if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;
mode = MODE_HANDLE;
move();
}
break;
}
case 32: { // SPACE
if (mode === MODE_SPACE) {
if (exports.event.altKey) {
if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;
if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;
mode = MODE_CENTER;
} else {
if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;
if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;
mode = MODE_HANDLE;
}
overlay.attr("cursor", cursors[type]);
move();
}
break;
}
default: return;
}
noevent$1();
}
}
function initialize() {
var state = this.__brush || {selection: null};
state.extent = extent.apply(this, arguments);
state.dim = dim;
return state;
}
brush.extent = function(_) {
return arguments.length ? (extent = typeof _ === "function" ? _ : constant$4([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), brush) : extent;
};
brush.filter = function(_) {
return arguments.length ? (filter = typeof _ === "function" ? _ : constant$4(!!_), brush) : filter;
};
brush.handleSize = function(_) {
return arguments.length ? (handleSize = +_, brush) : handleSize;
};
brush.on = function() {
var value = listeners.on.apply(listeners, arguments);
return value === listeners ? brush : value;
};
return brush;
}
var cos = Math.cos;
var sin = Math.sin;
var pi$1 = Math.PI;
var halfPi$1 = pi$1 / 2;
var tau$1 = pi$1 * 2;
var max$1 = Math.max;
function compareValue(compare) {
return function(a, b) {
return compare(
a.source.value + a.target.value,
b.source.value + b.target.value
);
};
}
var chord = function() {
var padAngle = 0,
sortGroups = null,
sortSubgroups = null,
sortChords = null;
function chord(matrix) {
var n = matrix.length,
groupSums = [],
groupIndex = sequence(n),
subgroupIndex = [],
chords = [],
groups = chords.groups = new Array(n),
subgroups = new Array(n * n),
k,
x,
x0,
dx,
i,
j;
// Compute the sum.
k = 0, i = -1; while (++i < n) {
x = 0, j = -1; while (++j < n) {
x += matrix[i][j];
}
groupSums.push(x);
subgroupIndex.push(sequence(n));
k += x;
}
// Sort groups…
if (sortGroups) groupIndex.sort(function(a, b) {
return sortGroups(groupSums[a], groupSums[b]);
});
// Sort subgroups…
if (sortSubgroups) subgroupIndex.forEach(function(d, i) {
d.sort(function(a, b) {
return sortSubgroups(matrix[i][a], matrix[i][b]);
});
});
// Convert the sum to scaling factor for [0, 2pi].
// TODO Allow start and end angle to be specified?
// TODO Allow padding to be specified as percentage?
k = max$1(0, tau$1 - padAngle * n) / k;
dx = k ? padAngle : tau$1 / n;
// Compute the start and end angle for each group and subgroup.
// Note: Opera has a bug reordering object literal properties!
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[dj * n + di] = {
index: di,
subindex: dj,
startAngle: a0,
endAngle: a1,
value: v
};
}
groups[di] = {
index: di,
startAngle: x0,
endAngle: x,
value: groupSums[di]
};
x += dx;
}
// Generate chords for each (non-empty) subgroup-subgroup link.
i = -1; while (++i < n) {
j = i - 1; while (++j < n) {
var source = subgroups[j * n + i],
target = subgroups[i * n + j];
if (source.value || target.value) {
chords.push(source.value < target.value
? {source: target, target: source}
: {source: source, target: target});
}
}
}
return sortChords ? chords.sort(sortChords) : chords;
}
chord.padAngle = function(_) {
return arguments.length ? (padAngle = max$1(0, _), chord) : padAngle;
};
chord.sortGroups = function(_) {
return arguments.length ? (sortGroups = _, chord) : sortGroups;
};
chord.sortSubgroups = function(_) {
return arguments.length ? (sortSubgroups = _, chord) : sortSubgroups;
};
chord.sortChords = function(_) {
return arguments.length ? (_ == null ? sortChords = null : (sortChords = compareValue(_))._ = _, chord) : sortChords && sortChords._;
};
return chord;
};
var slice$2 = Array.prototype.slice;
var constant$5 = function(x) {
return function() {
return x;
};
};
var pi$2 = Math.PI;
var tau$2 = 2 * pi$2;
var epsilon$1 = 1e-6;
var tauEpsilon = tau$2 - epsilon$1;
function Path() {
this._x0 = this._y0 = // start of current subpath
this._x1 = this._y1 = null; // end of current subpath
this._ = "";
}
function path() {
return new Path;
}
Path.prototype = path.prototype = {
constructor: Path,
moveTo: function(x, y) {
this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y);
},
closePath: function() {
if (this._x1 !== null) {
this._x1 = this._x0, this._y1 = this._y0;
this._ += "Z";
}
},
lineTo: function(x, y) {
this._ += "L" + (this._x1 = +x) + "," + (this._y1 = +y);
},
quadraticCurveTo: function(x1, y1, x, y) {
this._ += "Q" + (+x1) + "," + (+y1) + "," + (this._x1 = +x) + "," + (this._y1 = +y);
},
bezierCurveTo: function(x1, y1, x2, y2, x, y) {
this._ += "C" + (+x1) + "," + (+y1) + "," + (+x2) + "," + (+y2) + "," + (this._x1 = +x) + "," + (this._y1 = +y);
},
arcTo: function(x1, y1, x2, y2, r) {
x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;
var x0 = this._x1,
y0 = this._y1,
x21 = x2 - x1,
y21 = y2 - y1,
x01 = x0 - x1,
y01 = y0 - y1,
l01_2 = x01 * x01 + y01 * y01;
// Is the radius negative? Error.
if (r < 0) throw new Error("negative radius: " + r);
// Is this path empty? Move to (x1,y1).
if (this._x1 === null) {
this._ += "M" + (this._x1 = x1) + "," + (this._y1 = y1);
}
// Or, is (x1,y1) coincident with (x0,y0)? Do nothing.
else if (!(l01_2 > epsilon$1)) {}
// Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?
// Equivalently, is (x1,y1) coincident with (x2,y2)?
// Or, is the radius zero? Line to (x1,y1).
else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon$1) || !r) {
this._ += "L" + (this._x1 = x1) + "," + (this._y1 = y1);
}
// Otherwise, draw an arc!
else {
var x20 = x2 - x0,
y20 = y2 - y0,
l21_2 = x21 * x21 + y21 * y21,
l20_2 = x20 * x20 + y20 * y20,
l21 = Math.sqrt(l21_2),
l01 = Math.sqrt(l01_2),
l = r * Math.tan((pi$2 - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),
t01 = l / l01,
t21 = l / l21;
// If the start tangent is not coincident with (x0,y0), line to.
if (Math.abs(t01 - 1) > epsilon$1) {
this._ += "L" + (x1 + t01 * x01) + "," + (y1 + t01 * y01);
}
this._ += "A" + r + "," + r + ",0,0," + (+(y01 * x20 > x01 * y20)) + "," + (this._x1 = x1 + t21 * x21) + "," + (this._y1 = y1 + t21 * y21);
}
},
arc: function(x, y, r, a0, a1, ccw) {
x = +x, y = +y, r = +r;
var dx = r * Math.cos(a0),
dy = r * Math.sin(a0),
x0 = x + dx,
y0 = y + dy,
cw = 1 ^ ccw,
da = ccw ? a0 - a1 : a1 - a0;
// Is the radius negative? Error.
if (r < 0) throw new Error("negative radius: " + r);
// Is this path empty? Move to (x0,y0).
if (this._x1 === null) {
this._ += "M" + x0 + "," + y0;
}
// Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).
else if (Math.abs(this._x1 - x0) > epsilon$1 || Math.abs(this._y1 - y0) > epsilon$1) {
this._ += "L" + x0 + "," + y0;
}
// Is this arc empty? We’re done.
if (!r) return;
// Does the angle go the wrong way? Flip the direction.
if (da < 0) da = da % tau$2 + tau$2;
// Is this a complete circle? Draw two arcs to complete the circle.
if (da > tauEpsilon) {
this._ += "A" + r + "," + r + ",0,1," + cw + "," + (x - dx) + "," + (y - dy) + "A" + r + "," + r + ",0,1," + cw + "," + (this._x1 = x0) + "," + (this._y1 = y0);
}
// Is this arc non-empty? Draw an arc!
else if (da > epsilon$1) {
this._ += "A" + r + "," + r + ",0," + (+(da >= pi$2)) + "," + cw + "," + (this._x1 = x + r * Math.cos(a1)) + "," + (this._y1 = y + r * Math.sin(a1));
}
},
rect: function(x, y, w, h) {
this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y) + "h" + (+w) + "v" + (+h) + "h" + (-w) + "Z";
},
toString: function() {
return this._;
}
};
function defaultSource(d) {
return d.source;
}
function defaultTarget(d) {
return d.target;
}
function defaultRadius(d) {
return d.radius;
}
function defaultStartAngle(d) {
return d.startAngle;
}
function defaultEndAngle(d) {
return d.endAngle;
}
var ribbon = function() {
var source = defaultSource,
target = defaultTarget,
radius = defaultRadius,
startAngle = defaultStartAngle,
endAngle = defaultEndAngle,
context = null;
function ribbon() {
var buffer,
argv = slice$2.call(arguments),
s = source.apply(this, argv),
t = target.apply(this, argv),
sr = +radius.apply(this, (argv[0] = s, argv)),
sa0 = startAngle.apply(this, argv) - halfPi$1,
sa1 = endAngle.apply(this, argv) - halfPi$1,
sx0 = sr * cos(sa0),
sy0 = sr * sin(sa0),
tr = +radius.apply(this, (argv[0] = t, argv)),
ta0 = startAngle.apply(this, argv) - halfPi$1,
ta1 = endAngle.apply(this, argv) - halfPi$1;
if (!context) context = buffer = path();
context.moveTo(sx0, sy0);
context.arc(0, 0, sr, sa0, sa1);
if (sa0 !== ta0 || sa1 !== ta1) { // TODO sr !== tr?
context.quadraticCurveTo(0, 0, tr * cos(ta0), tr * sin(ta0));
context.arc(0, 0, tr, ta0, ta1);
}
context.quadraticCurveTo(0, 0, sx0, sy0);
context.closePath();
if (buffer) return context = null, buffer + "" || null;
}
ribbon.radius = function(_) {
return arguments.length ? (radius = typeof _ === "function" ? _ : constant$5(+_), ribbon) : radius;
};
ribbon.startAngle = function(_) {
return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$5(+_), ribbon) : startAngle;
};
ribbon.endAngle = function(_) {
return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$5(+_), ribbon) : endAngle;
};
ribbon.source = function(_) {
return arguments.length ? (source = _, ribbon) : source;
};
ribbon.target = function(_) {
return arguments.length ? (target = _, ribbon) : target;
};
ribbon.context = function(_) {
return arguments.length ? ((context = _ == null ? null : _), ribbon) : context;
};
return ribbon;
};
var prefix = "$";
function Map() {}
Map.prototype = map$1.prototype = {
constructor: Map,
has: function(key) {
return (prefix + key) in this;
},
get: function(key) {
return this[prefix + key];
},
set: function(key, value) {
this[prefix + key] = value;
return this;
},
remove: function(key) {
var property = prefix + key;
return property in this && delete this[property];
},
clear: function() {
for (var property in this) if (property[0] === prefix) delete this[property];
},
keys: function() {
var keys = [];
for (var property in this) if (property[0] === prefix) keys.push(property.slice(1));
return keys;
},
values: function() {
var values = [];
for (var property in this) if (property[0] === prefix) values.push(this[property]);
return values;
},
entries: function() {
var entries = [];
for (var property in this) if (property[0] === prefix) entries.push({key: property.slice(1), value: this[property]});
return entries;
},
size: function() {
var size = 0;
for (var property in this) if (property[0] === prefix) ++size;
return size;
},
empty: function() {
for (var property in this) if (property[0] === prefix) return false;
return true;
},
each: function(f) {
for (var property in this) if (property[0] === prefix) f(this[property], property.slice(1), this);
}
};
function map$1(object, f) {
var map = new Map;
// Copy constructor.
if (object instanceof Map) object.each(function(value, key) { map.set(key, value); });
// Index array by numeric index or specified key function.
else if (Array.isArray(object)) {
var i = -1,
n = object.length,
o;
if (f == null) while (++i < n) map.set(i, object[i]);
else while (++i < n) map.set(f(o = object[i], i, object), o);
}
// Convert object to map.
else if (object) for (var key in object) map.set(key, object[key]);
return map;
}
var nest = function() {
var keys = [],
sortKeys = [],
sortValues,
rollup,
nest;
function apply(array, depth, createResult, setResult) {
if (depth >= keys.length) {
if (sortValues != null) array.sort(sortValues);
return rollup != null ? rollup(array) : array;
}
var i = -1,
n = array.length,
key = keys[depth++],
keyValue,
value,
valuesByKey = map$1(),
values,
result = createResult();
while (++i < n) {
if (values = valuesByKey.get(keyValue = key(value = array[i]) + "")) {
values.push(value);
} else {
valuesByKey.set(keyValue, [value]);
}
}
valuesByKey.each(function(values, key) {
setResult(result, key, apply(values, depth, createResult, setResult));
});
return result;
}
function entries(map, depth) {
if (++depth > keys.length) return map;
var array, sortKey = sortKeys[depth - 1];
if (rollup != null && depth >= keys.length) array = map.entries();
else array = [], map.each(function(v, k) { array.push({key: k, values: entries(v, depth)}); });
return sortKey != null ? array.sort(function(a, b) { return sortKey(a.key, b.key); }) : array;
}
return nest = {
object: function(array) { return apply(array, 0, createObject, setObject); },
map: function(array) { return apply(array, 0, createMap, setMap); },
entries: function(array) { return entries(apply(array, 0, createMap, setMap), 0); },
key: function(d) { keys.push(d); return nest; },
sortKeys: function(order) { sortKeys[keys.length - 1] = order; return nest; },
sortValues: function(order) { sortValues = order; return nest; },
rollup: function(f) { rollup = f; return nest; }
};
};
function createObject() {
return {};
}
function setObject(object, key, value) {
object[key] = value;
}
function createMap() {
return map$1();
}
function setMap(map, key, value) {
map.set(key, value);
}
function Set() {}
var proto = map$1.prototype;
Set.prototype = set$2.prototype = {
constructor: Set,
has: proto.has,
add: function(value) {
value += "";
this[prefix + value] = value;
return this;
},
remove: proto.remove,
clear: proto.clear,
values: proto.keys,
size: proto.size,
empty: proto.empty,
each: proto.each
};
function set$2(object, f) {
var set = new Set;
// Copy constructor.
if (object instanceof Set) object.each(function(value) { set.add(value); });
// Otherwise, assume it’s an array.
else if (object) {
var i = -1, n = object.length;
if (f == null) while (++i < n) set.add(object[i]);
else while (++i < n) set.add(f(object[i], i, object));
}
return set;
}
var d3keys = function(map) {
var keys = [];
for (var key in map) keys.push(key);
return keys;
};
var values = function(map) {
var values = [];
for (var key in map) values.push(map[key]);
return values;
};
var entries = function(map) {
var entries = [];
for (var key in map) entries.push({key: key, value: map[key]});
return entries;
};
function objectConverter(columns) {
return new Function("d", "return {" + columns.map(function(name, i) {
return JSON.stringify(name) + ": d[" + i + "]";
}).join(",") + "}");
}
function customConverter(columns, f) {
var object = objectConverter(columns);
return function(row, i) {
return f(object(row), i, columns);
};
}
// Compute unique columns in order of discovery.
function inferColumns(rows) {
var columnSet = Object.create(null),
columns = [];
rows.forEach(function(row) {
for (var column in row) {
if (!(column in columnSet)) {
columns.push(columnSet[column] = column);
}
}
});
return columns;
}
var dsv = function(delimiter) {
var reFormat = new RegExp("[\"" + delimiter + "\n\r]"),
delimiterCode = delimiter.charCodeAt(0);
function parse(text, f) {
var convert, columns, rows = parseRows(text, function(row, i) {
if (convert) return convert(row, i - 1);
columns = row, convert = f ? customConverter(row, f) : objectConverter(row);
});
rows.columns = columns;
return rows;
}
function parseRows(text, f) {
var EOL = {}, // sentinel value for end-of-line
EOF = {}, // sentinel value for end-of-file
rows = [], // output rows
N = text.length,
I = 0, // current character index
n = 0, // the current line number
t, // the current token
eol; // is the current token followed by EOL?
function token() {
if (I >= N) return EOF; // special case: end of file
if (eol) return eol = false, EOL; // special case: end of line
// special case: quotes
var j = I, c;
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;
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, "\"");
}
// common case: find next delimiter or newline
while (I < N) {
var k = 1;
c = text.charCodeAt(I++);
if (c === 10) eol = true; // \n
else if (c === 13) { eol = true; if (text.charCodeAt(I) === 10) ++I, ++k; } // \r|\r\n
else if (c !== delimiterCode) continue;
return text.slice(j, I - k);
}
// special case: last token before EOF
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;
}
function format(rows, columns) {
if (columns == null) columns = inferColumns(rows);
return [columns.map(formatValue).join(delimiter)].concat(rows.map(function(row) {
return columns.map(function(column) {
return formatValue(row[column]);
}).join(delimiter);
})).join("\n");
}
function formatRows(rows) {
return rows.map(formatRow).join("\n");
}
function formatRow(row) {
return row.map(formatValue).join(delimiter);
}
function formatValue(text) {
return text == null ? ""
: reFormat.test(text += "") ? "\"" + text.replace(/\"/g, "\"\"") + "\""
: text;
}
return {
parse: parse,
parseRows: parseRows,
format: format,
formatRows: formatRows
};
};
var csv = dsv(",");
var csvParse = csv.parse;
var csvParseRows = csv.parseRows;
var csvFormat = csv.format;
var csvFormatRows = csv.formatRows;
var tsv = dsv("\t");
var tsvParse = tsv.parse;
var tsvParseRows = tsv.parseRows;
var tsvFormat = tsv.format;
var tsvFormatRows = tsv.formatRows;
var center$1 = function(x, y) {
var nodes;
if (x == null) x = 0;
if (y == null) y = 0;
function force() {
var i,
n = nodes.length,
node,
sx = 0,
sy = 0;
for (i = 0; i < n; ++i) {
node = nodes[i], sx += node.x, sy += node.y;
}
for (sx = sx / n - x, sy = sy / n - y, i = 0; i < n; ++i) {
node = nodes[i], node.x -= sx, node.y -= sy;
}
}
force.initialize = function(_) {
nodes = _;
};
force.x = function(_) {
return arguments.length ? (x = +_, force) : x;
};
force.y = function(_) {
return arguments.length ? (y = +_, force) : y;
};
return force;
};
var constant$6 = function(x) {
return function() {
return x;
};
};
var jiggle = function() {
return (Math.random() - 0.5) * 1e-6;
};
var tree_add = function(d) {
var x = +this._x.call(null, d),
y = +this._y.call(null, d);
return add(this.cover(x, y), x, y, d);
};
function add(tree, x, y, d) {
if (isNaN(x) || isNaN(y)) return tree; // ignore invalid points
var parent,
node = tree._root,
leaf = {data: d},
x0 = tree._x0,
y0 = tree._y0,
x1 = tree._x1,
y1 = tree._y1,
xm,
ym,
xp,
yp,
right,
bottom,
i,
j;
// If the tree is empty, initialize the root as a leaf.
if (!node) return tree._root = leaf, tree;
// Find the existing leaf for the new point, or add it.
while (node.length) {
if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
if (parent = node, !(node = node[i = bottom << 1 | right])) return parent[i] = leaf, tree;
}
// Is the new point is exactly coincident with the existing point?
xp = +tree._x.call(null, node.data);
yp = +tree._y.call(null, node.data);
if (x === xp && y === yp) return leaf.next = node, parent ? parent[i] = leaf : tree._root = leaf, tree;
// Otherwise, split the leaf node until the old and new point are separated.
do {
parent = parent ? parent[i] = new Array(4) : tree._root = new Array(4);
if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
} while ((i = bottom << 1 | right) === (j = (yp >= ym) << 1 | (xp >= xm)));
return parent[j] = node, parent[i] = leaf, tree;
}
function addAll(data) {
var d, i, n = data.length,
x,
y,
xz = new Array(n),
yz = new Array(n),
x0 = Infinity,
y0 = Infinity,
x1 = -Infinity,
y1 = -Infinity;
// Compute the points and their extent.
for (i = 0; i < n; ++i) {
if (isNaN(x = +this._x.call(null, d = data[i])) || isNaN(y = +this._y.call(null, d))) continue;
xz[i] = x;
yz[i] = y;
if (x < x0) x0 = x;
if (x > x1) x1 = x;
if (y < y0) y0 = y;
if (y > y1) y1 = y;
}
// If there were no (valid) points, inherit the existing extent.
if (x1 < x0) x0 = this._x0, x1 = this._x1;
if (y1 < y0) y0 = this._y0, y1 = this._y1;
// Expand the tree to cover the new points.
this.cover(x0, y0).cover(x1, y1);
// Add the new points.
for (i = 0; i < n; ++i) {
add(this, xz[i], yz[i], data[i]);
}
return this;
}
var tree_cover = function(x, y) {
if (isNaN(x = +x) || isNaN(y = +y)) return this; // ignore invalid points
var x0 = this._x0,
y0 = this._y0,
x1 = this._x1,
y1 = this._y1;
// If the quadtree has no extent, initialize them.
// Integer extent are necessary so that if we later double the extent,
// the existing quadrant boundaries don’t change due to floating point error!
if (isNaN(x0)) {
x1 = (x0 = Math.floor(x)) + 1;
y1 = (y0 = Math.floor(y)) + 1;
}
// Otherwise, double repeatedly to cover.
else if (x0 > x || x > x1 || y0 > y || y > y1) {
var z = x1 - x0,
node = this._root,
parent,
i;
switch (i = (y < (y0 + y1) / 2) << 1 | (x < (x0 + x1) / 2)) {
case 0: {
do parent = new Array(4), parent[i] = node, node = parent;
while (z *= 2, x1 = x0 + z, y1 = y0 + z, x > x1 || y > y1);
break;
}
case 1: {
do parent = new Array(4), parent[i] = node, node = parent;
while (z *= 2, x0 = x1 - z, y1 = y0 + z, x0 > x || y > y1);
break;
}
case 2: {
do parent = new Array(4), parent[i] = node, node = parent;
while (z *= 2, x1 = x0 + z, y0 = y1 - z, x > x1 || y0 > y);
break;
}
case 3: {
do parent = new Array(4), parent[i] = node, node = parent;
while (z *= 2, x0 = x1 - z, y0 = y1 - z, x0 > x || y0 > y);
break;
}
}
if (this._root && this._root.length) this._root = node;
}
// If the quadtree covers the point already, just return.
else return this;
this._x0 = x0;
this._y0 = y0;
this._x1 = x1;
this._y1 = y1;
return this;
};
var tree_data = function() {
var data = [];
this.visit(function(node) {
if (!node.length) do data.push(node.data); while (node = node.next)
});
return data;
};
var tree_extent = function(_) {
return arguments.length
? this.cover(+_[0][0], +_[0][1]).cover(+_[1][0], +_[1][1])
: isNaN(this._x0) ? undefined : [[this._x0, this._y0], [this._x1, this._y1]];
};
var Quad = function(node, x0, y0, x1, y1) {
this.node = node;
this.x0 = x0;
this.y0 = y0;
this.x1 = x1;
this.y1 = y1;
};
var tree_find = function(x, y, radius) {
var data,
x0 = this._x0,
y0 = this._y0,
x1,
y1,
x2,
y2,
x3 = this._x1,
y3 = this._y1,
quads = [],
node = this._root,
q,
i;
if (node) quads.push(new Quad(node, x0, y0, x3, y3));
if (radius == null) radius = Infinity;
else {
x0 = x - radius, y0 = y - radius;
x3 = x + radius, y3 = y + radius;
radius *= radius;
}
while (q = quads.pop()) {
// Stop searching if this quadrant can’t contain a closer node.
if (!(node = q.node)
|| (x1 = q.x0) > x3
|| (y1 = q.y0) > y3
|| (x2 = q.x1) < x0
|| (y2 = q.y1) < y0) continue;
// Bisect the current quadrant.
if (node.length) {
var xm = (x1 + x2) / 2,
ym = (y1 + y2) / 2;
quads.push(
new Quad(node[3], xm, ym, x2, y2),
new Quad(node[2], x1, ym, xm, y2),
new Quad(node[1], xm, y1, x2, ym),
new Quad(node[0], x1, y1, xm, ym)
);
// Visit the closest quadrant first.
if (i = (y >= ym) << 1 | (x >= xm)) {
q = quads[quads.length - 1];
quads[quads.length - 1] = quads[quads.length - 1 - i];
quads[quads.length - 1 - i] = q;
}
}
// Visit this point. (Visiting coincident points isn’t necessary!)
else {
var dx = x - +this._x.call(null, node.data),
dy = y - +this._y.call(null, node.data),
d2 = dx * dx + dy * dy;
if (d2 < radius) {
var d = Math.sqrt(radius = d2);
x0 = x - d, y0 = y - d;
x3 = x + d, y3 = y + d;
data = node.data;
}
}
}
return data;
};
var tree_remove = function(d) {
if (isNaN(x = +this._x.call(null, d)) || isNaN(y = +this._y.call(null, d))) return this; // ignore invalid points
var parent,
node = this._root,
retainer,
previous,
next,
x0 = this._x0,
y0 = this._y0,
x1 = this._x1,
y1 = this._y1,
x,
y,
xm,
ym,
right,
bottom,
i,
j;
// If the tree is empty, initialize the root as a leaf.
if (!node) return this;
// Find the leaf node for the point.
// While descending, also retain the deepest parent with a non-removed sibling.
if (node.length) while (true) {
if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
if (!(parent = node, node = node[i = bottom << 1 | right])) return this;
if (!node.length) break;
if (parent[(i + 1) & 3] || parent[(i + 2) & 3] || parent[(i + 3) & 3]) retainer = parent, j = i;
}
// Find the point to remove.
while (node.data !== d) if (!(previous = node, node = node.next)) return this;
if (next = node.next) delete node.next;
// If there are multiple coincident points, remove just the point.
if (previous) return (next ? previous.next = next : delete previous.next), this;
// If this is the root point, remove it.
if (!parent) return this._root = next, this;
// Remove this leaf.
next ? parent[i] = next : delete parent[i];
// If the parent now contains exactly one leaf, collapse superfluous parents.
if ((node = parent[0] || parent[1] || parent[2] || parent[3])
&& node === (parent[3] || parent[2] || parent[1] || parent[0])
&& !node.length) {
if (retainer) retainer[j] = node;
else this._root = node;
}
return this;
};
function removeAll(data) {
for (var i = 0, n = data.length; i < n; ++i) this.remove(data[i]);
return this;
}
var tree_root = function() {
return this._root;
};
var tree_size = function() {
var size = 0;
this.visit(function(node) {
if (!node.length) do ++size; while (node = node.next)
});
return size;
};
var tree_visit = function(callback) {
var quads = [], q, node = this._root, child, x0, y0, x1, y1;
if (node) quads.push(new Quad(node, this._x0, this._y0, this._x1, this._y1));
while (q = quads.pop()) {
if (!callback(node = q.node, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1) && node.length) {
var xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;
if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1));
if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1));
if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym));
if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym));
}
}
return this;
};
var tree_visitAfter = function(callback) {
var quads = [], next = [], q;
if (this._root) quads.push(new Quad(this._root, this._x0, this._y0, this._x1, this._y1));
while (q = quads.pop()) {
var node = q.node;
if (node.length) {
var child, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1, xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;
if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym));
if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym));
if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1));
if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1));
}
next.push(q);
}
while (q = next.pop()) {
callback(q.node, q.x0, q.y0, q.x1, q.y1);
}
return this;
};
function defaultX(d) {
return d[0];
}
var tree_x = function(_) {
return arguments.length ? (this._x = _, this) : this._x;
};
function defaultY(d) {
return d[1];
}
var tree_y = function(_) {
return arguments.length ? (this._y = _, this) : this._y;
};
function quadtree(nodes, x, y) {
var tree = new Quadtree(x == null ? defaultX : x, y == null ? defaultY : y, NaN, NaN, NaN, NaN);
return nodes == null ? tree : tree.addAll(nodes);
}
function Quadtree(x, y, x0, y0, x1, y1) {
this._x = x;
this._y = y;
this._x0 = x0;
this._y0 = y0;
this._x1 = x1;
this._y1 = y1;
this._root = undefined;
}
function leaf_copy(leaf) {
var copy = {data: leaf.data}, next = copy;
while (leaf = leaf.next) next = next.next = {data: leaf.data};
return copy;
}
var treeProto = quadtree.prototype = Quadtree.prototype;
treeProto.copy = function() {
var copy = new Quadtree(this._x, this._y, this._x0, this._y0, this._x1, this._y1),
node = this._root,
nodes,
child;
if (!node) return copy;
if (!node.length) return copy._root = leaf_copy(node), copy;
nodes = [{source: node, target: copy._root = new Array(4)}];
while (node = nodes.pop()) {
for (var i = 0; i < 4; ++i) {
if (child = node.source[i]) {
if (child.length) nodes.push({source: child, target: node.target[i] = new Array(4)});
else node.target[i] = leaf_copy(child);
}
}
}
return copy;
};
treeProto.add = tree_add;
treeProto.addAll = addAll;
treeProto.cover = tree_cover;
treeProto.data = tree_data;
treeProto.extent = tree_extent;
treeProto.find = tree_find;
treeProto.remove = tree_remove;
treeProto.removeAll = removeAll;
treeProto.root = tree_root;
treeProto.size = tree_size;
treeProto.visit = tree_visit;
treeProto.visitAfter = tree_visitAfter;
treeProto.x = tree_x;
treeProto.y = tree_y;
function x(d) {
return d.x + d.vx;
}
function y(d) {
return d.y + d.vy;
}
var collide = function(radius) {
var nodes,
radii,
strength = 1,
iterations = 1;
if (typeof radius !== "function") radius = constant$6(radius == null ? 1 : +radius);
function force() {
var i, n = nodes.length,
tree,
node,
xi,
yi,
ri,
ri2;
for (var k = 0; k < iterations; ++k) {
tree = quadtree(nodes, x, y).visitAfter(prepare);
for (i = 0; i < n; ++i) {
node = nodes[i];
ri = radii[node.index], ri2 = ri * ri;
xi = node.x + node.vx;
yi = node.y + node.vy;
tree.visit(apply);
}
}
function apply(quad, x0, y0, x1, y1) {
var data = quad.data, rj = quad.r, r = ri + rj;
if (data) {
if (data.index > node.index) {
var x = xi - data.x - data.vx,
y = yi - data.y - data.vy,
l = x * x + y * y;
if (l < r * r) {
if (x === 0) x = jiggle(), l += x * x;
if (y === 0) y = jiggle(), l += y * y;
l = (r - (l = Math.sqrt(l))) / l * strength;
node.vx += (x *= l) * (r = (rj *= rj) / (ri2 + rj));
node.vy += (y *= l) * r;
data.vx -= x * (r = 1 - r);
data.vy -= y * r;
}
}
return;
}
return x0 > xi + r || x1 < xi - r || y0 > yi + r || y1 < yi - r;
}
}
function prepare(quad) {
if (quad.data) return quad.r = radii[quad.data.index];
for (var i = quad.r = 0; i < 4; ++i) {
if (quad[i] && quad[i].r > quad.r) {
quad.r = quad[i].r;
}
}
}
function initialize() {
if (!nodes) return;
var i, n = nodes.length, node;
radii = new Array(n);
for (i = 0; i < n; ++i) node = nodes[i], radii[node.index] = +radius(node, i, nodes);
}
force.initialize = function(_) {
nodes = _;
initialize();
};
force.iterations = function(_) {
return arguments.length ? (iterations = +_, force) : iterations;
};
force.strength = function(_) {
return arguments.length ? (strength = +_, force) : strength;
};
force.radius = function(_) {
return arguments.length ? (radius = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : radius;
};
return force;
};
function index(d) {
return d.index;
}
function find(nodeById, nodeId) {
var node = nodeById.get(nodeId);
if (!node) throw new Error("missing: " + nodeId);
return node;
}
var link = function(links) {
var id = index,
strength = defaultStrength,
strengths,
distance = constant$6(30),
distances,
nodes,
count,
bias,
iterations = 1;
if (links == null) links = [];
function defaultStrength(link) {
return 1 / Math.min(count[link.source.index], count[link.target.index]);
}
function force(alpha) {
for (var k = 0, n = links.length; k < iterations; ++k) {
for (var i = 0, link, source, target, x, y, l, b; i < n; ++i) {
link = links[i], source = link.source, target = link.target;
x = target.x + target.vx - source.x - source.vx || jiggle();
y = target.y + target.vy - source.y - source.vy || jiggle();
l = Math.sqrt(x * x + y * y);
l = (l - distances[i]) / l * alpha * strengths[i];
x *= l, y *= l;
target.vx -= x * (b = bias[i]);
target.vy -= y * b;
source.vx += x * (b = 1 - b);
source.vy += y * b;
}
}
}
function initialize() {
if (!nodes) return;
var i,
n = nodes.length,
m = links.length,
nodeById = map$1(nodes, id),
link;
for (i = 0, count = new Array(n); i < m; ++i) {
link = links[i], link.index = i;
if (typeof link.source !== "object") link.source = find(nodeById, link.source);
if (typeof link.target !== "object") link.target = find(nodeById, link.target);
count[link.source.index] = (count[link.source.index] || 0) + 1;
count[link.target.index] = (count[link.target.index] || 0) + 1;
}
for (i = 0, bias = new Array(m); i < m; ++i) {
link = links[i], bias[i] = count[link.source.index] / (count[link.source.index] + count[link.target.index]);
}
strengths = new Array(m), initializeStrength();
distances = new Array(m), initializeDistance();
}
function initializeStrength() {
if (!nodes) return;
for (var i = 0, n = links.length; i < n; ++i) {
strengths[i] = +strength(links[i], i, links);
}
}
function initializeDistance() {
if (!nodes) return;
for (var i = 0, n = links.length; i < n; ++i) {
distances[i] = +distance(links[i], i, links);
}
}
force.initialize = function(_) {
nodes = _;
initialize();
};
force.links = function(_) {
return arguments.length ? (links = _, initialize(), force) : links;
};
force.id = function(_) {
return arguments.length ? (id = _, force) : id;
};
force.iterations = function(_) {
return arguments.length ? (iterations = +_, force) : iterations;
};
force.strength = function(_) {
return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initializeStrength(), force) : strength;
};
force.distance = function(_) {
return arguments.length ? (distance = typeof _ === "function" ? _ : constant$6(+_), initializeDistance(), force) : distance;
};
return force;
};
function x$1(d) {
return d.x;
}
function y$1(d) {
return d.y;
}
var initialRadius = 10;
var initialAngle = Math.PI * (3 - Math.sqrt(5));
var simulation = function(nodes) {
var simulation,
alpha = 1,
alphaMin = 0.001,
alphaDecay = 1 - Math.pow(alphaMin, 1 / 300),
alphaTarget = 0,
velocityDecay = 0.6,
forces = map$1(),
stepper = timer(step),
event = dispatch("tick", "end");
if (nodes == null) nodes = [];
function step() {
tick();
event.call("tick", simulation);
if (alpha < alphaMin) {
stepper.stop();
event.call("end", simulation);
}
}
function tick() {
var i, n = nodes.length, node;
alpha += (alphaTarget - alpha) * alphaDecay;
forces.each(function(force) {
force(alpha);
});
for (i = 0; i < n; ++i) {
node = nodes[i];
if (node.fx == null) node.x += node.vx *= velocityDecay;
else node.x = node.fx, node.vx = 0;
if (node.fy == null) node.y += node.vy *= velocityDecay;
else node.y = node.fy, node.vy = 0;
}
}
function initializeNodes() {
for (var i = 0, n = nodes.length, node; i < n; ++i) {
node = nodes[i], node.index = i;
if (isNaN(node.x) || isNaN(node.y)) {
var radius = initialRadius * Math.sqrt(i), angle = i * initialAngle;
node.x = radius * Math.cos(angle);
node.y = radius * Math.sin(angle);
}
if (isNaN(node.vx) || isNaN(node.vy)) {
node.vx = node.vy = 0;
}
}
}
function initializeForce(force) {
if (force.initialize) force.initialize(nodes);
return force;
}
initializeNodes();
return simulation = {
tick: tick,
restart: function() {
return stepper.restart(step), simulation;
},
stop: function() {
return stepper.stop(), simulation;
},
nodes: function(_) {
return arguments.length ? (nodes = _, initializeNodes(), forces.each(initializeForce), simulation) : nodes;
},
alpha: function(_) {
return arguments.length ? (alpha = +_, simulation) : alpha;
},
alphaMin: function(_) {
return arguments.length ? (alphaMin = +_, simulation) : alphaMin;
},
alphaDecay: function(_) {
return arguments.length ? (alphaDecay = +_, simulation) : +alphaDecay;
},
alphaTarget: function(_) {
return arguments.length ? (alphaTarget = +_, simulation) : alphaTarget;
},
velocityDecay: function(_) {
return arguments.length ? (velocityDecay = 1 - _, simulation) : 1 - velocityDecay;
},
force: function(name, _) {
return arguments.length > 1 ? ((_ == null ? forces.remove(name) : forces.set(name, initializeForce(_))), simulation) : forces.get(name);
},
find: function(x, y, radius) {
var i = 0,
n = nodes.length,
dx,
dy,
d2,
node,
closest;
if (radius == null) radius = Infinity;
else radius *= radius;
for (i = 0; i < n; ++i) {
node = nodes[i];
dx = x - node.x;
dy = y - node.y;
d2 = dx * dx + dy * dy;
if (d2 < radius) closest = node, radius = d2;
}
return closest;
},
on: function(name, _) {
return arguments.length > 1 ? (event.on(name, _), simulation) : event.on(name);
}
};
};
var manyBody = function() {
var nodes,
node,
alpha,
strength = constant$6(-30),
strengths,
distanceMin2 = 1,
distanceMax2 = Infinity,
theta2 = 0.81;
function force(_) {
var i, n = nodes.length, tree = quadtree(nodes, x$1, y$1).visitAfter(accumulate);
for (alpha = _, i = 0; i < n; ++i) node = nodes[i], tree.visit(apply);
}
function initialize() {
if (!nodes) return;
var i, n = nodes.length, node;
strengths = new Array(n);
for (i = 0; i < n; ++i) node = nodes[i], strengths[node.index] = +strength(node, i, nodes);
}
function accumulate(quad) {
var strength = 0, q, c, x$$1, y$$1, i;
// For internal nodes, accumulate forces from child quadrants.
if (quad.length) {
for (x$$1 = y$$1 = i = 0; i < 4; ++i) {
if ((q = quad[i]) && (c = q.value)) {
strength += c, x$$1 += c * q.x, y$$1 += c * q.y;
}
}
quad.x = x$$1 / strength;
quad.y = y$$1 / strength;
}
// For leaf nodes, accumulate forces from coincident quadrants.
else {
q = quad;
q.x = q.data.x;
q.y = q.data.y;
do strength += strengths[q.data.index];
while (q = q.next);
}
quad.value = strength;
}
function apply(quad, x1, _, x2) {
if (!quad.value) return true;
var x$$1 = quad.x - node.x,
y$$1 = quad.y - node.y,
w = x2 - x1,
l = x$$1 * x$$1 + y$$1 * y$$1;
// Apply the Barnes-Hut approximation if possible.
// Limit forces for very close nodes; randomize direction if coincident.
if (w * w / theta2 < l) {
if (l < distanceMax2) {
if (x$$1 === 0) x$$1 = jiggle(), l += x$$1 * x$$1;
if (y$$1 === 0) y$$1 = jiggle(), l += y$$1 * y$$1;
if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);
node.vx += x$$1 * quad.value * alpha / l;
node.vy += y$$1 * quad.value * alpha / l;
}
return true;
}
// Otherwise, process points directly.
else if (quad.length || l >= distanceMax2) return;
// Limit forces for very close nodes; randomize direction if coincident.
if (quad.data !== node || quad.next) {
if (x$$1 === 0) x$$1 = jiggle(), l += x$$1 * x$$1;
if (y$$1 === 0) y$$1 = jiggle(), l += y$$1 * y$$1;
if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);
}
do if (quad.data !== node) {
w = strengths[quad.data.index] * alpha / l;
node.vx += x$$1 * w;
node.vy += y$$1 * w;
} while (quad = quad.next);
}
force.initialize = function(_) {
nodes = _;
initialize();
};
force.strength = function(_) {
return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : strength;
};
force.distanceMin = function(_) {
return arguments.length ? (distanceMin2 = _ * _, force) : Math.sqrt(distanceMin2);
};
force.distanceMax = function(_) {
return arguments.length ? (distanceMax2 = _ * _, force) : Math.sqrt(distanceMax2);
};
force.theta = function(_) {
return arguments.length ? (theta2 = _ * _, force) : Math.sqrt(theta2);
};
return force;
};
var x$2 = function(x) {
var strength = constant$6(0.1),
nodes,
strengths,
xz;
if (typeof x !== "function") x = constant$6(x == null ? 0 : +x);
function force(alpha) {
for (var i = 0, n = nodes.length, node; i < n; ++i) {
node = nodes[i], node.vx += (xz[i] - node.x) * strengths[i] * alpha;
}
}
function initialize() {
if (!nodes) return;
var i, n = nodes.length;
strengths = new Array(n);
xz = new Array(n);
for (i = 0; i < n; ++i) {
strengths[i] = isNaN(xz[i] = +x(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);
}
}
force.initialize = function(_) {
nodes = _;
initialize();
};
force.strength = function(_) {
return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : strength;
};
force.x = function(_) {
return arguments.length ? (x = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : x;
};
return force;
};
var y$2 = function(y) {
var strength = constant$6(0.1),
nodes,
strengths,
yz;
if (typeof y !== "function") y = constant$6(y == null ? 0 : +y);
function force(alpha) {
for (var i = 0, n = nodes.length, node; i < n; ++i) {
node = nodes[i], node.vy += (yz[i] - node.y) * strengths[i] * alpha;
}
}
function initialize() {
if (!nodes) return;
var i, n = nodes.length;
strengths = new Array(n);
yz = new Array(n);
for (i = 0; i < n; ++i) {
strengths[i] = isNaN(yz[i] = +y(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);
}
}
force.initialize = function(_) {
nodes = _;
initialize();
};
force.strength = function(_) {
return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : strength;
};
force.y = function(_) {
return arguments.length ? (y = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : y;
};
return force;
};
// Computes the decimal coefficient and exponent of the specified number x with
// significant digits p, where x is positive and p is in [1, 21] or undefined.
// For example, formatDecimal(1.23) returns ["123", 0].
var formatDecimal = function(x, p) {
if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity
var i, coefficient = x.slice(0, i);
// The string returned by toExponential either has the form \d\.\d+e[-+]\d+
// (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3).
return [
coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient,
+x.slice(i + 1)
];
};
var exponent$1 = function(x) {
return x = formatDecimal(Math.abs(x)), x ? x[1] : NaN;
};
var formatGroup = function(grouping, thousands) {
return function(value, width) {
var i = value.length,
t = [],
j = 0,
g = 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 = grouping[j = (j + 1) % grouping.length];
}
return t.reverse().join(thousands);
};
};
var formatNumerals = function(numerals) {
return function(value) {
return value.replace(/[0-9]/g, function(i) {
return numerals[+i];
});
};
};
var formatDefault = function(x, p) {
x = x.toPrecision(p);
out: for (var n = x.length, i = 1, i0 = -1, i1; i < n; ++i) {
switch (x[i]) {
case ".": i0 = i1 = i; break;
case "0": if (i0 === 0) i0 = i; i1 = i; break;
case "e": break out;
default: if (i0 > 0) i0 = 0; break;
}
}
return i0 > 0 ? x.slice(0, i0) + x.slice(i1 + 1) : x;
};
var prefixExponent;
var formatPrefixAuto = function(x, p) {
var d = formatDecimal(x, p);
if (!d) return x + "";
var coefficient = d[0],
exponent = d[1],
i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1,
n = coefficient.length;
return i === n ? coefficient
: i > n ? coefficient + new Array(i - n + 1).join("0")
: i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i)
: "0." + new Array(1 - i).join("0") + formatDecimal(x, Math.max(0, p + i - 1))[0]; // less than 1y!
};
var formatRounded = function(x, p) {
var d = formatDecimal(x, p);
if (!d) return x + "";
var coefficient = d[0],
exponent = d[1];
return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient
: coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1)
: coefficient + new Array(exponent - coefficient.length + 2).join("0");
};
var formatTypes = {
"": formatDefault,
"%": function(x, p) { return (x * 100).toFixed(p); },
"b": function(x) { return Math.round(x).toString(2); },
"c": function(x) { return x + ""; },
"d": function(x) { return Math.round(x).toString(10); },
"e": function(x, p) { return x.toExponential(p); },
"f": function(x, p) { return x.toFixed(p); },
"g": function(x, p) { return x.toPrecision(p); },
"o": function(x) { return Math.round(x).toString(8); },
"p": function(x, p) { return formatRounded(x * 100, p); },
"r": formatRounded,
"s": formatPrefixAuto,
"X": function(x) { return Math.round(x).toString(16).toUpperCase(); },
"x": function(x) { return Math.round(x).toString(16); }
};
// [[fill]align][sign][symbol][0][width][,][.precision][type]
var re = /^(?:(.)?([<>=^]))?([+\-\( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?([a-z%])?$/i;
function formatSpecifier(specifier) {
return new FormatSpecifier(specifier);
}
formatSpecifier.prototype = FormatSpecifier.prototype; // instanceof
function FormatSpecifier(specifier) {
if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier);
var match,
fill = match[1] || " ",
align = match[2] || ">",
sign = match[3] || "-",
symbol = match[4] || "",
zero = !!match[5],
width = match[6] && +match[6],
comma = !!match[7],
precision = match[8] && +match[8].slice(1),
type = match[9] || "";
// The "n" type is an alias for ",g".
if (type === "n") comma = true, type = "g";
// Map invalid types to the default format.
else if (!formatTypes[type]) type = "";
// If zero fill is specified, padding goes after sign and before digits.
if (zero || (fill === "0" && align === "=")) zero = true, fill = "0", align = "=";
this.fill = fill;
this.align = align;
this.sign = sign;
this.symbol = symbol;
this.zero = zero;
this.width = width;
this.comma = comma;
this.precision = precision;
this.type = type;
}
FormatSpecifier.prototype.toString = function() {
return this.fill
+ this.align
+ this.sign
+ this.symbol
+ (this.zero ? "0" : "")
+ (this.width == null ? "" : Math.max(1, this.width | 0))
+ (this.comma ? "," : "")
+ (this.precision == null ? "" : "." + Math.max(0, this.precision | 0))
+ this.type;
};
var identity$3 = function(x) {
return x;
};
var prefixes = ["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];
var formatLocale = function(locale) {
var group = locale.grouping && locale.thousands ? formatGroup(locale.grouping, locale.thousands) : identity$3,
currency = locale.currency,
decimal = locale.decimal,
numerals = locale.numerals ? formatNumerals(locale.numerals) : identity$3,
percent = locale.percent || "%";
function newFormat(specifier) {
specifier = formatSpecifier(specifier);
var fill = specifier.fill,
align = specifier.align,
sign = specifier.sign,
symbol = specifier.symbol,
zero = specifier.zero,
width = specifier.width,
comma = specifier.comma,
precision = specifier.precision,
type = specifier.type;
// Compute the prefix and suffix.
// For SI-prefix, the suffix is lazily computed.
var prefix = symbol === "$" ? currency[0] : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "",
suffix = symbol === "$" ? currency[1] : /[%p]/.test(type) ? percent : "";
// What format function should we use?
// Is this an integer type?
// Can this type generate exponential notation?
var formatType = formatTypes[type],
maybeSuffix = !type || /[defgprs%]/.test(type);
// Set the default precision if not specified,
// or clamp the specified precision to the supported range.
// For significant precision, it must be in [1, 21].
// For fixed precision, it must be in [0, 20].
precision = precision == null ? (type ? 6 : 12)
: /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision))
: Math.max(0, Math.min(20, precision));
function format(value) {
var valuePrefix = prefix,
valueSuffix = suffix,
i, n, c;
if (type === "c") {
valueSuffix = formatType(value) + valueSuffix;
value = "";
} else {
value = +value;
// Perform the initial formatting.
var valueNegative = value < 0;
value = formatType(Math.abs(value), precision);
// If a negative value rounds to zero during formatting, treat as positive.
if (valueNegative && +value === 0) valueNegative = false;
// Compute the prefix and suffix.
valuePrefix = (valueNegative ? (sign === "(" ? sign : "-") : sign === "-" || sign === "(" ? "" : sign) + valuePrefix;
valueSuffix = valueSuffix + (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + (valueNegative && sign === "(" ? ")" : "");
// Break the formatted value into the integer “value” part that can be
// grouped, and fractional or exponential “suffix” part that is not.
if (maybeSuffix) {
i = -1, n = value.length;
while (++i < n) {
if (c = value.charCodeAt(i), 48 > c || c > 57) {
valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix;
value = value.slice(0, i);
break;
}
}
}
}
// If the fill character is not "0", grouping is applied before padding.
if (comma && !zero) value = group(value, Infinity);
// Compute the padding.
var length = valuePrefix.length + value.length + valueSuffix.length,
padding = length < width ? new Array(width - length + 1).join(fill) : "";
// If the fill character is "0", grouping is applied after padding.
if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = "";
// Reconstruct the final output based on the desired alignment.
switch (align) {
case "<": value = valuePrefix + value + valueSuffix + padding; break;
case "=": value = valuePrefix + padding + value + valueSuffix; break;
case "^": value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); break;
default: value = padding + valuePrefix + value + valueSuffix; break;
}
return numerals(value);
}
format.toString = function() {
return specifier + "";
};
return format;
}
function formatPrefix(specifier, value) {
var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)),
e = Math.max(-8, Math.min(8, Math.floor(exponent$1(value) / 3))) * 3,
k = Math.pow(10, -e),
prefix = prefixes[8 + e / 3];
return function(value) {
return f(k * value) + prefix;
};
}
return {
format: newFormat,
formatPrefix: formatPrefix
};
};
var locale$1;
defaultLocale({
decimal: ".",
thousands: ",",
grouping: [3],
currency: ["$", ""]
});
function defaultLocale(definition) {
locale$1 = formatLocale(definition);
exports.format = locale$1.format;
exports.formatPrefix = locale$1.formatPrefix;
return locale$1;
}
var precisionFixed = function(step) {
return Math.max(0, -exponent$1(Math.abs(step)));
};
var precisionPrefix = function(step, value) {
return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent$1(value) / 3))) * 3 - exponent$1(Math.abs(step)));
};
var precisionRound = function(step, max) {
step = Math.abs(step), max = Math.abs(max) - step;
return Math.max(0, exponent$1(max) - exponent$1(step)) + 1;
};
// Adds floating point numbers with twice the normal precision.
// Reference: J. R. Shewchuk, Adaptive Precision Floating-Point Arithmetic and
// Fast Robust Geometric Predicates, Discrete & Computational Geometry 18(3)
// 305–363 (1997).
// Code adapted from GeographicLib by Charles F. F. Karney,
// http://geographiclib.sourceforge.net/
var adder = function() {
return new Adder;
};
function Adder() {
this.reset();
}
Adder.prototype = {
constructor: Adder,
reset: function() {
this.s = // rounded value
this.t = 0; // exact error
},
add: function(y) {
add$1(temp, y, this.t);
add$1(this, temp.s, this.s);
if (this.s) this.t += temp.t;
else this.s = temp.t;
},
valueOf: function() {
return this.s;
}
};
var temp = new Adder;
function add$1(adder, a, b) {
var x = adder.s = a + b,
bv = x - a,
av = x - bv;
adder.t = (a - av) + (b - bv);
}
var epsilon$2 = 1e-6;
var epsilon2$1 = 1e-12;
var pi$3 = Math.PI;
var halfPi$2 = pi$3 / 2;
var quarterPi = pi$3 / 4;
var tau$3 = pi$3 * 2;
var degrees$1 = 180 / pi$3;
var radians = pi$3 / 180;
var abs = Math.abs;
var atan = Math.atan;
var atan2 = Math.atan2;
var cos$1 = Math.cos;
var ceil = Math.ceil;
var exp = Math.exp;
var log = Math.log;
var pow = Math.pow;
var sin$1 = Math.sin;
var sign = Math.sign || function(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; };
var sqrt = Math.sqrt;
var tan = Math.tan;
function acos(x) {
return x > 1 ? 0 : x < -1 ? pi$3 : Math.acos(x);
}
function asin(x) {
return x > 1 ? halfPi$2 : x < -1 ? -halfPi$2 : Math.asin(x);
}
function haversin(x) {
return (x = sin$1(x / 2)) * x;
}
function noop$1() {}
function streamGeometry(geometry, stream) {
if (geometry && streamGeometryType.hasOwnProperty(geometry.type)) {
streamGeometryType[geometry.type](geometry, stream);
}
}
var streamObjectType = {
Feature: function(object, stream) {
streamGeometry(object.geometry, stream);
},
FeatureCollection: function(object, stream) {
var features = object.features, i = -1, n = features.length;
while (++i < n) streamGeometry(features[i].geometry, stream);
}
};
var streamGeometryType = {
Sphere: function(object, stream) {
stream.sphere();
},
Point: function(object, stream) {
object = object.coordinates;
stream.point(object[0], object[1], object[2]);
},
MultiPoint: function(object, stream) {
var coordinates = object.coordinates, i = -1, n = coordinates.length;
while (++i < n) object = coordinates[i], stream.point(object[0], object[1], object[2]);
},
LineString: function(object, stream) {
streamLine(object.coordinates, stream, 0);
},
MultiLineString: function(object, stream) {
var coordinates = object.coordinates, i = -1, n = coordinates.length;
while (++i < n) streamLine(coordinates[i], stream, 0);
},
Polygon: function(object, stream) {
streamPolygon(object.coordinates, stream);
},
MultiPolygon: function(object, stream) {
var coordinates = object.coordinates, i = -1, n = coordinates.length;
while (++i < n) streamPolygon(coordinates[i], stream);
},
GeometryCollection: function(object, stream) {
var geometries = object.geometries, i = -1, n = geometries.length;
while (++i < n) streamGeometry(geometries[i], stream);
}
};
function streamLine(coordinates, stream, closed) {
var i = -1, n = coordinates.length - closed, coordinate;
stream.lineStart();
while (++i < n) coordinate = coordinates[i], stream.point(coordinate[0], coordinate[1], coordinate[2]);
stream.lineEnd();
}
function streamPolygon(coordinates, stream) {
var i = -1, n = coordinates.length;
stream.polygonStart();
while (++i < n) streamLine(coordinates[i], stream, 1);
stream.polygonEnd();
}
var geoStream = function(object, stream) {
if (object && streamObjectType.hasOwnProperty(object.type)) {
streamObjectType[object.type](object, stream);
} else {
streamGeometry(object, stream);
}
};
var areaRingSum = adder();
var areaSum = adder();
var lambda00;
var phi00;
var lambda0;
var cosPhi0;
var sinPhi0;
var areaStream = {
point: noop$1,
lineStart: noop$1,
lineEnd: noop$1,
polygonStart: function() {
areaRingSum.reset();
areaStream.lineStart = areaRingStart;
areaStream.lineEnd = areaRingEnd;
},
polygonEnd: function() {
var areaRing = +areaRingSum;
areaSum.add(areaRing < 0 ? tau$3 + areaRing : areaRing);
this.lineStart = this.lineEnd = this.point = noop$1;
},
sphere: function() {
areaSum.add(tau$3);
}
};
function areaRingStart() {
areaStream.point = areaPointFirst;
}
function areaRingEnd() {
areaPoint(lambda00, phi00);
}
function areaPointFirst(lambda, phi) {
areaStream.point = areaPoint;
lambda00 = lambda, phi00 = phi;
lambda *= radians, phi *= radians;
lambda0 = lambda, cosPhi0 = cos$1(phi = phi / 2 + quarterPi), sinPhi0 = sin$1(phi);
}
function areaPoint(lambda, phi) {
lambda *= radians, phi *= radians;
phi = phi / 2 + quarterPi; // half the angular distance from south pole
// Spherical excess E for a spherical triangle with vertices: south pole,
// previous point, current point. Uses a formula derived from Cagnoli’s
// theorem. See Todhunter, Spherical Trig. (1871), Sec. 103, Eq. (2).
var dLambda = lambda - lambda0,
sdLambda = dLambda >= 0 ? 1 : -1,
adLambda = sdLambda * dLambda,
cosPhi = cos$1(phi),
sinPhi = sin$1(phi),
k = sinPhi0 * sinPhi,
u = cosPhi0 * cosPhi + k * cos$1(adLambda),
v = k * sdLambda * sin$1(adLambda);
areaRingSum.add(atan2(v, u));
// Advance the previous points.
lambda0 = lambda, cosPhi0 = cosPhi, sinPhi0 = sinPhi;
}
var area = function(object) {
areaSum.reset();
geoStream(object, areaStream);
return areaSum * 2;
};
function spherical(cartesian) {
return [atan2(cartesian[1], cartesian[0]), asin(cartesian[2])];
}
function cartesian(spherical) {
var lambda = spherical[0], phi = spherical[1], cosPhi = cos$1(phi);
return [cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi)];
}
function cartesianDot(a, b) {
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
}
function 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]];
}
// TODO return a
function cartesianAddInPlace(a, b) {
a[0] += b[0], a[1] += b[1], a[2] += b[2];
}
function cartesianScale(vector, k) {
return [vector[0] * k, vector[1] * k, vector[2] * k];
}
// TODO return d
function cartesianNormalizeInPlace(d) {
var l = sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
d[0] /= l, d[1] /= l, d[2] /= l;
}
var lambda0$1;
var phi0;
var lambda1;
var phi1;
var lambda2;
var lambda00$1;
var phi00$1;
var p0;
var deltaSum = adder();
var ranges;
var range;
var boundsStream = {
point: boundsPoint,
lineStart: boundsLineStart,
lineEnd: boundsLineEnd,
polygonStart: function() {
boundsStream.point = boundsRingPoint;
boundsStream.lineStart = boundsRingStart;
boundsStream.lineEnd = boundsRingEnd;
deltaSum.reset();
areaStream.polygonStart();
},
polygonEnd: function() {
areaStream.polygonEnd();
boundsStream.point = boundsPoint;
boundsStream.lineStart = boundsLineStart;
boundsStream.lineEnd = boundsLineEnd;
if (areaRingSum < 0) lambda0$1 = -(lambda1 = 180), phi0 = -(phi1 = 90);
else if (deltaSum > epsilon$2) phi1 = 90;
else if (deltaSum < -epsilon$2) phi0 = -90;
range[0] = lambda0$1, range[1] = lambda1;
}
};
function boundsPoint(lambda, phi) {
ranges.push(range = [lambda0$1 = lambda, lambda1 = lambda]);
if (phi < phi0) phi0 = phi;
if (phi > phi1) phi1 = phi;
}
function linePoint(lambda, phi) {
var p = cartesian([lambda * radians, phi * radians]);
if (p0) {
var normal = cartesianCross(p0, p),
equatorial = [normal[1], -normal[0], 0],
inflection = cartesianCross(equatorial, normal);
cartesianNormalizeInPlace(inflection);
inflection = spherical(inflection);
var delta = lambda - lambda2,
sign$$1 = delta > 0 ? 1 : -1,
lambdai = inflection[0] * degrees$1 * sign$$1,
phii,
antimeridian = abs(delta) > 180;
if (antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) {
phii = inflection[1] * degrees$1;
if (phii > phi1) phi1 = phii;
} else if (lambdai = (lambdai + 360) % 360 - 180, antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) {
phii = -inflection[1] * degrees$1;
if (phii < phi0) phi0 = phii;
} else {
if (phi < phi0) phi0 = phi;
if (phi > phi1) phi1 = phi;
}
if (antimeridian) {
if (lambda < lambda2) {
if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda;
} else {
if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda;
}
} else {
if (lambda1 >= lambda0$1) {
if (lambda < lambda0$1) lambda0$1 = lambda;
if (lambda > lambda1) lambda1 = lambda;
} else {
if (lambda > lambda2) {
if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda;
} else {
if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda;
}
}
}
} else {
ranges.push(range = [lambda0$1 = lambda, lambda1 = lambda]);
}
if (phi < phi0) phi0 = phi;
if (phi > phi1) phi1 = phi;
p0 = p, lambda2 = lambda;
}
function boundsLineStart() {
boundsStream.point = linePoint;
}
function boundsLineEnd() {
range[0] = lambda0$1, range[1] = lambda1;
boundsStream.point = boundsPoint;
p0 = null;
}
function boundsRingPoint(lambda, phi) {
if (p0) {
var delta = lambda - lambda2;
deltaSum.add(abs(delta) > 180 ? delta + (delta > 0 ? 360 : -360) : delta);
} else {
lambda00$1 = lambda, phi00$1 = phi;
}
areaStream.point(lambda, phi);
linePoint(lambda, phi);
}
function boundsRingStart() {
areaStream.lineStart();
}
function boundsRingEnd() {
boundsRingPoint(lambda00$1, phi00$1);
areaStream.lineEnd();
if (abs(deltaSum) > epsilon$2) lambda0$1 = -(lambda1 = 180);
range[0] = lambda0$1, range[1] = lambda1;
p0 = null;
}
// Finds the left-right distance between two longitudes.
// This is almost the same as (lambda1 - lambda0 + 360°) % 360°, except that we want
// the distance between ±180° to be 360°.
function angle(lambda0, lambda1) {
return (lambda1 -= lambda0) < 0 ? lambda1 + 360 : lambda1;
}
function rangeCompare(a, b) {
return a[0] - b[0];
}
function rangeContains(range, x) {
return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x;
}
var bounds = function(feature) {
var i, n, a, b, merged, deltaMax, delta;
phi1 = lambda1 = -(lambda0$1 = phi0 = Infinity);
ranges = [];
geoStream(feature, boundsStream);
// First, sort ranges by their minimum longitudes.
if (n = ranges.length) {
ranges.sort(rangeCompare);
// Then, merge any ranges that overlap.
for (i = 1, a = ranges[0], merged = [a]; i < n; ++i) {
b = ranges[i];
if (rangeContains(a, b[0]) || rangeContains(a, b[1])) {
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);
}
}
// Finally, find the largest gap between the merged ranges.
// The final bounding box will be the inverse of this gap.
for (deltaMax = -Infinity, n = merged.length - 1, i = 0, a = merged[n]; i <= n; a = b, ++i) {
b = merged[i];
if ((delta = angle(a[1], b[0])) > deltaMax) deltaMax = delta, lambda0$1 = b[0], lambda1 = a[1];
}
}
ranges = range = null;
return lambda0$1 === Infinity || phi0 === Infinity
? [[NaN, NaN], [NaN, NaN]]
: [[lambda0$1, phi0], [lambda1, phi1]];
};
var W0;
var W1;
var X0;
var Y0;
var Z0;
var X1;
var Y1;
var Z1;
var X2;
var Y2;
var Z2;
var lambda00$2;
var phi00$2;
var x0;
var y0;
var z0; // previous point
var centroidStream = {
sphere: noop$1,
point: centroidPoint,
lineStart: centroidLineStart,
lineEnd: centroidLineEnd,
polygonStart: function() {
centroidStream.lineStart = centroidRingStart;
centroidStream.lineEnd = centroidRingEnd;
},
polygonEnd: function() {
centroidStream.lineStart = centroidLineStart;
centroidStream.lineEnd = centroidLineEnd;
}
};
// Arithmetic mean of Cartesian vectors.
function centroidPoint(lambda, phi) {
lambda *= radians, phi *= radians;
var cosPhi = cos$1(phi);
centroidPointCartesian(cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi));
}
function centroidPointCartesian(x, y, z) {
++W0;
X0 += (x - X0) / W0;
Y0 += (y - Y0) / W0;
Z0 += (z - Z0) / W0;
}
function centroidLineStart() {
centroidStream.point = centroidLinePointFirst;
}
function centroidLinePointFirst(lambda, phi) {
lambda *= radians, phi *= radians;
var cosPhi = cos$1(phi);
x0 = cosPhi * cos$1(lambda);
y0 = cosPhi * sin$1(lambda);
z0 = sin$1(phi);
centroidStream.point = centroidLinePoint;
centroidPointCartesian(x0, y0, z0);
}
function centroidLinePoint(lambda, phi) {
lambda *= radians, phi *= radians;
var cosPhi = cos$1(phi),
x = cosPhi * cos$1(lambda),
y = cosPhi * sin$1(lambda),
z = sin$1(phi),
w = atan2(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);
W1 += w;
X1 += w * (x0 + (x0 = x));
Y1 += w * (y0 + (y0 = y));
Z1 += w * (z0 + (z0 = z));
centroidPointCartesian(x0, y0, z0);
}
function centroidLineEnd() {
centroidStream.point = centroidPoint;
}
// See J. E. Brock, The Inertia Tensor for a Spherical Triangle,
// J. Applied Mechanics 42, 239 (1975).
function centroidRingStart() {
centroidStream.point = centroidRingPointFirst;
}
function centroidRingEnd() {
centroidRingPoint(lambda00$2, phi00$2);
centroidStream.point = centroidPoint;
}
function centroidRingPointFirst(lambda, phi) {
lambda00$2 = lambda, phi00$2 = phi;
lambda *= radians, phi *= radians;
centroidStream.point = centroidRingPoint;
var cosPhi = cos$1(phi);
x0 = cosPhi * cos$1(lambda);
y0 = cosPhi * sin$1(lambda);
z0 = sin$1(phi);
centroidPointCartesian(x0, y0, z0);
}
function centroidRingPoint(lambda, phi) {
lambda *= radians, phi *= radians;
var cosPhi = cos$1(phi),
x = cosPhi * cos$1(lambda),
y = cosPhi * sin$1(lambda),
z = sin$1(phi),
cx = y0 * z - z0 * y,
cy = z0 * x - x0 * z,
cz = x0 * y - y0 * x,
m = sqrt(cx * cx + cy * cy + cz * cz),
w = asin(m), // line weight = angle
v = m && -w / m; // area weight multiplier
X2 += v * cx;
Y2 += v * cy;
Z2 += v * cz;
W1 += w;
X1 += w * (x0 + (x0 = x));
Y1 += w * (y0 + (y0 = y));
Z1 += w * (z0 + (z0 = z));
centroidPointCartesian(x0, y0, z0);
}
var centroid = function(object) {
W0 = W1 =
X0 = Y0 = Z0 =
X1 = Y1 = Z1 =
X2 = Y2 = Z2 = 0;
geoStream(object, centroidStream);
var x = X2,
y = Y2,
z = Z2,
m = x * x + y * y + z * z;
// If the area-weighted ccentroid is undefined, fall back to length-weighted ccentroid.
if (m < epsilon2$1) {
x = X1, y = Y1, z = Z1;
// If the feature has zero length, fall back to arithmetic mean of point vectors.
if (W1 < epsilon$2) x = X0, y = Y0, z = Z0;
m = x * x + y * y + z * z;
// If the feature still has an undefined ccentroid, then return.
if (m < epsilon2$1) return [NaN, NaN];
}
return [atan2(y, x) * degrees$1, asin(z / sqrt(m)) * degrees$1];
};
var constant$7 = function(x) {
return function() {
return x;
};
};
var compose = function(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 rotationIdentity(lambda, phi) {
return [lambda > pi$3 ? lambda - tau$3 : lambda < -pi$3 ? lambda + tau$3 : lambda, phi];
}
rotationIdentity.invert = rotationIdentity;
function rotateRadians(deltaLambda, deltaPhi, deltaGamma) {
return (deltaLambda %= tau$3) ? (deltaPhi || deltaGamma ? compose(rotationLambda(deltaLambda), rotationPhiGamma(deltaPhi, deltaGamma))
: rotationLambda(deltaLambda))
: (deltaPhi || deltaGamma ? rotationPhiGamma(deltaPhi, deltaGamma)
: rotationIdentity);
}
function forwardRotationLambda(deltaLambda) {
return function(lambda, phi) {
return lambda += deltaLambda, [lambda > pi$3 ? lambda - tau$3 : lambda < -pi$3 ? lambda + tau$3 : lambda, phi];
};
}
function rotationLambda(deltaLambda) {
var rotation = forwardRotationLambda(deltaLambda);
rotation.invert = forwardRotationLambda(-deltaLambda);
return rotation;
}
function rotationPhiGamma(deltaPhi, deltaGamma) {
var cosDeltaPhi = cos$1(deltaPhi),
sinDeltaPhi = sin$1(deltaPhi),
cosDeltaGamma = cos$1(deltaGamma),
sinDeltaGamma = sin$1(deltaGamma);
function rotation(lambda, phi) {
var cosPhi = cos$1(phi),
x = cos$1(lambda) * cosPhi,
y = sin$1(lambda) * cosPhi,
z = sin$1(phi),
k = z * cosDeltaPhi + x * sinDeltaPhi;
return [
atan2(y * cosDeltaGamma - k * sinDeltaGamma, x * cosDeltaPhi - z * sinDeltaPhi),
asin(k * cosDeltaGamma + y * sinDeltaGamma)
];
}
rotation.invert = function(lambda, phi) {
var cosPhi = cos$1(phi),
x = cos$1(lambda) * cosPhi,
y = sin$1(lambda) * cosPhi,
z = sin$1(phi),
k = z * cosDeltaGamma - y * sinDeltaGamma;
return [
atan2(y * cosDeltaGamma + z * sinDeltaGamma, x * cosDeltaPhi + k * sinDeltaPhi),
asin(k * cosDeltaPhi - x * sinDeltaPhi)
];
};
return rotation;
}
var rotation = function(rotate) {
rotate = rotateRadians(rotate[0] * radians, rotate[1] * radians, rotate.length > 2 ? rotate[2] * radians : 0);
function forward(coordinates) {
coordinates = rotate(coordinates[0] * radians, coordinates[1] * radians);
return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates;
}
forward.invert = function(coordinates) {
coordinates = rotate.invert(coordinates[0] * radians, coordinates[1] * radians);
return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates;
};
return forward;
};
// Generates a circle centered at [0°, 0°], with a given radius and precision.
function circleStream(stream, radius, delta, direction, t0, t1) {
if (!delta) return;
var cosRadius = cos$1(radius),
sinRadius = sin$1(radius),
step = direction * delta;
if (t0 == null) {
t0 = radius + direction * tau$3;
t1 = radius - step / 2;
} else {
t0 = circleRadius(cosRadius, t0);
t1 = circleRadius(cosRadius, t1);
if (direction > 0 ? t0 < t1 : t0 > t1) t0 += direction * tau$3;
}
for (var point, t = t0; direction > 0 ? t > t1 : t < t1; t -= step) {
point = spherical([cosRadius, -sinRadius * cos$1(t), -sinRadius * sin$1(t)]);
stream.point(point[0], point[1]);
}
}
// Returns the signed angle of a cartesian point relative to [cosRadius, 0, 0].
function circleRadius(cosRadius, point) {
point = cartesian(point), point[0] -= cosRadius;
cartesianNormalizeInPlace(point);
var radius = acos(-point[1]);
return ((-point[2] < 0 ? -radius : radius) + tau$3 - epsilon$2) % tau$3;
}
var circle = function() {
var center = constant$7([0, 0]),
radius = constant$7(90),
precision = constant$7(6),
ring,
rotate,
stream = {point: point};
function point(x, y) {
ring.push(x = rotate(x, y));
x[0] *= degrees$1, x[1] *= degrees$1;
}
function circle() {
var c = center.apply(this, arguments),
r = radius.apply(this, arguments) * radians,
p = precision.apply(this, arguments) * radians;
ring = [];
rotate = rotateRadians(-c[0] * radians, -c[1] * radians, 0).invert;
circleStream(stream, r, p, 1);
c = {type: "Polygon", coordinates: [ring]};
ring = rotate = null;
return c;
}
circle.center = function(_) {
return arguments.length ? (center = typeof _ === "function" ? _ : constant$7([+_[0], +_[1]]), circle) : center;
};
circle.radius = function(_) {
return arguments.length ? (radius = typeof _ === "function" ? _ : constant$7(+_), circle) : radius;
};
circle.precision = function(_) {
return arguments.length ? (precision = typeof _ === "function" ? _ : constant$7(+_), circle) : precision;
};
return circle;
};
var clipBuffer = function() {
var lines = [],
line;
return {
point: function(x, y) {
line.push([x, y]);
},
lineStart: function() {
lines.push(line = []);
},
lineEnd: noop$1,
rejoin: function() {
if (lines.length > 1) lines.push(lines.pop().concat(lines.shift()));
},
result: function() {
var result = lines;
lines = [];
line = null;
return result;
}
};
};
var clipLine = function(a, b, x0, y0, x1, y1) {
var ax = a[0],
ay = a[1],
bx = b[0],
by = b[1],
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) a[0] = ax + t0 * dx, a[1] = ay + t0 * dy;
if (t1 < 1) b[0] = ax + t1 * dx, b[1] = ay + t1 * dy;
return true;
};
var pointEqual = function(a, b) {
return abs(a[0] - b[0]) < epsilon$2 && abs(a[1] - b[1]) < epsilon$2;
};
function Intersection(point, points, other, entry) {
this.x = point;
this.z = points;
this.o = other; // another intersection
this.e = entry; // is an entry?
this.v = false; // visited
this.n = this.p = null; // next & previous
}
// A generalized polygon clipping algorithm: given a polygon that has been cut
// into its visible line segments, and rejoins the segments by interpolating
// along the clip edge.
var clipPolygon = function(segments, compareIntersection, startInside, interpolate, stream) {
var subject = [],
clip = [],
i,
n;
segments.forEach(function(segment) {
if ((n = segment.length - 1) <= 0) return;
var n, p0 = segment[0], p1 = segment[n], x;
// If the first and last points of a segment are coincident, then treat as a
// closed ring. TODO if all rings are closed, then the winding order of the
// exterior ring should be checked.
if (pointEqual(p0, p1)) {
stream.lineStart();
for (i = 0; i < n; ++i) stream.point((p0 = segment[i])[0], p0[1]);
stream.lineEnd();
return;
}
subject.push(x = new Intersection(p0, segment, null, true));
clip.push(x.o = new Intersection(p0, null, x, false));
subject.push(x = new Intersection(p1, segment, null, false));
clip.push(x.o = new Intersection(p1, null, x, true));
});
if (!subject.length) return;
clip.sort(compareIntersection);
link$1(subject);
link$1(clip);
for (i = 0, n = clip.length; i < n; ++i) {
clip[i].e = startInside = !startInside;
}
var start = subject[0],
points,
point;
while (1) {
// Find first unvisited intersection.
var current = start,
isSubject = true;
while (current.v) if ((current = current.n) === start) return;
points = current.z;
stream.lineStart();
do {
current.v = current.o.v = true;
if (current.e) {
if (isSubject) {
for (i = 0, n = points.length; i < n; ++i) stream.point((point = points[i])[0], point[1]);
} else {
interpolate(current.x, current.n.x, 1, stream);
}
current = current.n;
} else {
if (isSubject) {
points = current.p.z;
for (i = points.length - 1; i >= 0; --i) stream.point((point = points[i])[0], point[1]);
} else {
interpolate(current.x, current.p.x, -1, stream);
}
current = current.p;
}
current = current.o;
points = current.z;
isSubject = !isSubject;
} while (!current.v);
stream.lineEnd();
}
};
function link$1(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;
}
var clipMax = 1e9;
var clipMin = -clipMax;
// TODO Use d3-polygon’s polygonContains here for the ring check?
// TODO Eliminate duplicate buffering in clipBuffer and polygon.push?
function clipExtent(x0, y0, x1, y1) {
function visible(x, y) {
return x0 <= x && x <= x1 && y0 <= y && y <= y1;
}
function interpolate(from, to, direction, stream) {
var a = 0, a1 = 0;
if (from == null
|| (a = corner(from, direction)) !== (a1 = corner(to, direction))
|| comparePoint(from, to) < 0 ^ direction > 0) {
do stream.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0);
while ((a = (a + direction + 4) % 4) !== a1);
} else {
stream.point(to[0], to[1]);
}
}
function corner(p, direction) {
return abs(p[0] - x0) < epsilon$2 ? direction > 0 ? 0 : 3
: abs(p[0] - x1) < epsilon$2 ? direction > 0 ? 2 : 1
: abs(p[1] - y0) < epsilon$2 ? direction > 0 ? 1 : 0
: direction > 0 ? 3 : 2; // abs(p[1] - y1) < epsilon
}
function compareIntersection(a, b) {
return comparePoint(a.x, b.x);
}
function comparePoint(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];
}
return function(stream) {
var activeStream = stream,
bufferStream = clipBuffer(),
segments,
polygon,
ring,
x__, y__, v__, // first point
x_, y_, v_, // previous point
first,
clean;
var clipStream = {
point: point,
lineStart: lineStart,
lineEnd: lineEnd,
polygonStart: polygonStart,
polygonEnd: polygonEnd
};
function point(x, y) {
if (visible(x, y)) activeStream.point(x, y);
}
function polygonInside() {
var winding = 0;
for (var i = 0, n = polygon.length; i < n; ++i) {
for (var ring = polygon[i], j = 1, m = ring.length, point = ring[0], a0, a1, b0 = point[0], b1 = point[1]; j < m; ++j) {
a0 = b0, a1 = b1, point = ring[j], b0 = point[0], b1 = point[1];
if (a1 <= y1) { if (b1 > y1 && (b0 - a0) * (y1 - a1) > (b1 - a1) * (x0 - a0)) ++winding; }
else { if (b1 <= y1 && (b0 - a0) * (y1 - a1) < (b1 - a1) * (x0 - a0)) --winding; }
}
}
return winding;
}
// Buffer geometry within a polygon and then clip it en masse.
function polygonStart() {
activeStream = bufferStream, segments = [], polygon = [], clean = true;
}
function polygonEnd() {
var startInside = polygonInside(),
cleanInside = clean && startInside,
visible = (segments = merge(segments)).length;
if (cleanInside || visible) {
stream.polygonStart();
if (cleanInside) {
stream.lineStart();
interpolate(null, null, 1, stream);
stream.lineEnd();
}
if (visible) {
clipPolygon(segments, compareIntersection, startInside, interpolate, stream);
}
stream.polygonEnd();
}
activeStream = stream, segments = polygon = ring = null;
}
function lineStart() {
clipStream.point = linePoint;
if (polygon) polygon.push(ring = []);
first = true;
v_ = false;
x_ = y_ = NaN;
}
// TODO rather than special-case polygons, simply handle them separately.
// Ideally, coincident intersection points should be jittered to avoid
// clipping issues.
function lineEnd() {
if (segments) {
linePoint(x__, y__);
if (v__ && v_) bufferStream.rejoin();
segments.push(bufferStream.result());
}
clipStream.point = point;
if (v_) activeStream.lineEnd();
}
function linePoint(x, y) {
var v = visible(x, y);
if (polygon) ring.push([x, y]);
if (first) {
x__ = x, y__ = y, v__ = v;
first = false;
if (v) {
activeStream.lineStart();
activeStream.point(x, y);
}
} else {
if (v && v_) activeStream.point(x, y);
else {
var a = [x_ = Math.max(clipMin, Math.min(clipMax, x_)), y_ = Math.max(clipMin, Math.min(clipMax, y_))],
b = [x = Math.max(clipMin, Math.min(clipMax, x)), y = Math.max(clipMin, Math.min(clipMax, y))];
if (clipLine(a, b, x0, y0, x1, y1)) {
if (!v_) {
activeStream.lineStart();
activeStream.point(a[0], a[1]);
}
activeStream.point(b[0], b[1]);
if (!v) activeStream.lineEnd();
clean = false;
} else if (v) {
activeStream.lineStart();
activeStream.point(x, y);
clean = false;
}
}
}
x_ = x, y_ = y, v_ = v;
}
return clipStream;
};
}
var extent$1 = function() {
var x0 = 0,
y0 = 0,
x1 = 960,
y1 = 500,
cache,
cacheStream,
clip;
return clip = {
stream: function(stream) {
return cache && cacheStream === stream ? cache : cache = clipExtent(x0, y0, x1, y1)(cacheStream = stream);
},
extent: function(_) {
return arguments.length ? (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1], cache = cacheStream = null, clip) : [[x0, y0], [x1, y1]];
}
};
};
var sum$1 = adder();
var polygonContains = function(polygon, point) {
var lambda = point[0],
phi = point[1],
normal = [sin$1(lambda), -cos$1(lambda), 0],
angle = 0,
winding = 0;
sum$1.reset();
for (var i = 0, n = polygon.length; i < n; ++i) {
if (!(m = (ring = polygon[i]).length)) continue;
var ring,
m,
point0 = ring[m - 1],
lambda0 = point0[0],
phi0 = point0[1] / 2 + quarterPi,
sinPhi0 = sin$1(phi0),
cosPhi0 = cos$1(phi0);
for (var j = 0; j < m; ++j, lambda0 = lambda1, sinPhi0 = sinPhi1, cosPhi0 = cosPhi1, point0 = point1) {
var point1 = ring[j],
lambda1 = point1[0],
phi1 = point1[1] / 2 + quarterPi,
sinPhi1 = sin$1(phi1),
cosPhi1 = cos$1(phi1),
delta = lambda1 - lambda0,
sign$$1 = delta >= 0 ? 1 : -1,
absDelta = sign$$1 * delta,
antimeridian = absDelta > pi$3,
k = sinPhi0 * sinPhi1;
sum$1.add(atan2(k * sign$$1 * sin$1(absDelta), cosPhi0 * cosPhi1 + k * cos$1(absDelta)));
angle += antimeridian ? delta + sign$$1 * tau$3 : delta;
// Are the longitudes either side of the point’s meridian (lambda),
// and are the latitudes smaller than the parallel (phi)?
if (antimeridian ^ lambda0 >= lambda ^ lambda1 >= lambda) {
var arc = cartesianCross(cartesian(point0), cartesian(point1));
cartesianNormalizeInPlace(arc);
var intersection = cartesianCross(normal, arc);
cartesianNormalizeInPlace(intersection);
var phiArc = (antimeridian ^ delta >= 0 ? -1 : 1) * asin(intersection[2]);
if (phi > phiArc || phi === phiArc && (arc[0] || arc[1])) {
winding += antimeridian ^ delta >= 0 ? 1 : -1;
}
}
}
}
// First, determine whether the South pole is inside or outside:
//
// It is inside if:
// * the polygon winds around it in a clockwise direction.
// * the polygon does not (cumulatively) wind around it, but has a negative
// (counter-clockwise) area.
//
// Second, count the (signed) number of times a segment crosses a lambda
// from the point to the South pole. If it is zero, then the point is the
// same side as the South pole.
return (angle < -epsilon$2 || angle < epsilon$2 && sum$1 < -epsilon$2) ^ (winding & 1);
};
var lengthSum = adder();
var lambda0$2;
var sinPhi0$1;
var cosPhi0$1;
var lengthStream = {
sphere: noop$1,
point: noop$1,
lineStart: lengthLineStart,
lineEnd: noop$1,
polygonStart: noop$1,
polygonEnd: noop$1
};
function lengthLineStart() {
lengthStream.point = lengthPointFirst;
lengthStream.lineEnd = lengthLineEnd;
}
function lengthLineEnd() {
lengthStream.point = lengthStream.lineEnd = noop$1;
}
function lengthPointFirst(lambda, phi) {
lambda *= radians, phi *= radians;
lambda0$2 = lambda, sinPhi0$1 = sin$1(phi), cosPhi0$1 = cos$1(phi);
lengthStream.point = lengthPoint;
}
function lengthPoint(lambda, phi) {
lambda *= radians, phi *= radians;
var sinPhi = sin$1(phi),
cosPhi = cos$1(phi),
delta = abs(lambda - lambda0$2),
cosDelta = cos$1(delta),
sinDelta = sin$1(delta),
x = cosPhi * sinDelta,
y = cosPhi0$1 * sinPhi - sinPhi0$1 * cosPhi * cosDelta,
z = sinPhi0$1 * sinPhi + cosPhi0$1 * cosPhi * cosDelta;
lengthSum.add(atan2(sqrt(x * x + y * y), z));
lambda0$2 = lambda, sinPhi0$1 = sinPhi, cosPhi0$1 = cosPhi;
}
var length$1 = function(object) {
lengthSum.reset();
geoStream(object, lengthStream);
return +lengthSum;
};
var coordinates = [null, null];
var object$1 = {type: "LineString", coordinates: coordinates};
var distance = function(a, b) {
coordinates[0] = a;
coordinates[1] = b;
return length$1(object$1);
};
var containsObjectType = {
Feature: function(object, point) {
return containsGeometry(object.geometry, point);
},
FeatureCollection: function(object, point) {
var features = object.features, i = -1, n = features.length;
while (++i < n) if (containsGeometry(features[i].geometry, point)) return true;
return false;
}
};
var containsGeometryType = {
Sphere: function() {
return true;
},
Point: function(object, point) {
return containsPoint(object.coordinates, point);
},
MultiPoint: function(object, point) {
var coordinates = object.coordinates, i = -1, n = coordinates.length;
while (++i < n) if (containsPoint(coordinates[i], point)) return true;
return false;
},
LineString: function(object, point) {
return containsLine(object.coordinates, point);
},
MultiLineString: function(object, point) {
var coordinates = object.coordinates, i = -1, n = coordinates.length;
while (++i < n) if (containsLine(coordinates[i], point)) return true;
return false;
},
Polygon: function(object, point) {
return containsPolygon(object.coordinates, point);
},
MultiPolygon: function(object, point) {
var coordinates = object.coordinates, i = -1, n = coordinates.length;
while (++i < n) if (containsPolygon(coordinates[i], point)) return true;
return false;
},
GeometryCollection: function(object, point) {
var geometries = object.geometries, i = -1, n = geometries.length;
while (++i < n) if (containsGeometry(geometries[i], point)) return true;
return false;
}
};
function containsGeometry(geometry, point) {
return geometry && containsGeometryType.hasOwnProperty(geometry.type)
? containsGeometryType[geometry.type](geometry, point)
: false;
}
function containsPoint(coordinates, point) {
return distance(coordinates, point) === 0;
}
function containsLine(coordinates, point) {
var ab = distance(coordinates[0], coordinates[1]),
ao = distance(coordinates[0], point),
ob = distance(point, coordinates[1]);
return ao + ob <= ab + epsilon$2;
}
function containsPolygon(coordinates, point) {
return !!polygonContains(coordinates.map(ringRadians), pointRadians(point));
}
function ringRadians(ring) {
return ring = ring.map(pointRadians), ring.pop(), ring;
}
function pointRadians(point) {
return [point[0] * radians, point[1] * radians];
}
var contains = function(object, point) {
return (object && containsObjectType.hasOwnProperty(object.type)
? containsObjectType[object.type]
: containsGeometry)(object, point);
};
function graticuleX(y0, y1, dy) {
var y = sequence(y0, y1 - epsilon$2, dy).concat(y1);
return function(x) { return y.map(function(y) { return [x, y]; }); };
}
function graticuleY(x0, x1, dx) {
var x = sequence(x0, x1 - epsilon$2, dx).concat(x1);
return function(y) { return x.map(function(x) { return [x, y]; }); };
}
function graticule() {
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 sequence(ceil(X0 / DX) * DX, X1, DX).map(X)
.concat(sequence(ceil(Y0 / DY) * DY, Y1, DY).map(Y))
.concat(sequence(ceil(x0 / dx) * dx, x1, dx).filter(function(x) { return abs(x % DX) > epsilon$2; }).map(x))
.concat(sequence(ceil(y0 / dy) * dy, y1, dy).filter(function(y) { return abs(y % DY) > epsilon$2; }).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.extentMinor();
return graticule.extentMajor(_).extentMinor(_);
};
graticule.extentMajor = 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.extentMinor = 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.stepMinor();
return graticule.stepMajor(_).stepMinor(_);
};
graticule.stepMajor = function(_) {
if (!arguments.length) return [DX, DY];
DX = +_[0], DY = +_[1];
return graticule;
};
graticule.stepMinor = function(_) {
if (!arguments.length) return [dx, dy];
dx = +_[0], dy = +_[1];
return graticule;
};
graticule.precision = function(_) {
if (!arguments.length) return precision;
precision = +_;
x = graticuleX(y0, y1, 90);
y = graticuleY(x0, x1, precision);
X = graticuleX(Y0, Y1, 90);
Y = graticuleY(X0, X1, precision);
return graticule;
};
return graticule
.extentMajor([[-180, -90 + epsilon$2], [180, 90 - epsilon$2]])
.extentMinor([[-180, -80 - epsilon$2], [180, 80 + epsilon$2]]);
}
function graticule10() {
return graticule()();
}
var interpolate$1 = function(a, b) {
var x0 = a[0] * radians,
y0 = a[1] * radians,
x1 = b[0] * radians,
y1 = b[1] * radians,
cy0 = cos$1(y0),
sy0 = sin$1(y0),
cy1 = cos$1(y1),
sy1 = sin$1(y1),
kx0 = cy0 * cos$1(x0),
ky0 = cy0 * sin$1(x0),
kx1 = cy1 * cos$1(x1),
ky1 = cy1 * sin$1(x1),
d = 2 * asin(sqrt(haversin(y1 - y0) + cy0 * cy1 * haversin(x1 - x0))),
k = sin$1(d);
var interpolate = d ? function(t) {
var B = sin$1(t *= d) / k,
A = sin$1(d - t) / k,
x = A * kx0 + B * kx1,
y = A * ky0 + B * ky1,
z = A * sy0 + B * sy1;
return [
atan2(y, x) * degrees$1,
atan2(z, sqrt(x * x + y * y)) * degrees$1
];
} : function() {
return [x0 * degrees$1, y0 * degrees$1];
};
interpolate.distance = d;
return interpolate;
};
var identity$4 = function(x) {
return x;
};
var areaSum$1 = adder();
var areaRingSum$1 = adder();
var x00;
var y00;
var x0$1;
var y0$1;
var areaStream$1 = {
point: noop$1,
lineStart: noop$1,
lineEnd: noop$1,
polygonStart: function() {
areaStream$1.lineStart = areaRingStart$1;
areaStream$1.lineEnd = areaRingEnd$1;
},
polygonEnd: function() {
areaStream$1.lineStart = areaStream$1.lineEnd = areaStream$1.point = noop$1;
areaSum$1.add(abs(areaRingSum$1));
areaRingSum$1.reset();
},
result: function() {
var area = areaSum$1 / 2;
areaSum$1.reset();
return area;
}
};
function areaRingStart$1() {
areaStream$1.point = areaPointFirst$1;
}
function areaPointFirst$1(x, y) {
areaStream$1.point = areaPoint$1;
x00 = x0$1 = x, y00 = y0$1 = y;
}
function areaPoint$1(x, y) {
areaRingSum$1.add(y0$1 * x - x0$1 * y);
x0$1 = x, y0$1 = y;
}
function areaRingEnd$1() {
areaPoint$1(x00, y00);
}
var x0$2 = Infinity;
var y0$2 = x0$2;
var x1 = -x0$2;
var y1 = x1;
var boundsStream$1 = {
point: boundsPoint$1,
lineStart: noop$1,
lineEnd: noop$1,
polygonStart: noop$1,
polygonEnd: noop$1,
result: function() {
var bounds = [[x0$2, y0$2], [x1, y1]];
x1 = y1 = -(y0$2 = x0$2 = Infinity);
return bounds;
}
};
function boundsPoint$1(x, y) {
if (x < x0$2) x0$2 = x;
if (x > x1) x1 = x;
if (y < y0$2) y0$2 = y;
if (y > y1) y1 = y;
}
// TODO Enforce positive area for exterior, negative area for interior?
var X0$1 = 0;
var Y0$1 = 0;
var Z0$1 = 0;
var X1$1 = 0;
var Y1$1 = 0;
var Z1$1 = 0;
var X2$1 = 0;
var Y2$1 = 0;
var Z2$1 = 0;
var x00$1;
var y00$1;
var x0$3;
var y0$3;
var centroidStream$1 = {
point: centroidPoint$1,
lineStart: centroidLineStart$1,
lineEnd: centroidLineEnd$1,
polygonStart: function() {
centroidStream$1.lineStart = centroidRingStart$1;
centroidStream$1.lineEnd = centroidRingEnd$1;
},
polygonEnd: function() {
centroidStream$1.point = centroidPoint$1;
centroidStream$1.lineStart = centroidLineStart$1;
centroidStream$1.lineEnd = centroidLineEnd$1;
},
result: function() {
var centroid = Z2$1 ? [X2$1 / Z2$1, Y2$1 / Z2$1]
: Z1$1 ? [X1$1 / Z1$1, Y1$1 / Z1$1]
: Z0$1 ? [X0$1 / Z0$1, Y0$1 / Z0$1]
: [NaN, NaN];
X0$1 = Y0$1 = Z0$1 =
X1$1 = Y1$1 = Z1$1 =
X2$1 = Y2$1 = Z2$1 = 0;
return centroid;
}
};
function centroidPoint$1(x, y) {
X0$1 += x;
Y0$1 += y;
++Z0$1;
}
function centroidLineStart$1() {
centroidStream$1.point = centroidPointFirstLine;
}
function centroidPointFirstLine(x, y) {
centroidStream$1.point = centroidPointLine;
centroidPoint$1(x0$3 = x, y0$3 = y);
}
function centroidPointLine(x, y) {
var dx = x - x0$3, dy = y - y0$3, z = sqrt(dx * dx + dy * dy);
X1$1 += z * (x0$3 + x) / 2;
Y1$1 += z * (y0$3 + y) / 2;
Z1$1 += z;
centroidPoint$1(x0$3 = x, y0$3 = y);
}
function centroidLineEnd$1() {
centroidStream$1.point = centroidPoint$1;
}
function centroidRingStart$1() {
centroidStream$1.point = centroidPointFirstRing;
}
function centroidRingEnd$1() {
centroidPointRing(x00$1, y00$1);
}
function centroidPointFirstRing(x, y) {
centroidStream$1.point = centroidPointRing;
centroidPoint$1(x00$1 = x0$3 = x, y00$1 = y0$3 = y);
}
function centroidPointRing(x, y) {
var dx = x - x0$3,
dy = y - y0$3,
z = sqrt(dx * dx + dy * dy);
X1$1 += z * (x0$3 + x) / 2;
Y1$1 += z * (y0$3 + y) / 2;
Z1$1 += z;
z = y0$3 * x - x0$3 * y;
X2$1 += z * (x0$3 + x);
Y2$1 += z * (y0$3 + y);
Z2$1 += z * 3;
centroidPoint$1(x0$3 = x, y0$3 = y);
}
function PathContext(context) {
this._context = context;
}
PathContext.prototype = {
_radius: 4.5,
pointRadius: function(_) {
return this._radius = _, this;
},
polygonStart: function() {
this._line = 0;
},
polygonEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._point = 0;
},
lineEnd: function() {
if (this._line === 0) this._context.closePath();
this._point = NaN;
},
point: function(x, y) {
switch (this._point) {
case 0: {
this._context.moveTo(x, y);
this._point = 1;
break;
}
case 1: {
this._context.lineTo(x, y);
break;
}
default: {
this._context.moveTo(x + this._radius, y);
this._context.arc(x, y, this._radius, 0, tau$3);
break;
}
}
},
result: noop$1
};
var lengthSum$1 = adder();
var lengthRing;
var x00$2;
var y00$2;
var x0$4;
var y0$4;
var lengthStream$1 = {
point: noop$1,
lineStart: function() {
lengthStream$1.point = lengthPointFirst$1;
},
lineEnd: function() {
if (lengthRing) lengthPoint$1(x00$2, y00$2);
lengthStream$1.point = noop$1;
},
polygonStart: function() {
lengthRing = true;
},
polygonEnd: function() {
lengthRing = null;
},
result: function() {
var length = +lengthSum$1;
lengthSum$1.reset();
return length;
}
};
function lengthPointFirst$1(x, y) {
lengthStream$1.point = lengthPoint$1;
x00$2 = x0$4 = x, y00$2 = y0$4 = y;
}
function lengthPoint$1(x, y) {
x0$4 -= x, y0$4 -= y;
lengthSum$1.add(sqrt(x0$4 * x0$4 + y0$4 * y0$4));
x0$4 = x, y0$4 = y;
}
function PathString() {
this._string = [];
}
PathString.prototype = {
_radius: 4.5,
_circle: circle$1(4.5),
pointRadius: function(_) {
if ((_ = +_) !== this._radius) this._radius = _, this._circle = null;
return this;
},
polygonStart: function() {
this._line = 0;
},
polygonEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._point = 0;
},
lineEnd: function() {
if (this._line === 0) this._string.push("Z");
this._point = NaN;
},
point: function(x, y) {
switch (this._point) {
case 0: {
this._string.push("M", x, ",", y);
this._point = 1;
break;
}
case 1: {
this._string.push("L", x, ",", y);
break;
}
default: {
if (this._circle == null) this._circle = circle$1(this._radius);
this._string.push("M", x, ",", y, this._circle);
break;
}
}
},
result: function() {
if (this._string.length) {
var result = this._string.join("");
this._string = [];
return result;
} else {
return null;
}
}
};
function circle$1(radius) {
return "m0," + radius
+ "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius
+ "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius
+ "z";
}
var index$1 = function(projection, context) {
var pointRadius = 4.5,
projectionStream,
contextStream;
function path(object) {
if (object) {
if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments));
geoStream(object, projectionStream(contextStream));
}
return contextStream.result();
}
path.area = function(object) {
geoStream(object, projectionStream(areaStream$1));
return areaStream$1.result();
};
path.measure = function(object) {
geoStream(object, projectionStream(lengthStream$1));
return lengthStream$1.result();
};
path.bounds = function(object) {
geoStream(object, projectionStream(boundsStream$1));
return boundsStream$1.result();
};
path.centroid = function(object) {
geoStream(object, projectionStream(centroidStream$1));
return centroidStream$1.result();
};
path.projection = function(_) {
return arguments.length ? (projectionStream = _ == null ? (projection = null, identity$4) : (projection = _).stream, path) : projection;
};
path.context = function(_) {
if (!arguments.length) return context;
contextStream = _ == null ? (context = null, new PathString) : new PathContext(context = _);
if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius);
return path;
};
path.pointRadius = function(_) {
if (!arguments.length) return pointRadius;
pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_);
return path;
};
return path.projection(projection).context(context);
};
var clip = function(pointVisible, clipLine, interpolate, start) {
return function(rotate, sink) {
var line = clipLine(sink),
rotatedStart = rotate.invert(start[0], start[1]),
ringBuffer = clipBuffer(),
ringSink = clipLine(ringBuffer),
polygonStarted = false,
polygon,
segments,
ring;
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 = merge(segments);
var startInside = polygonContains(polygon, rotatedStart);
if (segments.length) {
if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
clipPolygon(segments, compareIntersection, startInside, interpolate, sink);
} else if (startInside) {
if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
sink.lineStart();
interpolate(null, null, 1, sink);
sink.lineEnd();
}
if (polygonStarted) sink.polygonEnd(), polygonStarted = false;
segments = polygon = null;
},
sphere: function() {
sink.polygonStart();
sink.lineStart();
interpolate(null, null, 1, sink);
sink.lineEnd();
sink.polygonEnd();
}
};
function point(lambda, phi) {
var point = rotate(lambda, phi);
if (pointVisible(lambda = point[0], phi = point[1])) sink.point(lambda, phi);
}
function pointLine(lambda, phi) {
var point = rotate(lambda, phi);
line.point(point[0], point[1]);
}
function lineStart() {
clip.point = pointLine;
line.lineStart();
}
function lineEnd() {
clip.point = point;
line.lineEnd();
}
function pointRing(lambda, phi) {
ring.push([lambda, phi]);
var point = rotate(lambda, phi);
ringSink.point(point[0], point[1]);
}
function ringStart() {
ringSink.lineStart();
ring = [];
}
function ringEnd() {
pointRing(ring[0][0], ring[0][1]);
ringSink.lineEnd();
var clean = ringSink.clean(),
ringSegments = ringBuffer.result(),
i, n = ringSegments.length, m,
segment,
point;
ring.pop();
polygon.push(ring);
ring = null;
if (!n) return;
// No intersections.
if (clean & 1) {
segment = ringSegments[0];
if ((m = segment.length - 1) > 0) {
if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
sink.lineStart();
for (i = 0; i < m; ++i) sink.point((point = segment[i])[0], point[1]);
sink.lineEnd();
}
return;
}
// Rejoin connected segments.
// TODO reuse ringBuffer.rejoin()?
if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift()));
segments.push(ringSegments.filter(validSegment));
}
return clip;
};
};
function validSegment(segment) {
return segment.length > 1;
}
// Intersections are sorted along the clip edge. For both antimeridian cutting
// and circle clipping, the same comparison is used.
function compareIntersection(a, b) {
return ((a = a.x)[0] < 0 ? a[1] - halfPi$2 - epsilon$2 : halfPi$2 - a[1])
- ((b = b.x)[0] < 0 ? b[1] - halfPi$2 - epsilon$2 : halfPi$2 - b[1]);
}
var clipAntimeridian = clip(
function() { return true; },
clipAntimeridianLine,
clipAntimeridianInterpolate,
[-pi$3, -halfPi$2]
);
// Takes a line and cuts into visible segments. Return values: 0 - there were
// intersections or the line was empty; 1 - no intersections; 2 - there were
// intersections, and the first and last segments should be rejoined.
function clipAntimeridianLine(stream) {
var lambda0 = NaN,
phi0 = NaN,
sign0 = NaN,
clean; // no intersections
return {
lineStart: function() {
stream.lineStart();
clean = 1;
},
point: function(lambda1, phi1) {
var sign1 = lambda1 > 0 ? pi$3 : -pi$3,
delta = abs(lambda1 - lambda0);
if (abs(delta - pi$3) < epsilon$2) { // line crosses a pole
stream.point(lambda0, phi0 = (phi0 + phi1) / 2 > 0 ? halfPi$2 : -halfPi$2);
stream.point(sign0, phi0);
stream.lineEnd();
stream.lineStart();
stream.point(sign1, phi0);
stream.point(lambda1, phi0);
clean = 0;
} else if (sign0 !== sign1 && delta >= pi$3) { // line crosses antimeridian
if (abs(lambda0 - sign0) < epsilon$2) lambda0 -= sign0 * epsilon$2; // handle degeneracies
if (abs(lambda1 - sign1) < epsilon$2) lambda1 -= sign1 * epsilon$2;
phi0 = clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1);
stream.point(sign0, phi0);
stream.lineEnd();
stream.lineStart();
stream.point(sign1, phi0);
clean = 0;
}
stream.point(lambda0 = lambda1, phi0 = phi1);
sign0 = sign1;
},
lineEnd: function() {
stream.lineEnd();
lambda0 = phi0 = NaN;
},
clean: function() {
return 2 - clean; // if intersections, rejoin first and last segments
}
};
}
function clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1) {
var cosPhi0,
cosPhi1,
sinLambda0Lambda1 = sin$1(lambda0 - lambda1);
return abs(sinLambda0Lambda1) > epsilon$2
? atan((sin$1(phi0) * (cosPhi1 = cos$1(phi1)) * sin$1(lambda1)
- sin$1(phi1) * (cosPhi0 = cos$1(phi0)) * sin$1(lambda0))
/ (cosPhi0 * cosPhi1 * sinLambda0Lambda1))
: (phi0 + phi1) / 2;
}
function clipAntimeridianInterpolate(from, to, direction, stream) {
var phi;
if (from == null) {
phi = direction * halfPi$2;
stream.point(-pi$3, phi);
stream.point(0, phi);
stream.point(pi$3, phi);
stream.point(pi$3, 0);
stream.point(pi$3, -phi);
stream.point(0, -phi);
stream.point(-pi$3, -phi);
stream.point(-pi$3, 0);
stream.point(-pi$3, phi);
} else if (abs(from[0] - to[0]) > epsilon$2) {
var lambda = from[0] < to[0] ? pi$3 : -pi$3;
phi = direction * lambda / 2;
stream.point(-lambda, phi);
stream.point(0, phi);
stream.point(lambda, phi);
} else {
stream.point(to[0], to[1]);
}
}
var clipCircle = function(radius, delta) {
var cr = cos$1(radius),
smallRadius = cr > 0,
notHemisphere = abs(cr) > epsilon$2; // TODO optimise for this common case
function interpolate(from, to, direction, stream) {
circleStream(stream, radius, delta, direction, from, to);
}
function visible(lambda, phi) {
return cos$1(lambda) * cos$1(phi) > cr;
}
// Takes a line and cuts into visible segments. Return values used for polygon
// clipping: 0 - there were intersections or the line was empty; 1 - no
// intersections 2 - there were intersections, and the first and last segments
// should be rejoined.
function clipLine(stream) {
var point0, // previous point
c0, // code for previous point
v0, // visibility of previous point
v00, // visibility of first point
clean; // no intersections
return {
lineStart: function() {
v00 = v0 = false;
clean = 1;
},
point: function(lambda, phi) {
var point1 = [lambda, phi],
point2,
v = visible(lambda, phi),
c = smallRadius
? v ? 0 : code(lambda, phi)
: v ? code(lambda + (lambda < 0 ? pi$3 : -pi$3), phi) : 0;
if (!point0 && (v00 = v0 = v)) stream.lineStart();
// Handle degeneracies.
// TODO ignore if not clipping polygons.
if (v !== v0) {
point2 = intersect(point0, point1);
if (!point2 || pointEqual(point0, point2) || pointEqual(point1, point2)) {
point1[0] += epsilon$2;
point1[1] += epsilon$2;
v = visible(point1[0], point1[1]);
}
}
if (v !== v0) {
clean = 0;
if (v) {
// outside going in
stream.lineStart();
point2 = intersect(point1, point0);
stream.point(point2[0], point2[1]);
} else {
// inside going out
point2 = intersect(point0, point1);
stream.point(point2[0], point2[1]);
stream.lineEnd();
}
point0 = point2;
} else if (notHemisphere && point0 && smallRadius ^ v) {
var t;
// If the codes for two points are different, or are both zero,
// and there this segment intersects with the small circle.
if (!(c & c0) && (t = intersect(point1, point0, true))) {
clean = 0;
if (smallRadius) {
stream.lineStart();
stream.point(t[0][0], t[0][1]);
stream.point(t[1][0], t[1][1]);
stream.lineEnd();
} else {
stream.point(t[1][0], t[1][1]);
stream.lineEnd();
stream.lineStart();
stream.point(t[0][0], t[0][1]);
}
}
}
if (v && (!point0 || !pointEqual(point0, point1))) {
stream.point(point1[0], point1[1]);
}
point0 = point1, v0 = v, c0 = c;
},
lineEnd: function() {
if (v0) stream.lineEnd();
point0 = null;
},
// Rejoin first and last segments if there were intersections and the first
// and last points were visible.
clean: function() {
return clean | ((v00 && v0) << 1);
}
};
}
// Intersects the great circle between a and b with the clip circle.
function intersect(a, b, two) {
var pa = cartesian(a),
pb = cartesian(b);
// We have two planes, n1.p = d1 and n2.p = d2.
// Find intersection line p(t) = c1 n1 + c2 n2 + t (n1 ⨯ n2).
var n1 = [1, 0, 0], // normal
n2 = cartesianCross(pa, pb),
n2n2 = cartesianDot(n2, n2),
n1n2 = n2[0], // cartesianDot(n1, n2),
determinant = n2n2 - n1n2 * n1n2;
// Two polar points.
if (!determinant) return !two && a;
var c1 = cr * n2n2 / determinant,
c2 = -cr * n1n2 / determinant,
n1xn2 = cartesianCross(n1, n2),
A = cartesianScale(n1, c1),
B = cartesianScale(n2, c2);
cartesianAddInPlace(A, B);
// Solve |p(t)|^2 = 1.
var u = n1xn2,
w = cartesianDot(A, u),
uu = cartesianDot(u, u),
t2 = w * w - uu * (cartesianDot(A, A) - 1);
if (t2 < 0) return;
var t = sqrt(t2),
q = cartesianScale(u, (-w - t) / uu);
cartesianAddInPlace(q, A);
q = spherical(q);
if (!two) return q;
// Two intersection points.
var lambda0 = a[0],
lambda1 = b[0],
phi0 = a[1],
phi1 = b[1],
z;
if (lambda1 < lambda0) z = lambda0, lambda0 = lambda1, lambda1 = z;
var delta = lambda1 - lambda0,
polar = abs(delta - pi$3) < epsilon$2,
meridian = polar || delta < epsilon$2;
if (!polar && phi1 < phi0) z = phi0, phi0 = phi1, phi1 = z;
// Check that the first point is between a and b.
if (meridian
? polar
? phi0 + phi1 > 0 ^ q[1] < (abs(q[0] - lambda0) < epsilon$2 ? phi0 : phi1)
: phi0 <= q[1] && q[1] <= phi1
: delta > pi$3 ^ (lambda0 <= q[0] && q[0] <= lambda1)) {
var q1 = cartesianScale(u, (-w + t) / uu);
cartesianAddInPlace(q1, A);
return [q, spherical(q1)];
}
}
// Generates a 4-bit vector representing the location of a point relative to
// the small circle's bounding box.
function code(lambda, phi) {
var r = smallRadius ? radius : pi$3 - radius,
code = 0;
if (lambda < -r) code |= 1; // left
else if (lambda > r) code |= 2; // right
if (phi < -r) code |= 4; // below
else if (phi > r) code |= 8; // above
return code;
}
return clip(visible, clipLine, interpolate, smallRadius ? [0, -radius] : [-pi$3, radius - pi$3]);
};
var transform = function(methods) {
return {
stream: transformer(methods)
};
};
function transformer(methods) {
return function(stream) {
var s = new TransformStream;
for (var key in methods) s[key] = methods[key];
s.stream = stream;
return s;
};
}
function TransformStream() {}
TransformStream.prototype = {
constructor: TransformStream,
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 fitExtent(projection, extent, object) {
var w = extent[1][0] - extent[0][0],
h = extent[1][1] - extent[0][1],
clip = projection.clipExtent && projection.clipExtent();
projection
.scale(150)
.translate([0, 0]);
if (clip != null) projection.clipExtent(null);
geoStream(object, projection.stream(boundsStream$1));
var b = boundsStream$1.result(),
k = Math.min(w / (b[1][0] - b[0][0]), h / (b[1][1] - b[0][1])),
x = +extent[0][0] + (w - k * (b[1][0] + b[0][0])) / 2,
y = +extent[0][1] + (h - k * (b[1][1] + b[0][1])) / 2;
if (clip != null) projection.clipExtent(clip);
return projection
.scale(k * 150)
.translate([x, y]);
}
function fitSize(projection, size, object) {
return fitExtent(projection, [[0, 0], size], object);
}
var maxDepth = 16;
var cosMinDistance = cos$1(30 * radians); // cos(minimum angular distance)
var resample = function(project, delta2) {
return +delta2 ? resample$1(project, delta2) : resampleNone(project);
};
function resampleNone(project) {
return transformer({
point: function(x, y) {
x = project(x, y);
this.stream.point(x[0], x[1]);
}
});
}
function resample$1(project, delta2) {
function resampleLineTo(x0, y0, lambda0, a0, b0, c0, x1, y1, lambda1, a1, b1, c1, depth, stream) {
var dx = x1 - x0,
dy = y1 - y0,
d2 = dx * dx + dy * dy;
if (d2 > 4 * delta2 && depth--) {
var a = a0 + a1,
b = b0 + b1,
c = c0 + c1,
m = sqrt(a * a + b * b + c * c),
phi2 = asin(c /= m),
lambda2 = abs(abs(c) - 1) < epsilon$2 || abs(lambda0 - lambda1) < epsilon$2 ? (lambda0 + lambda1) / 2 : atan2(b, a),
p = project(lambda2, phi2),
x2 = p[0],
y2 = p[1],
dx2 = x2 - x0,
dy2 = y2 - y0,
dz = dy * dx2 - dx * dy2;
if (dz * dz / d2 > delta2 // perpendicular projected distance
|| abs((dx * dx2 + dy * dy2) / d2 - 0.5) > 0.3 // midpoint close to an end
|| a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { // angular distance
resampleLineTo(x0, y0, lambda0, a0, b0, c0, x2, y2, lambda2, a /= m, b /= m, c, depth, stream);
stream.point(x2, y2);
resampleLineTo(x2, y2, lambda2, a, b, c, x1, y1, lambda1, a1, b1, c1, depth, stream);
}
}
}
return function(stream) {
var lambda00, x00, y00, a00, b00, c00, // first point
lambda0, x0, y0, a0, b0, c0; // previous point
var resampleStream = {
point: point,
lineStart: lineStart,
lineEnd: lineEnd,
polygonStart: function() { stream.polygonStart(); resampleStream.lineStart = ringStart; },
polygonEnd: function() { stream.polygonEnd(); resampleStream.lineStart = lineStart; }
};
function point(x, y) {
x = project(x, y);
stream.point(x[0], x[1]);
}
function lineStart() {
x0 = NaN;
resampleStream.point = linePoint;
stream.lineStart();
}
function linePoint(lambda, phi) {
var c = cartesian([lambda, phi]), p = project(lambda, phi);
resampleLineTo(x0, y0, lambda0, a0, b0, c0, x0 = p[0], y0 = p[1], lambda0 = lambda, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream);
stream.point(x0, y0);
}
function lineEnd() {
resampleStream.point = point;
stream.lineEnd();
}
function ringStart() {
lineStart();
resampleStream.point = ringPoint;
resampleStream.lineEnd = ringEnd;
}
function ringPoint(lambda, phi) {
linePoint(lambda00 = lambda, phi), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0;
resampleStream.point = linePoint;
}
function ringEnd() {
resampleLineTo(x0, y0, lambda0, a0, b0, c0, x00, y00, lambda00, a00, b00, c00, maxDepth, stream);
resampleStream.lineEnd = lineEnd;
lineEnd();
}
return resampleStream;
};
}
var transformRadians = transformer({
point: function(x, y) {
this.stream.point(x * radians, y * radians);
}
});
function projection(project) {
return projectionMutator(function() { return project; })();
}
function projectionMutator(projectAt) {
var project,
k = 150, // scale
x = 480, y = 250, // translate
dx, dy, lambda = 0, phi = 0, // center
deltaLambda = 0, deltaPhi = 0, deltaGamma = 0, rotate, projectRotate, // rotate
theta = null, preclip = clipAntimeridian, // clip angle
x0 = null, y0, x1, y1, postclip = identity$4, // clip extent
delta2 = 0.5, projectResample = resample(projectTransform, delta2), // precision
cache,
cacheStream;
function projection(point) {
point = projectRotate(point[0] * radians, point[1] * radians);
return [point[0] * k + dx, dy - point[1] * k];
}
function invert(point) {
point = projectRotate.invert((point[0] - dx) / k, (dy - point[1]) / k);
return point && [point[0] * degrees$1, point[1] * degrees$1];
}
function projectTransform(x, y) {
return x = project(x, y), [x[0] * k + dx, dy - x[1] * k];
}
projection.stream = function(stream) {
return cache && cacheStream === stream ? cache : cache = transformRadians(preclip(rotate, projectResample(postclip(cacheStream = stream))));
};
projection.clipAngle = function(_) {
return arguments.length ? (preclip = +_ ? clipCircle(theta = _ * radians, 6 * radians) : (theta = null, clipAntimeridian), reset()) : theta * degrees$1;
};
projection.clipExtent = function(_) {
return arguments.length ? (postclip = _ == null ? (x0 = y0 = x1 = y1 = null, identity$4) : clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];
};
projection.scale = function(_) {
return arguments.length ? (k = +_, recenter()) : k;
};
projection.translate = function(_) {
return arguments.length ? (x = +_[0], y = +_[1], recenter()) : [x, y];
};
projection.center = function(_) {
return arguments.length ? (lambda = _[0] % 360 * radians, phi = _[1] % 360 * radians, recenter()) : [lambda * degrees$1, phi * degrees$1];
};
projection.rotate = function(_) {
return arguments.length ? (deltaLambda = _[0] % 360 * radians, deltaPhi = _[1] % 360 * radians, deltaGamma = _.length > 2 ? _[2] % 360 * radians : 0, recenter()) : [deltaLambda * degrees$1, deltaPhi * degrees$1, deltaGamma * degrees$1];
};
projection.precision = function(_) {
return arguments.length ? (projectResample = resample(projectTransform, delta2 = _ * _), reset()) : sqrt(delta2);
};
projection.fitExtent = function(extent, object) {
return fitExtent(projection, extent, object);
};
projection.fitSize = function(size, object) {
return fitSize(projection, size, object);
};
function recenter() {
projectRotate = compose(rotate = rotateRadians(deltaLambda, deltaPhi, deltaGamma), project);
var center = project(lambda, phi);
dx = x - center[0] * k;
dy = y + center[1] * k;
return reset();
}
function reset() {
cache = cacheStream = null;
return projection;
}
return function() {
project = projectAt.apply(this, arguments);
projection.invert = project.invert && invert;
return recenter();
};
}
function conicProjection(projectAt) {
var phi0 = 0,
phi1 = pi$3 / 3,
m = projectionMutator(projectAt),
p = m(phi0, phi1);
p.parallels = function(_) {
return arguments.length ? m(phi0 = _[0] * radians, phi1 = _[1] * radians) : [phi0 * degrees$1, phi1 * degrees$1];
};
return p;
}
function cylindricalEqualAreaRaw(phi0) {
var cosPhi0 = cos$1(phi0);
function forward(lambda, phi) {
return [lambda * cosPhi0, sin$1(phi) / cosPhi0];
}
forward.invert = function(x, y) {
return [x / cosPhi0, asin(y * cosPhi0)];
};
return forward;
}
function conicEqualAreaRaw(y0, y1) {
var sy0 = sin$1(y0), n = (sy0 + sin$1(y1)) / 2;
// Are the parallels symmetrical around the Equator?
if (abs(n) < epsilon$2) return cylindricalEqualAreaRaw(y0);
var c = 1 + sy0 * (2 * n - sy0), r0 = sqrt(c) / n;
function project(x, y) {
var r = sqrt(c - 2 * n * sin$1(y)) / n;
return [r * sin$1(x *= n), r0 - r * cos$1(x)];
}
project.invert = function(x, y) {
var r0y = r0 - y;
return [atan2(x, abs(r0y)) / n * sign(r0y), asin((c - (x * x + r0y * r0y) * n * n) / (2 * n))];
};
return project;
}
var conicEqualArea = function() {
return conicProjection(conicEqualAreaRaw)
.scale(155.424)
.center([0, 33.6442]);
};
var albers = function() {
return conicEqualArea()
.parallels([29.5, 45.5])
.scale(1070)
.translate([480, 250])
.rotate([96, 0])
.center([-0.6, 38.7]);
};
// The projections must have mutually exclusive clip regions on the sphere,
// as this will avoid emitting interleaving lines and polygons.
function multiplex(streams) {
var n = streams.length;
return {
point: function(x, y) { var i = -1; while (++i < n) streams[i].point(x, y); },
sphere: function() { var i = -1; while (++i < n) streams[i].sphere(); },
lineStart: function() { var i = -1; while (++i < n) streams[i].lineStart(); },
lineEnd: function() { var i = -1; while (++i < n) streams[i].lineEnd(); },
polygonStart: function() { var i = -1; while (++i < n) streams[i].polygonStart(); },
polygonEnd: function() { var i = -1; while (++i < n) streams[i].polygonEnd(); }
};
}
// A composite projection for the United States, configured by default for
// 960×500. The projection also works quite well at 960×600 if you change the
// scale to 1285 and adjust the translate accordingly. The set of standard
// parallels for each region comes from USGS, which is published here:
// http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers
var albersUsa = function() {
var cache,
cacheStream,
lower48 = albers(), lower48Point,
alaska = conicEqualArea().rotate([154, 0]).center([-2, 58.5]).parallels([55, 65]), alaskaPoint, // EPSG:3338
hawaii = conicEqualArea().rotate([157, 0]).center([-3, 19.9]).parallels([8, 18]), hawaiiPoint, // ESRI:102007
point, pointStream = {point: function(x, y) { point = [x, y]; }};
function albersUsa(coordinates) {
var x = coordinates[0], y = coordinates[1];
return point = null,
(lower48Point.point(x, y), point)
|| (alaskaPoint.point(x, y), point)
|| (hawaiiPoint.point(x, y), 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 >= 0.120 && y < 0.234 && x >= -0.425 && x < -0.214 ? alaska
: y >= 0.166 && y < 0.234 && x >= -0.214 && x < -0.115 ? hawaii
: lower48).invert(coordinates);
};
albersUsa.stream = function(stream) {
return cache && cacheStream === stream ? cache : cache = multiplex([lower48.stream(cacheStream = stream), alaska.stream(stream), hawaii.stream(stream)]);
};
albersUsa.precision = function(_) {
if (!arguments.length) return lower48.precision();
lower48.precision(_), alaska.precision(_), hawaii.precision(_);
return reset();
};
albersUsa.scale = function(_) {
if (!arguments.length) return lower48.scale();
lower48.scale(_), alaska.scale(_ * 0.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 - 0.455 * k, y - 0.238 * k], [x + 0.455 * k, y + 0.238 * k]])
.stream(pointStream);
alaskaPoint = alaska
.translate([x - 0.307 * k, y + 0.201 * k])
.clipExtent([[x - 0.425 * k + epsilon$2, y + 0.120 * k + epsilon$2], [x - 0.214 * k - epsilon$2, y + 0.234 * k - epsilon$2]])
.stream(pointStream);
hawaiiPoint = hawaii
.translate([x - 0.205 * k, y + 0.212 * k])
.clipExtent([[x - 0.214 * k + epsilon$2, y + 0.166 * k + epsilon$2], [x - 0.115 * k - epsilon$2, y + 0.234 * k - epsilon$2]])
.stream(pointStream);
return reset();
};
albersUsa.fitExtent = function(extent, object) {
return fitExtent(albersUsa, extent, object);
};
albersUsa.fitSize = function(size, object) {
return fitSize(albersUsa, size, object);
};
function reset() {
cache = cacheStream = null;
return albersUsa;
}
return albersUsa.scale(1070);
};
function azimuthalRaw(scale) {
return function(x, y) {
var cx = cos$1(x),
cy = cos$1(y),
k = scale(cx * cy);
return [
k * cy * sin$1(x),
k * sin$1(y)
];
}
}
function azimuthalInvert(angle) {
return function(x, y) {
var z = sqrt(x * x + y * y),
c = angle(z),
sc = sin$1(c),
cc = cos$1(c);
return [
atan2(x * sc, z * cc),
asin(z && y * sc / z)
];
}
}
var azimuthalEqualAreaRaw = azimuthalRaw(function(cxcy) {
return sqrt(2 / (1 + cxcy));
});
azimuthalEqualAreaRaw.invert = azimuthalInvert(function(z) {
return 2 * asin(z / 2);
});
var azimuthalEqualArea = function() {
return projection(azimuthalEqualAreaRaw)
.scale(124.75)
.clipAngle(180 - 1e-3);
};
var azimuthalEquidistantRaw = azimuthalRaw(function(c) {
return (c = acos(c)) && c / sin$1(c);
});
azimuthalEquidistantRaw.invert = azimuthalInvert(function(z) {
return z;
});
var azimuthalEquidistant = function() {
return projection(azimuthalEquidistantRaw)
.scale(79.4188)
.clipAngle(180 - 1e-3);
};
function mercatorRaw(lambda, phi) {
return [lambda, log(tan((halfPi$2 + phi) / 2))];
}
mercatorRaw.invert = function(x, y) {
return [x, 2 * atan(exp(y)) - halfPi$2];
};
var mercator = function() {
return mercatorProjection(mercatorRaw)
.scale(961 / tau$3);
};
function mercatorProjection(project) {
var m = projection(project),
center = m.center,
scale = m.scale,
translate = m.translate,
clipExtent = m.clipExtent,
x0 = null, y0, x1, y1; // clip extent
m.scale = function(_) {
return arguments.length ? (scale(_), reclip()) : scale();
};
m.translate = function(_) {
return arguments.length ? (translate(_), reclip()) : translate();
};
m.center = function(_) {
return arguments.length ? (center(_), reclip()) : center();
};
m.clipExtent = function(_) {
return arguments.length ? ((_ == null ? x0 = y0 = x1 = y1 = null : (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1])), reclip()) : x0 == null ? null : [[x0, y0], [x1, y1]];
};
function reclip() {
var k = pi$3 * scale(),
t = m(rotation(m.rotate()).invert([0, 0]));
return clipExtent(x0 == null
? [[t[0] - k, t[1] - k], [t[0] + k, t[1] + k]] : project === mercatorRaw
? [[Math.max(t[0] - k, x0), y0], [Math.min(t[0] + k, x1), y1]]
: [[x0, Math.max(t[1] - k, y0)], [x1, Math.min(t[1] + k, y1)]]);
}
return reclip();
}
function tany(y) {
return tan((halfPi$2 + y) / 2);
}
function conicConformalRaw(y0, y1) {
var cy0 = cos$1(y0),
n = y0 === y1 ? sin$1(y0) : log(cy0 / cos$1(y1)) / log(tany(y1) / tany(y0)),
f = cy0 * pow(tany(y0), n) / n;
if (!n) return mercatorRaw;
function project(x, y) {
if (f > 0) { if (y < -halfPi$2 + epsilon$2) y = -halfPi$2 + epsilon$2; }
else { if (y > halfPi$2 - epsilon$2) y = halfPi$2 - epsilon$2; }
var r = f / pow(tany(y), n);
return [r * sin$1(n * x), f - r * cos$1(n * x)];
}
project.invert = function(x, y) {
var fy = f - y, r = sign(n) * sqrt(x * x + fy * fy);
return [atan2(x, abs(fy)) / n * sign(fy), 2 * atan(pow(f / r, 1 / n)) - halfPi$2];
};
return project;
}
var conicConformal = function() {
return conicProjection(conicConformalRaw)
.scale(109.5)
.parallels([30, 30]);
};
function equirectangularRaw(lambda, phi) {
return [lambda, phi];
}
equirectangularRaw.invert = equirectangularRaw;
var equirectangular = function() {
return projection(equirectangularRaw)
.scale(152.63);
};
function conicEquidistantRaw(y0, y1) {
var cy0 = cos$1(y0),
n = y0 === y1 ? sin$1(y0) : (cy0 - cos$1(y1)) / (y1 - y0),
g = cy0 / n + y0;
if (abs(n) < epsilon$2) return equirectangularRaw;
function project(x, y) {
var gy = g - y, nx = n * x;
return [gy * sin$1(nx), g - gy * cos$1(nx)];
}
project.invert = function(x, y) {
var gy = g - y;
return [atan2(x, abs(gy)) / n * sign(gy), g - sign(n) * sqrt(x * x + gy * gy)];
};
return project;
}
var conicEquidistant = function() {
return conicProjection(conicEquidistantRaw)
.scale(131.154)
.center([0, 13.9389]);
};
function gnomonicRaw(x, y) {
var cy = cos$1(y), k = cos$1(x) * cy;
return [cy * sin$1(x) / k, sin$1(y) / k];
}
gnomonicRaw.invert = azimuthalInvert(atan);
var gnomonic = function() {
return projection(gnomonicRaw)
.scale(144.049)
.clipAngle(60);
};
function scaleTranslate(kx, ky, tx, ty) {
return kx === 1 && ky === 1 && tx === 0 && ty === 0 ? identity$4 : transformer({
point: function(x, y) {
this.stream.point(x * kx + tx, y * ky + ty);
}
});
}
var identity$5 = function() {
var k = 1, tx = 0, ty = 0, sx = 1, sy = 1, transform = identity$4, // scale, translate and reflect
x0 = null, y0, x1, y1, clip = identity$4, // clip extent
cache,
cacheStream,
projection;
function reset() {
cache = cacheStream = null;
return projection;
}
return projection = {
stream: function(stream) {
return cache && cacheStream === stream ? cache : cache = transform(clip(cacheStream = stream));
},
clipExtent: function(_) {
return arguments.length ? (clip = _ == null ? (x0 = y0 = x1 = y1 = null, identity$4) : clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];
},
scale: function(_) {
return arguments.length ? (transform = scaleTranslate((k = +_) * sx, k * sy, tx, ty), reset()) : k;
},
translate: function(_) {
return arguments.length ? (transform = scaleTranslate(k * sx, k * sy, tx = +_[0], ty = +_[1]), reset()) : [tx, ty];
},
reflectX: function(_) {
return arguments.length ? (transform = scaleTranslate(k * (sx = _ ? -1 : 1), k * sy, tx, ty), reset()) : sx < 0;
},
reflectY: function(_) {
return arguments.length ? (transform = scaleTranslate(k * sx, k * (sy = _ ? -1 : 1), tx, ty), reset()) : sy < 0;
},
fitExtent: function(extent, object) {
return fitExtent(projection, extent, object);
},
fitSize: function(size, object) {
return fitSize(projection, size, object);
}
};
};
function orthographicRaw(x, y) {
return [cos$1(y) * sin$1(x), sin$1(y)];
}
orthographicRaw.invert = azimuthalInvert(asin);
var orthographic = function() {
return projection(orthographicRaw)
.scale(249.5)
.clipAngle(90 + epsilon$2);
};
function stereographicRaw(x, y) {
var cy = cos$1(y), k = 1 + cos$1(x) * cy;
return [cy * sin$1(x) / k, sin$1(y) / k];
}
stereographicRaw.invert = azimuthalInvert(function(z) {
return 2 * atan(z);
});
var stereographic = function() {
return projection(stereographicRaw)
.scale(250)
.clipAngle(142);
};
function transverseMercatorRaw(lambda, phi) {
return [log(tan((halfPi$2 + phi) / 2)), -lambda];
}
transverseMercatorRaw.invert = function(x, y) {
return [-y, 2 * atan(exp(x)) - halfPi$2];
};
var transverseMercator = function() {
var m = mercatorProjection(transverseMercatorRaw),
center = m.center,
rotate = m.rotate;
m.center = function(_) {
return arguments.length ? center([-_[1], _[0]]) : (_ = center(), [_[1], -_[0]]);
};
m.rotate = function(_) {
return arguments.length ? rotate([_[0], _[1], _.length > 2 ? _[2] + 90 : 90]) : (_ = rotate(), [_[0], _[1], _[2] - 90]);
};
return rotate([0, 0, 90])
.scale(159.155);
};
function defaultSeparation(a, b) {
return a.parent === b.parent ? 1 : 2;
}
function meanX(children) {
return children.reduce(meanXReduce, 0) / children.length;
}
function meanXReduce(x, c) {
return x + c.x;
}
function maxY(children) {
return 1 + children.reduce(maxYReduce, 0);
}
function maxYReduce(y, c) {
return Math.max(y, c.y);
}
function leafLeft(node) {
var children;
while (children = node.children) node = children[0];
return node;
}
function leafRight(node) {
var children;
while (children = node.children) node = children[children.length - 1];
return node;
}
var cluster = function() {
var separation = defaultSeparation,
dx = 1,
dy = 1,
nodeSize = false;
function cluster(root) {
var previousNode,
x = 0;
// First walk, computing the initial x & y values.
root.eachAfter(function(node) {
var children = node.children;
if (children) {
node.x = meanX(children);
node.y = maxY(children);
} else {
node.x = previousNode ? x += separation(node, previousNode) : 0;
node.y = 0;
previousNode = node;
}
});
var left = leafLeft(root),
right = leafRight(root),
x0 = left.x - separation(left, right) / 2,
x1 = right.x + separation(right, left) / 2;
// Second walk, normalizing x & y to the desired size.
return root.eachAfter(nodeSize ? function(node) {
node.x = (node.x - root.x) * dx;
node.y = (root.y - node.y) * dy;
} : function(node) {
node.x = (node.x - x0) / (x1 - x0) * dx;
node.y = (1 - (root.y ? node.y / root.y : 1)) * dy;
});
}
cluster.separation = function(x) {
return arguments.length ? (separation = x, cluster) : separation;
};
cluster.size = function(x) {
return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? null : [dx, dy]);
};
cluster.nodeSize = function(x) {
return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? [dx, dy] : null);
};
return cluster;
};
function count(node) {
var sum = 0,
children = node.children,
i = children && children.length;
if (!i) sum = 1;
else while (--i >= 0) sum += children[i].value;
node.value = sum;
}
var node_count = function() {
return this.eachAfter(count);
};
var node_each = function(callback) {
var node = this, current, next = [node], children, i, n;
do {
current = next.reverse(), next = [];
while (node = current.pop()) {
callback(node), children = node.children;
if (children) for (i = 0, n = children.length; i < n; ++i) {
next.push(children[i]);
}
}
} while (next.length);
return this;
};
var node_eachBefore = function(callback) {
var node = this, nodes = [node], children, i;
while (node = nodes.pop()) {
callback(node), children = node.children;
if (children) for (i = children.length - 1; i >= 0; --i) {
nodes.push(children[i]);
}
}
return this;
};
var node_eachAfter = function(callback) {
var node = this, nodes = [node], next = [], children, i, n;
while (node = nodes.pop()) {
next.push(node), children = node.children;
if (children) for (i = 0, n = children.length; i < n; ++i) {
nodes.push(children[i]);
}
}
while (node = next.pop()) {
callback(node);
}
return this;
};
var node_sum = function(value) {
return this.eachAfter(function(node) {
var sum = +value(node.data) || 0,
children = node.children,
i = children && children.length;
while (--i >= 0) sum += children[i].value;
node.value = sum;
});
};
var node_sort = function(compare) {
return this.eachBefore(function(node) {
if (node.children) {
node.children.sort(compare);
}
});
};
var node_path = function(end) {
var start = this,
ancestor = leastCommonAncestor(start, end),
nodes = [start];
while (start !== ancestor) {
start = start.parent;
nodes.push(start);
}
var k = nodes.length;
while (end !== ancestor) {
nodes.splice(k, 0, end);
end = end.parent;
}
return nodes;
};
function leastCommonAncestor(a, b) {
if (a === b) return a;
var aNodes = a.ancestors(),
bNodes = b.ancestors(),
c = null;
a = aNodes.pop();
b = bNodes.pop();
while (a === b) {
c = a;
a = aNodes.pop();
b = bNodes.pop();
}
return c;
}
var node_ancestors = function() {
var node = this, nodes = [node];
while (node = node.parent) {
nodes.push(node);
}
return nodes;
};
var node_descendants = function() {
var nodes = [];
this.each(function(node) {
nodes.push(node);
});
return nodes;
};
var node_leaves = function() {
var leaves = [];
this.eachBefore(function(node) {
if (!node.children) {
leaves.push(node);
}
});
return leaves;
};
var node_links = function() {
var root = this, links = [];
root.each(function(node) {
if (node !== root) { // Don’t include the root’s parent, if any.
links.push({source: node.parent, target: node});
}
});
return links;
};
function hierarchy(data, children) {
var root = new Node(data),
valued = +data.value && (root.value = data.value),
node,
nodes = [root],
child,
childs,
i,
n;
if (children == null) children = defaultChildren;
while (node = nodes.pop()) {
if (valued) node.value = +node.data.value;
if ((childs = children(node.data)) && (n = childs.length)) {
node.children = new Array(n);
for (i = n - 1; i >= 0; --i) {
nodes.push(child = node.children[i] = new Node(childs[i]));
child.parent = node;
child.depth = node.depth + 1;
}
}
}
return root.eachBefore(computeHeight);
}
function node_copy() {
return hierarchy(this).eachBefore(copyData);
}
function defaultChildren(d) {
return d.children;
}
function copyData(node) {
node.data = node.data.data;
}
function computeHeight(node) {
var height = 0;
do node.height = height;
while ((node = node.parent) && (node.height < ++height));
}
function Node(data) {
this.data = data;
this.depth =
this.height = 0;
this.parent = null;
}
Node.prototype = hierarchy.prototype = {
constructor: Node,
count: node_count,
each: node_each,
eachAfter: node_eachAfter,
eachBefore: node_eachBefore,
sum: node_sum,
sort: node_sort,
path: node_path,
ancestors: node_ancestors,
descendants: node_descendants,
leaves: node_leaves,
links: node_links,
copy: node_copy
};
var slice$3 = Array.prototype.slice;
function shuffle$1(array) {
var m = array.length,
t,
i;
while (m) {
i = Math.random() * m-- | 0;
t = array[m];
array[m] = array[i];
array[i] = t;
}
return array;
}
var enclose = function(circles) {
var i = 0, n = (circles = shuffle$1(slice$3.call(circles))).length, B = [], p, e;
while (i < n) {
p = circles[i];
if (e && enclosesWeak(e, p)) ++i;
else e = encloseBasis(B = extendBasis(B, p)), i = 0;
}
return e;
};
function extendBasis(B, p) {
var i, j;
if (enclosesWeakAll(p, B)) return [p];
// If we get here then B must have at least one element.
for (i = 0; i < B.length; ++i) {
if (enclosesNot(p, B[i])
&& enclosesWeakAll(encloseBasis2(B[i], p), B)) {
return [B[i], p];
}
}
// If we get here then B must have at least two elements.
for (i = 0; i < B.length - 1; ++i) {
for (j = i + 1; j < B.length; ++j) {
if (enclosesNot(encloseBasis2(B[i], B[j]), p)
&& enclosesNot(encloseBasis2(B[i], p), B[j])
&& enclosesNot(encloseBasis2(B[j], p), B[i])
&& enclosesWeakAll(encloseBasis3(B[i], B[j], p), B)) {
return [B[i], B[j], p];
}
}
}
// If we get here then something is very wrong.
throw new Error;
}
function enclosesNot(a, b) {
var dr = a.r - b.r, dx = b.x - a.x, dy = b.y - a.y;
return dr < 0 || dr * dr < dx * dx + dy * dy;
}
function enclosesWeak(a, b) {
var dr = a.r - b.r + 1e-6, dx = b.x - a.x, dy = b.y - a.y;
return dr > 0 && dr * dr > dx * dx + dy * dy;
}
function enclosesWeakAll(a, B) {
for (var i = 0; i < B.length; ++i) {
if (!enclosesWeak(a, B[i])) {
return false;
}
}
return true;
}
function encloseBasis(B) {
switch (B.length) {
case 1: return encloseBasis1(B[0]);
case 2: return encloseBasis2(B[0], B[1]);
case 3: return encloseBasis3(B[0], B[1], B[2]);
}
}
function encloseBasis1(a) {
return {
x: a.x,
y: a.y,
r: a.r
};
}
function encloseBasis2(a, b) {
var x1 = a.x, y1 = a.y, r1 = a.r,
x2 = b.x, y2 = b.y, r2 = b.r,
x21 = x2 - x1, y21 = y2 - y1, r21 = r2 - r1,
l = Math.sqrt(x21 * x21 + y21 * y21);
return {
x: (x1 + x2 + x21 / l * r21) / 2,
y: (y1 + y2 + y21 / l * r21) / 2,
r: (l + r1 + r2) / 2
};
}
function encloseBasis3(a, b, c) {
var x1 = a.x, y1 = a.y, r1 = a.r,
x2 = b.x, y2 = b.y, r2 = b.r,
x3 = c.x, y3 = c.y, r3 = c.r,
a2 = x1 - x2,
a3 = x1 - x3,
b2 = y1 - y2,
b3 = y1 - y3,
c2 = r2 - r1,
c3 = r3 - r1,
d1 = x1 * x1 + y1 * y1 - r1 * r1,
d2 = d1 - x2 * x2 - y2 * y2 + r2 * r2,
d3 = d1 - x3 * x3 - y3 * y3 + r3 * r3,
ab = a3 * b2 - a2 * b3,
xa = (b2 * d3 - b3 * d2) / (ab * 2) - x1,
xb = (b3 * c2 - b2 * c3) / ab,
ya = (a3 * d2 - a2 * d3) / (ab * 2) - y1,
yb = (a2 * c3 - a3 * c2) / ab,
A = xb * xb + yb * yb - 1,
B = 2 * (r1 + xa * xb + ya * yb),
C = xa * xa + ya * ya - r1 * r1,
r = -(A ? (B + Math.sqrt(B * B - 4 * A * C)) / (2 * A) : C / B);
return {
x: x1 + xa + xb * r,
y: y1 + ya + yb * r,
r: r
};
}
function place(a, b, c) {
var ax = a.x,
ay = a.y,
da = b.r + c.r,
db = a.r + c.r,
dx = b.x - ax,
dy = b.y - ay,
dc = dx * dx + dy * dy;
if (dc) {
var x = 0.5 + ((db *= db) - (da *= da)) / (2 * dc),
y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc);
c.x = ax + x * dx + y * dy;
c.y = ay + x * dy - y * dx;
} else {
c.x = ax + db;
c.y = ay;
}
}
function intersects(a, b) {
var dx = b.x - a.x,
dy = b.y - a.y,
dr = a.r + b.r;
return dr * dr - 1e-6 > dx * dx + dy * dy;
}
function score(node) {
var a = node._,
b = node.next._,
ab = a.r + b.r,
dx = (a.x * b.r + b.x * a.r) / ab,
dy = (a.y * b.r + b.y * a.r) / ab;
return dx * dx + dy * dy;
}
function Node$1(circle) {
this._ = circle;
this.next = null;
this.previous = null;
}
function packEnclose(circles) {
if (!(n = circles.length)) return 0;
var a, b, c, n, aa, ca, i, j, k, sj, sk;
// Place the first circle.
a = circles[0], a.x = 0, a.y = 0;
if (!(n > 1)) return a.r;
// Place the second circle.
b = circles[1], a.x = -b.r, b.x = a.r, b.y = 0;
if (!(n > 2)) return a.r + b.r;
// Place the third circle.
place(b, a, c = circles[2]);
// Initialize the front-chain using the first three circles a, b and c.
a = new Node$1(a), b = new Node$1(b), c = new Node$1(c);
a.next = c.previous = b;
b.next = a.previous = c;
c.next = b.previous = a;
// Attempt to place each remaining circle…
pack: for (i = 3; i < n; ++i) {
place(a._, b._, c = circles[i]), c = new Node$1(c);
// Find the closest intersecting circle on the front-chain, if any.
// “Closeness” is determined by linear distance along the front-chain.
// “Ahead” or “behind” is likewise determined by linear distance.
j = b.next, k = a.previous, sj = b._.r, sk = a._.r;
do {
if (sj <= sk) {
if (intersects(j._, c._)) {
b = j, a.next = b, b.previous = a, --i;
continue pack;
}
sj += j._.r, j = j.next;
} else {
if (intersects(k._, c._)) {
a = k, a.next = b, b.previous = a, --i;
continue pack;
}
sk += k._.r, k = k.previous;
}
} while (j !== k.next);
// Success! Insert the new circle c between a and b.
c.previous = a, c.next = b, a.next = b.previous = b = c;
// Compute the new closest circle pair to the centroid.
aa = score(a);
while ((c = c.next) !== b) {
if ((ca = score(c)) < aa) {
a = c, aa = ca;
}
}
b = a.next;
}
// Compute the enclosing circle of the front chain.
a = [b._], c = b; while ((c = c.next) !== b) a.push(c._); c = enclose(a);
// Translate the circles to put the enclosing circle around the origin.
for (i = 0; i < n; ++i) a = circles[i], a.x -= c.x, a.y -= c.y;
return c.r;
}
var siblings = function(circles) {
packEnclose(circles);
return circles;
};
function optional(f) {
return f == null ? null : required(f);
}
function required(f) {
if (typeof f !== "function") throw new Error;
return f;
}
function constantZero() {
return 0;
}
var constant$8 = function(x) {
return function() {
return x;
};
};
function defaultRadius$1(d) {
return Math.sqrt(d.value);
}
var index$2 = function() {
var radius = null,
dx = 1,
dy = 1,
padding = constantZero;
function pack(root) {
root.x = dx / 2, root.y = dy / 2;
if (radius) {
root.eachBefore(radiusLeaf(radius))
.eachAfter(packChildren(padding, 0.5))
.eachBefore(translateChild(1));
} else {
root.eachBefore(radiusLeaf(defaultRadius$1))
.eachAfter(packChildren(constantZero, 1))
.eachAfter(packChildren(padding, root.r / Math.min(dx, dy)))
.eachBefore(translateChild(Math.min(dx, dy) / (2 * root.r)));
}
return root;
}
pack.radius = function(x) {
return arguments.length ? (radius = optional(x), pack) : radius;
};
pack.size = function(x) {
return arguments.length ? (dx = +x[0], dy = +x[1], pack) : [dx, dy];
};
pack.padding = function(x) {
return arguments.length ? (padding = typeof x === "function" ? x : constant$8(+x), pack) : padding;
};
return pack;
};
function radiusLeaf(radius) {
return function(node) {
if (!node.children) {
node.r = Math.max(0, +radius(node) || 0);
}
};
}
function packChildren(padding, k) {
return function(node) {
if (children = node.children) {
var children,
i,
n = children.length,
r = padding(node) * k || 0,
e;
if (r) for (i = 0; i < n; ++i) children[i].r += r;
e = packEnclose(children);
if (r) for (i = 0; i < n; ++i) children[i].r -= r;
node.r = e + r;
}
};
}
function translateChild(k) {
return function(node) {
var parent = node.parent;
node.r *= k;
if (parent) {
node.x = parent.x + k * node.x;
node.y = parent.y + k * node.y;
}
};
}
var roundNode = function(node) {
node.x0 = Math.round(node.x0);
node.y0 = Math.round(node.y0);
node.x1 = Math.round(node.x1);
node.y1 = Math.round(node.y1);
};
var treemapDice = function(parent, x0, y0, x1, y1) {
var nodes = parent.children,
node,
i = -1,
n = nodes.length,
k = parent.value && (x1 - x0) / parent.value;
while (++i < n) {
node = nodes[i], node.y0 = y0, node.y1 = y1;
node.x0 = x0, node.x1 = x0 += node.value * k;
}
};
var partition = function() {
var dx = 1,
dy = 1,
padding = 0,
round = false;
function partition(root) {
var n = root.height + 1;
root.x0 =
root.y0 = padding;
root.x1 = dx;
root.y1 = dy / n;
root.eachBefore(positionNode(dy, n));
if (round) root.eachBefore(roundNode);
return root;
}
function positionNode(dy, n) {
return function(node) {
if (node.children) {
treemapDice(node, node.x0, dy * (node.depth + 1) / n, node.x1, dy * (node.depth + 2) / n);
}
var x0 = node.x0,
y0 = node.y0,
x1 = node.x1 - padding,
y1 = node.y1 - padding;
if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
node.x0 = x0;
node.y0 = y0;
node.x1 = x1;
node.y1 = y1;
};
}
partition.round = function(x) {
return arguments.length ? (round = !!x, partition) : round;
};
partition.size = function(x) {
return arguments.length ? (dx = +x[0], dy = +x[1], partition) : [dx, dy];
};
partition.padding = function(x) {
return arguments.length ? (padding = +x, partition) : padding;
};
return partition;
};
var keyPrefix$1 = "$";
var preroot = {depth: -1};
var ambiguous = {};
function defaultId(d) {
return d.id;
}
function defaultParentId(d) {
return d.parentId;
}
var stratify = function() {
var id = defaultId,
parentId = defaultParentId;
function stratify(data) {
var d,
i,
n = data.length,
root,
parent,
node,
nodes = new Array(n),
nodeId,
nodeKey,
nodeByKey = {};
for (i = 0; i < n; ++i) {
d = data[i], node = nodes[i] = new Node(d);
if ((nodeId = id(d, i, data)) != null && (nodeId += "")) {
nodeKey = keyPrefix$1 + (node.id = nodeId);
nodeByKey[nodeKey] = nodeKey in nodeByKey ? ambiguous : node;
}
}
for (i = 0; i < n; ++i) {
node = nodes[i], nodeId = parentId(data[i], i, data);
if (nodeId == null || !(nodeId += "")) {
if (root) throw new Error("multiple roots");
root = node;
} else {
parent = nodeByKey[keyPrefix$1 + nodeId];
if (!parent) throw new Error("missing: " + nodeId);
if (parent === ambiguous) throw new Error("ambiguous: " + nodeId);
if (parent.children) parent.children.push(node);
else parent.children = [node];
node.parent = parent;
}
}
if (!root) throw new Error("no root");
root.parent = preroot;
root.eachBefore(function(node) { node.depth = node.parent.depth + 1; --n; }).eachBefore(computeHeight);
root.parent = null;
if (n > 0) throw new Error("cycle");
return root;
}
stratify.id = function(x) {
return arguments.length ? (id = required(x), stratify) : id;
};
stratify.parentId = function(x) {
return arguments.length ? (parentId = required(x), stratify) : parentId;
};
return stratify;
};
function defaultSeparation$1(a, b) {
return a.parent === b.parent ? 1 : 2;
}
// function radialSeparation(a, b) {
// return (a.parent === b.parent ? 1 : 2) / a.depth;
// }
// This function is used to traverse the left contour of a subtree (or
// subforest). It returns the successor of v on this contour. This successor is
// either given by the leftmost child of v or by the thread of v. The function
// returns null if and only if v is on the highest level of its subtree.
function nextLeft(v) {
var children = v.children;
return children ? children[0] : v.t;
}
// This function works analogously to nextLeft.
function nextRight(v) {
var children = v.children;
return children ? children[children.length - 1] : v.t;
}
// Shifts the current subtree rooted at w+. This is done by increasing
// prelim(w+) and mod(w+) by shift.
function moveSubtree(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;
}
// All other shifts, applied to the smaller subtrees between w- and w+, are
// performed by this function. To prepare the shifts, we have to adjust
// change(w+), shift(w+), and change(w-).
function executeShifts(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);
}
}
// If vi-’s ancestor is a sibling of v, returns vi-’s ancestor. Otherwise,
// returns the specified (default) ancestor.
function nextAncestor(vim, v, ancestor) {
return vim.a.parent === v.parent ? vim.a : ancestor;
}
function TreeNode(node, i) {
this._ = node;
this.parent = null;
this.children = null;
this.A = null; // default ancestor
this.a = this; // ancestor
this.z = 0; // prelim
this.m = 0; // mod
this.c = 0; // change
this.s = 0; // shift
this.t = null; // thread
this.i = i; // number
}
TreeNode.prototype = Object.create(Node.prototype);
function treeRoot(root) {
var tree = new TreeNode(root, 0),
node,
nodes = [tree],
child,
children,
i,
n;
while (node = nodes.pop()) {
if (children = node._.children) {
node.children = new Array(n = children.length);
for (i = n - 1; i >= 0; --i) {
nodes.push(child = node.children[i] = new TreeNode(children[i], i));
child.parent = node;
}
}
}
(tree.parent = new TreeNode(null, 0)).children = [tree];
return tree;
}
// Node-link tree diagram using the Reingold-Tilford "tidy" algorithm
var tree = function() {
var separation = defaultSeparation$1,
dx = 1,
dy = 1,
nodeSize = null;
function tree(root) {
var t = treeRoot(root);
// Compute the layout using Buchheim et al.’s algorithm.
t.eachAfter(firstWalk), t.parent.m = -t.z;
t.eachBefore(secondWalk);
// If a fixed node size is specified, scale x and y.
if (nodeSize) root.eachBefore(sizeNode);
// If a fixed tree size is specified, scale x and y based on the extent.
// Compute the left-most, right-most, and depth-most nodes for extents.
else {
var left = root,
right = root,
bottom = root;
root.eachBefore(function(node) {
if (node.x < left.x) left = node;
if (node.x > right.x) right = node;
if (node.depth > bottom.depth) bottom = node;
});
var s = left === right ? 1 : separation(left, right) / 2,
tx = s - left.x,
kx = dx / (right.x + s + tx),
ky = dy / (bottom.depth || 1);
root.eachBefore(function(node) {
node.x = (node.x + tx) * kx;
node.y = node.depth * ky;
});
}
return root;
}
// Computes a preliminary x-coordinate for v. Before that, FIRST WALK is
// applied recursively to the children of v, as well as the function
// APPORTION. After spacing out the children by calling EXECUTE SHIFTS, the
// node v is placed to the midpoint of its outermost children.
function firstWalk(v) {
var children = v.children,
siblings = v.parent.children,
w = v.i ? siblings[v.i - 1] : null;
if (children) {
executeShifts(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]);
}
// Computes all real x-coordinates by summing up the modifiers recursively.
function secondWalk(v) {
v._.x = v.z + v.parent.m;
v.m += v.parent.m;
}
// The core of the algorithm. Here, a new subtree is combined with the
// previous subtrees. Threads are used to traverse the inside and outside
// contours of the left and right subtree up to the highest common level. The
// vertices used for the traversals are vi+, vi-, vo-, and vo+, where the
// superscript o means outside and i means inside, the subscript - means left
// subtree and + means right subtree. For summing up the modifiers along the
// contour, we use respective variables si+, si-, so-, and so+. Whenever two
// nodes of the inside contours conflict, we compute the left one of the
// greatest uncommon ancestors using the function ANCESTOR and call MOVE
// SUBTREE to shift the subtree and prepare the shifts of smaller subtrees.
// Finally, we add a new thread (if necessary).
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 = nextRight(vim), vip = nextLeft(vip), vim && vip) {
vom = nextLeft(vom);
vop = nextRight(vop);
vop.a = v;
shift = vim.z + sim - vip.z - sip + separation(vim._, vip._);
if (shift > 0) {
moveSubtree(nextAncestor(vim, v, ancestor), v, shift);
sip += shift;
sop += shift;
}
sim += vim.m;
sip += vip.m;
som += vom.m;
sop += vop.m;
}
if (vim && !nextRight(vop)) {
vop.t = vim;
vop.m += sim - sop;
}
if (vip && !nextLeft(vom)) {
vom.t = vip;
vom.m += sip - som;
ancestor = v;
}
}
return ancestor;
}
function sizeNode(node) {
node.x *= dx;
node.y = node.depth * dy;
}
tree.separation = function(x) {
return arguments.length ? (separation = x, tree) : separation;
};
tree.size = function(x) {
return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], tree) : (nodeSize ? null : [dx, dy]);
};
tree.nodeSize = function(x) {
return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], tree) : (nodeSize ? [dx, dy] : null);
};
return tree;
};
var treemapSlice = function(parent, x0, y0, x1, y1) {
var nodes = parent.children,
node,
i = -1,
n = nodes.length,
k = parent.value && (y1 - y0) / parent.value;
while (++i < n) {
node = nodes[i], node.x0 = x0, node.x1 = x1;
node.y0 = y0, node.y1 = y0 += node.value * k;
}
};
var phi = (1 + Math.sqrt(5)) / 2;
function squarifyRatio(ratio, parent, x0, y0, x1, y1) {
var rows = [],
nodes = parent.children,
row,
nodeValue,
i0 = 0,
i1 = 0,
n = nodes.length,
dx, dy,
value = parent.value,
sumValue,
minValue,
maxValue,
newRatio,
minRatio,
alpha,
beta;
while (i0 < n) {
dx = x1 - x0, dy = y1 - y0;
// Find the next non-empty node.
do sumValue = nodes[i1++].value; while (!sumValue && i1 < n);
minValue = maxValue = sumValue;
alpha = Math.max(dy / dx, dx / dy) / (value * ratio);
beta = sumValue * sumValue * alpha;
minRatio = Math.max(maxValue / beta, beta / minValue);
// Keep adding nodes while the aspect ratio maintains or improves.
for (; i1 < n; ++i1) {
sumValue += nodeValue = nodes[i1].value;
if (nodeValue < minValue) minValue = nodeValue;
if (nodeValue > maxValue) maxValue = nodeValue;
beta = sumValue * sumValue * alpha;
newRatio = Math.max(maxValue / beta, beta / minValue);
if (newRatio > minRatio) { sumValue -= nodeValue; break; }
minRatio = newRatio;
}
// Position and record the row orientation.
rows.push(row = {value: sumValue, dice: dx < dy, children: nodes.slice(i0, i1)});
if (row.dice) treemapDice(row, x0, y0, x1, value ? y0 += dy * sumValue / value : y1);
else treemapSlice(row, x0, y0, value ? x0 += dx * sumValue / value : x1, y1);
value -= sumValue, i0 = i1;
}
return rows;
}
var squarify = ((function custom(ratio) {
function squarify(parent, x0, y0, x1, y1) {
squarifyRatio(ratio, parent, x0, y0, x1, y1);
}
squarify.ratio = function(x) {
return custom((x = +x) > 1 ? x : 1);
};
return squarify;
}))(phi);
var index$3 = function() {
var tile = squarify,
round = false,
dx = 1,
dy = 1,
paddingStack = [0],
paddingInner = constantZero,
paddingTop = constantZero,
paddingRight = constantZero,
paddingBottom = constantZero,
paddingLeft = constantZero;
function treemap(root) {
root.x0 =
root.y0 = 0;
root.x1 = dx;
root.y1 = dy;
root.eachBefore(positionNode);
paddingStack = [0];
if (round) root.eachBefore(roundNode);
return root;
}
function positionNode(node) {
var p = paddingStack[node.depth],
x0 = node.x0 + p,
y0 = node.y0 + p,
x1 = node.x1 - p,
y1 = node.y1 - p;
if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
node.x0 = x0;
node.y0 = y0;
node.x1 = x1;
node.y1 = y1;
if (node.children) {
p = paddingStack[node.depth + 1] = paddingInner(node) / 2;
x0 += paddingLeft(node) - p;
y0 += paddingTop(node) - p;
x1 -= paddingRight(node) - p;
y1 -= paddingBottom(node) - p;
if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
tile(node, x0, y0, x1, y1);
}
}
treemap.round = function(x) {
return arguments.length ? (round = !!x, treemap) : round;
};
treemap.size = function(x) {
return arguments.length ? (dx = +x[0], dy = +x[1], treemap) : [dx, dy];
};
treemap.tile = function(x) {
return arguments.length ? (tile = required(x), treemap) : tile;
};
treemap.padding = function(x) {
return arguments.length ? treemap.paddingInner(x).paddingOuter(x) : treemap.paddingInner();
};
treemap.paddingInner = function(x) {
return arguments.length ? (paddingInner = typeof x === "function" ? x : constant$8(+x), treemap) : paddingInner;
};
treemap.paddingOuter = function(x) {
return arguments.length ? treemap.paddingTop(x).paddingRight(x).paddingBottom(x).paddingLeft(x) : treemap.paddingTop();
};
treemap.paddingTop = function(x) {
return arguments.length ? (paddingTop = typeof x === "function" ? x : constant$8(+x), treemap) : paddingTop;
};
treemap.paddingRight = function(x) {
return arguments.length ? (paddingRight = typeof x === "function" ? x : constant$8(+x), treemap) : paddingRight;
};
treemap.paddingBottom = function(x) {
return arguments.length ? (paddingBottom = typeof x === "function" ? x : constant$8(+x), treemap) : paddingBottom;
};
treemap.paddingLeft = function(x) {
return arguments.length ? (paddingLeft = typeof x === "function" ? x : constant$8(+x), treemap) : paddingLeft;
};
return treemap;
};
var binary = function(parent, x0, y0, x1, y1) {
var nodes = parent.children,
i, n = nodes.length,
sum, sums = new Array(n + 1);
for (sums[0] = sum = i = 0; i < n; ++i) {
sums[i + 1] = sum += nodes[i].value;
}
partition(0, n, parent.value, x0, y0, x1, y1);
function partition(i, j, value, x0, y0, x1, y1) {
if (i >= j - 1) {
var node = nodes[i];
node.x0 = x0, node.y0 = y0;
node.x1 = x1, node.y1 = y1;
return;
}
var valueOffset = sums[i],
valueTarget = (value / 2) + valueOffset,
k = i + 1,
hi = j - 1;
while (k < hi) {
var mid = k + hi >>> 1;
if (sums[mid] < valueTarget) k = mid + 1;
else hi = mid;
}
if ((valueTarget - sums[k - 1]) < (sums[k] - valueTarget) && i + 1 < k) --k;
var valueLeft = sums[k] - valueOffset,
valueRight = value - valueLeft;
if ((x1 - x0) > (y1 - y0)) {
var xk = (x0 * valueRight + x1 * valueLeft) / value;
partition(i, k, valueLeft, x0, y0, xk, y1);
partition(k, j, valueRight, xk, y0, x1, y1);
} else {
var yk = (y0 * valueRight + y1 * valueLeft) / value;
partition(i, k, valueLeft, x0, y0, x1, yk);
partition(k, j, valueRight, x0, yk, x1, y1);
}
}
};
var sliceDice = function(parent, x0, y0, x1, y1) {
(parent.depth & 1 ? treemapSlice : treemapDice)(parent, x0, y0, x1, y1);
};
var resquarify = ((function custom(ratio) {
function resquarify(parent, x0, y0, x1, y1) {
if ((rows = parent._squarify) && (rows.ratio === ratio)) {
var rows,
row,
nodes,
i,
j = -1,
n,
m = rows.length,
value = parent.value;
while (++j < m) {
row = rows[j], nodes = row.children;
for (i = row.value = 0, n = nodes.length; i < n; ++i) row.value += nodes[i].value;
if (row.dice) treemapDice(row, x0, y0, x1, y0 += (y1 - y0) * row.value / value);
else treemapSlice(row, x0, y0, x0 += (x1 - x0) * row.value / value, y1);
value -= row.value;
}
} else {
parent._squarify = rows = squarifyRatio(ratio, parent, x0, y0, x1, y1);
rows.ratio = ratio;
}
}
resquarify.ratio = function(x) {
return custom((x = +x) > 1 ? x : 1);
};
return resquarify;
}))(phi);
var area$1 = function(polygon) {
var i = -1,
n = polygon.length,
a,
b = polygon[n - 1],
area = 0;
while (++i < n) {
a = b;
b = polygon[i];
area += a[1] * b[0] - a[0] * b[1];
}
return area / 2;
};
var centroid$1 = function(polygon) {
var i = -1,
n = polygon.length,
x = 0,
y = 0,
a,
b = polygon[n - 1],
c,
k = 0;
while (++i < n) {
a = b;
b = polygon[i];
k += c = a[0] * b[1] - b[0] * a[1];
x += (a[0] + b[0]) * c;
y += (a[1] + b[1]) * c;
}
return k *= 3, [x / k, y / k];
};
// Returns the 2D cross product of AB and AC vectors, i.e., the z-component of
// the 3D cross product in a quadrant I Cartesian coordinate system (+x is
// right, +y is up). Returns a positive value if ABC is counter-clockwise,
// negative if clockwise, and zero if the points are collinear.
var cross$1 = function(a, b, c) {
return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);
};
function lexicographicOrder(a, b) {
return a[0] - b[0] || a[1] - b[1];
}
// Computes the upper convex hull per the monotone chain algorithm.
// Assumes points.length >= 3, is sorted by x, unique in y.
// Returns an array of indices into points in left-to-right order.
function computeUpperHullIndexes(points) {
var n = points.length,
indexes = [0, 1],
size = 2;
for (var i = 2; i < n; ++i) {
while (size > 1 && cross$1(points[indexes[size - 2]], points[indexes[size - 1]], points[i]) <= 0) --size;
indexes[size++] = i;
}
return indexes.slice(0, size); // remove popped points
}
var hull = function(points) {
if ((n = points.length) < 3) return null;
var i,
n,
sortedPoints = new Array(n),
flippedPoints = new Array(n);
for (i = 0; i < n; ++i) sortedPoints[i] = [+points[i][0], +points[i][1], i];
sortedPoints.sort(lexicographicOrder);
for (i = 0; i < n; ++i) flippedPoints[i] = [sortedPoints[i][0], -sortedPoints[i][1]];
var upperIndexes = computeUpperHullIndexes(sortedPoints),
lowerIndexes = computeUpperHullIndexes(flippedPoints);
// Construct the hull polygon, removing possible duplicate endpoints.
var skipLeft = lowerIndexes[0] === upperIndexes[0],
skipRight = lowerIndexes[lowerIndexes.length - 1] === upperIndexes[upperIndexes.length - 1],
hull = [];
// Add upper hull in right-to-l order.
// Then add lower hull in left-to-right order.
for (i = upperIndexes.length - 1; i >= 0; --i) hull.push(points[sortedPoints[upperIndexes[i]][2]]);
for (i = +skipLeft; i < lowerIndexes.length - skipRight; ++i) hull.push(points[sortedPoints[lowerIndexes[i]][2]]);
return hull;
};
var contains$1 = function(polygon, point) {
var n = polygon.length,
p = polygon[n - 1],
x = point[0], y = point[1],
x0 = p[0], y0 = p[1],
x1, y1,
inside = false;
for (var i = 0; i < n; ++i) {
p = polygon[i], x1 = p[0], y1 = p[1];
if (((y1 > y) !== (y0 > y)) && (x < (x0 - x1) * (y - y1) / (y0 - y1) + x1)) inside = !inside;
x0 = x1, y0 = y1;
}
return inside;
};
var length$2 = function(polygon) {
var i = -1,
n = polygon.length,
b = polygon[n - 1],
xa,
ya,
xb = b[0],
yb = b[1],
perimeter = 0;
while (++i < n) {
xa = xb;
ya = yb;
b = polygon[i];
xb = b[0];
yb = b[1];
xa -= xb;
ya -= yb;
perimeter += Math.sqrt(xa * xa + ya * ya);
}
return perimeter;
};
var slice$4 = [].slice;
var noabort = {};
function Queue(size) {
this._size = size;
this._call =
this._error = null;
this._tasks = [];
this._data = [];
this._waiting =
this._active =
this._ended =
this._start = 0; // inside a synchronous task callback?
}
Queue.prototype = queue.prototype = {
constructor: Queue,
defer: function(callback) {
if (typeof callback !== "function") throw new Error("invalid callback");
if (this._call) throw new Error("defer after await");
if (this._error != null) return this;
var t = slice$4.call(arguments, 1);
t.push(callback);
++this._waiting, this._tasks.push(t);
poke$1(this);
return this;
},
abort: function() {
if (this._error == null) abort(this, new Error("abort"));
return this;
},
await: function(callback) {
if (typeof callback !== "function") throw new Error("invalid callback");
if (this._call) throw new Error("multiple await");
this._call = function(error, results) { callback.apply(null, [error].concat(results)); };
maybeNotify(this);
return this;
},
awaitAll: function(callback) {
if (typeof callback !== "function") throw new Error("invalid callback");
if (this._call) throw new Error("multiple await");
this._call = callback;
maybeNotify(this);
return this;
}
};
function poke$1(q) {
if (!q._start) {
try { start$1(q); } // let the current task complete
catch (e) {
if (q._tasks[q._ended + q._active - 1]) abort(q, e); // task errored synchronously
else if (!q._data) throw e; // await callback errored synchronously
}
}
}
function start$1(q) {
while (q._start = q._waiting && q._active < q._size) {
var i = q._ended + q._active,
t = q._tasks[i],
j = t.length - 1,
c = t[j];
t[j] = end(q, i);
--q._waiting, ++q._active;
t = c.apply(null, t);
if (!q._tasks[i]) continue; // task finished synchronously
q._tasks[i] = t || noabort;
}
}
function end(q, i) {
return function(e, r) {
if (!q._tasks[i]) return; // ignore multiple callbacks
--q._active, ++q._ended;
q._tasks[i] = null;
if (q._error != null) return; // ignore secondary errors
if (e != null) {
abort(q, e);
} else {
q._data[i] = r;
if (q._waiting) poke$1(q);
else maybeNotify(q);
}
};
}
function abort(q, e) {
var i = q._tasks.length, t;
q._error = e; // ignore active callbacks
q._data = undefined; // allow gc
q._waiting = NaN; // prevent starting
while (--i >= 0) {
if (t = q._tasks[i]) {
q._tasks[i] = null;
if (t.abort) {
try { t.abort(); }
catch (e) { /* ignore */ }
}
}
}
q._active = NaN; // allow notification
maybeNotify(q);
}
function maybeNotify(q) {
if (!q._active && q._call) {
var d = q._data;
q._data = undefined; // allow gc
q._call(q._error, d);
}
}
function queue(concurrency) {
if (concurrency == null) concurrency = Infinity;
else if (!((concurrency = +concurrency) >= 1)) throw new Error("invalid concurrency");
return new Queue(concurrency);
}
var defaultSource$1 = function() {
return Math.random();
};
var uniform = ((function sourceRandomUniform(source) {
function randomUniform(min, max) {
min = min == null ? 0 : +min;
max = max == null ? 1 : +max;
if (arguments.length === 1) max = min, min = 0;
else max -= min;
return function() {
return source() * max + min;
};
}
randomUniform.source = sourceRandomUniform;
return randomUniform;
}))(defaultSource$1);
var normal = ((function sourceRandomNormal(source) {
function randomNormal(mu, sigma) {
var x, r;
mu = mu == null ? 0 : +mu;
sigma = sigma == null ? 1 : +sigma;
return function() {
var y;
// If available, use the second previously-generated uniform random.
if (x != null) y = x, x = null;
// Otherwise, generate a new x and y.
else do {
x = source() * 2 - 1;
y = source() * 2 - 1;
r = x * x + y * y;
} while (!r || r > 1);
return mu + sigma * y * Math.sqrt(-2 * Math.log(r) / r);
};
}
randomNormal.source = sourceRandomNormal;
return randomNormal;
}))(defaultSource$1);
var logNormal = ((function sourceRandomLogNormal(source) {
function randomLogNormal() {
var randomNormal = normal.source(source).apply(this, arguments);
return function() {
return Math.exp(randomNormal());
};
}
randomLogNormal.source = sourceRandomLogNormal;
return randomLogNormal;
}))(defaultSource$1);
var irwinHall = ((function sourceRandomIrwinHall(source) {
function randomIrwinHall(n) {
return function() {
for (var sum = 0, i = 0; i < n; ++i) sum += source();
return sum;
};
}
randomIrwinHall.source = sourceRandomIrwinHall;
return randomIrwinHall;
}))(defaultSource$1);
var bates = ((function sourceRandomBates(source) {
function randomBates(n) {
var randomIrwinHall = irwinHall.source(source)(n);
return function() {
return randomIrwinHall() / n;
};
}
randomBates.source = sourceRandomBates;
return randomBates;
}))(defaultSource$1);
var exponential$1 = ((function sourceRandomExponential(source) {
function randomExponential(lambda) {
return function() {
return -Math.log(1 - source()) / lambda;
};
}
randomExponential.source = sourceRandomExponential;
return randomExponential;
}))(defaultSource$1);
var request = function(url, callback) {
var request,
event = dispatch("beforesend", "progress", "load", "error"),
mimeType,
headers = map$1(),
xhr = new XMLHttpRequest,
user = null,
password = null,
response,
responseType,
timeout = 0;
// If IE does not support CORS, use XDomainRequest.
if (typeof XDomainRequest !== "undefined"
&& !("withCredentials" in xhr)
&& /^(http(s)?:)?\/\//.test(url)) xhr = new XDomainRequest;
"onload" in xhr
? xhr.onload = xhr.onerror = xhr.ontimeout = respond
: xhr.onreadystatechange = function(o) { xhr.readyState > 3 && respond(o); };
function respond(o) {
var status = xhr.status, result;
if (!status && hasResponse(xhr)
|| status >= 200 && status < 300
|| status === 304) {
if (response) {
try {
result = response.call(request, xhr);
} catch (e) {
event.call("error", request, e);
return;
}
} else {
result = xhr;
}
event.call("load", request, result);
} else {
event.call("error", request, o);
}
}
xhr.onprogress = function(e) {
event.call("progress", request, e);
};
request = {
header: function(name, value) {
name = (name + "").toLowerCase();
if (arguments.length < 2) return headers.get(name);
if (value == null) headers.remove(name);
else headers.set(name, value + "");
return request;
},
// If mimeType is non-null and no Accept header is set, a default is used.
mimeType: function(value) {
if (!arguments.length) return mimeType;
mimeType = value == null ? null : value + "";
return request;
},
// Specifies what type the response value should take;
// for instance, arraybuffer, blob, document, or text.
responseType: function(value) {
if (!arguments.length) return responseType;
responseType = value;
return request;
},
timeout: function(value) {
if (!arguments.length) return timeout;
timeout = +value;
return request;
},
user: function(value) {
return arguments.length < 1 ? user : (user = value == null ? null : value + "", request);
},
password: function(value) {
return arguments.length < 1 ? password : (password = value == null ? null : value + "", request);
},
// Specify how to convert the response content to a specific type;
// changes the callback value on "load" events.
response: function(value) {
response = value;
return request;
},
// Alias for send("GET", …).
get: function(data, callback) {
return request.send("GET", data, callback);
},
// Alias for send("POST", …).
post: function(data, callback) {
return request.send("POST", data, callback);
},
// If callback is non-null, it will be used for error and load events.
send: function(method, data, callback) {
xhr.open(method, url, true, user, password);
if (mimeType != null && !headers.has("accept")) headers.set("accept", mimeType + ",*/*");
if (xhr.setRequestHeader) headers.each(function(value, name) { xhr.setRequestHeader(name, value); });
if (mimeType != null && xhr.overrideMimeType) xhr.overrideMimeType(mimeType);
if (responseType != null) xhr.responseType = responseType;
if (timeout > 0) xhr.timeout = timeout;
if (callback == null && typeof data === "function") callback = data, data = null;
if (callback != null && callback.length === 1) callback = fixCallback(callback);
if (callback != null) request.on("error", callback).on("load", function(xhr) { callback(null, xhr); });
event.call("beforesend", request, xhr);
xhr.send(data == null ? null : data);
return request;
},
abort: function() {
xhr.abort();
return request;
},
on: function() {
var value = event.on.apply(event, arguments);
return value === event ? request : value;
}
};
if (callback != null) {
if (typeof callback !== "function") throw new Error("invalid callback: " + callback);
return request.get(callback);
}
return request;
};
function fixCallback(callback) {
return function(error, xhr) {
callback(error == null ? xhr : null);
};
}
function hasResponse(xhr) {
var type = xhr.responseType;
return type && type !== "text"
? xhr.response // null on error
: xhr.responseText; // "" on error
}
var type$1 = function(defaultMimeType, response) {
return function(url, callback) {
var r = request(url).mimeType(defaultMimeType).response(response);
if (callback != null) {
if (typeof callback !== "function") throw new Error("invalid callback: " + callback);
return r.get(callback);
}
return r;
};
};
var html = type$1("text/html", function(xhr) {
return document.createRange().createContextualFragment(xhr.responseText);
});
var json = type$1("application/json", function(xhr) {
return JSON.parse(xhr.responseText);
});
var text = type$1("text/plain", function(xhr) {
return xhr.responseText;
});
var xml = type$1("application/xml", function(xhr) {
var xml = xhr.responseXML;
if (!xml) throw new Error("parse error");
return xml;
});
var dsv$1 = function(defaultMimeType, parse) {
return function(url, row, callback) {
if (arguments.length < 3) callback = row, row = null;
var r = request(url).mimeType(defaultMimeType);
r.row = function(_) { return arguments.length ? r.response(responseOf(parse, row = _)) : row; };
r.row(row);
return callback ? r.get(callback) : r;
};
};
function responseOf(parse, row) {
return function(request$$1) {
return parse(request$$1.responseText, row);
};
}
var csv$1 = dsv$1("text/csv", csvParse);
var tsv$1 = dsv$1("text/tab-separated-values", tsvParse);
var array$2 = Array.prototype;
var map$3 = array$2.map;
var slice$5 = array$2.slice;
var implicit = {name: "implicit"};
function ordinal(range) {
var index = map$1(),
domain = [],
unknown = implicit;
range = range == null ? [] : slice$5.call(range);
function scale(d) {
var key = d + "", i = index.get(key);
if (!i) {
if (unknown !== implicit) return unknown;
index.set(key, i = domain.push(d));
}
return range[(i - 1) % range.length];
}
scale.domain = function(_) {
if (!arguments.length) return domain.slice();
domain = [], index = map$1();
var i = -1, n = _.length, d, key;
while (++i < n) if (!index.has(key = (d = _[i]) + "")) index.set(key, domain.push(d));
return scale;
};
scale.range = function(_) {
return arguments.length ? (range = slice$5.call(_), scale) : range.slice();
};
scale.unknown = function(_) {
return arguments.length ? (unknown = _, scale) : unknown;
};
scale.copy = function() {
return ordinal()
.domain(domain)
.range(range)
.unknown(unknown);
};
return scale;
}
function band() {
var scale = ordinal().unknown(undefined),
domain = scale.domain,
ordinalRange = scale.range,
range$$1 = [0, 1],
step,
bandwidth,
round = false,
paddingInner = 0,
paddingOuter = 0,
align = 0.5;
delete scale.unknown;
function rescale() {
var n = domain().length,
reverse = range$$1[1] < range$$1[0],
start = range$$1[reverse - 0],
stop = range$$1[1 - reverse];
step = (stop - start) / Math.max(1, n - paddingInner + paddingOuter * 2);
if (round) step = Math.floor(step);
start += (stop - start - step * (n - paddingInner)) * align;
bandwidth = step * (1 - paddingInner);
if (round) start = Math.round(start), bandwidth = Math.round(bandwidth);
var values = sequence(n).map(function(i) { return start + step * i; });
return ordinalRange(reverse ? values.reverse() : values);
}
scale.domain = function(_) {
return arguments.length ? (domain(_), rescale()) : domain();
};
scale.range = function(_) {
return arguments.length ? (range$$1 = [+_[0], +_[1]], rescale()) : range$$1.slice();
};
scale.rangeRound = function(_) {
return range$$1 = [+_[0], +_[1]], round = true, rescale();
};
scale.bandwidth = function() {
return bandwidth;
};
scale.step = function() {
return step;
};
scale.round = function(_) {
return arguments.length ? (round = !!_, rescale()) : round;
};
scale.padding = function(_) {
return arguments.length ? (paddingInner = paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;
};
scale.paddingInner = function(_) {
return arguments.length ? (paddingInner = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;
};
scale.paddingOuter = function(_) {
return arguments.length ? (paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingOuter;
};
scale.align = function(_) {
return arguments.length ? (align = Math.max(0, Math.min(1, _)), rescale()) : align;
};
scale.copy = function() {
return band()
.domain(domain())
.range(range$$1)
.round(round)
.paddingInner(paddingInner)
.paddingOuter(paddingOuter)
.align(align);
};
return rescale();
}
function pointish(scale) {
var copy = scale.copy;
scale.padding = scale.paddingOuter;
delete scale.paddingInner;
delete scale.paddingOuter;
scale.copy = function() {
return pointish(copy());
};
return scale;
}
function point$1() {
return pointish(band().paddingInner(1));
}
var constant$9 = function(x) {
return function() {
return x;
};
};
var number$2 = function(x) {
return +x;
};
var unit = [0, 1];
function deinterpolateLinear(a, b) {
return (b -= (a = +a))
? function(x) { return (x - a) / b; }
: constant$9(b);
}
function deinterpolateClamp(deinterpolate) {
return function(a, b) {
var d = deinterpolate(a = +a, b = +b);
return function(x) { return x <= a ? 0 : x >= b ? 1 : d(x); };
};
}
function reinterpolateClamp(reinterpolate) {
return function(a, b) {
var r = reinterpolate(a = +a, b = +b);
return function(t) { return t <= 0 ? a : t >= 1 ? b : r(t); };
};
}
function bimap(domain, range$$1, deinterpolate, reinterpolate) {
var d0 = domain[0], d1 = domain[1], r0 = range$$1[0], r1 = range$$1[1];
if (d1 < d0) d0 = deinterpolate(d1, d0), r0 = reinterpolate(r1, r0);
else d0 = deinterpolate(d0, d1), r0 = reinterpolate(r0, r1);
return function(x) { return r0(d0(x)); };
}
function polymap(domain, range$$1, deinterpolate, reinterpolate) {
var j = Math.min(domain.length, range$$1.length) - 1,
d = new Array(j),
r = new Array(j),
i = -1;
// Reverse descending domains.
if (domain[j] < domain[0]) {
domain = domain.slice().reverse();
range$$1 = range$$1.slice().reverse();
}
while (++i < j) {
d[i] = deinterpolate(domain[i], domain[i + 1]);
r[i] = reinterpolate(range$$1[i], range$$1[i + 1]);
}
return function(x) {
var i = bisectRight(domain, x, 1, j) - 1;
return r[i](d[i](x));
};
}
function copy(source, target) {
return target
.domain(source.domain())
.range(source.range())
.interpolate(source.interpolate())
.clamp(source.clamp());
}
// deinterpolate(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1].
// reinterpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding domain value x in [a,b].
function continuous(deinterpolate, reinterpolate) {
var domain = unit,
range$$1 = unit,
interpolate$$1 = interpolateValue,
clamp = false,
piecewise,
output,
input;
function rescale() {
piecewise = Math.min(domain.length, range$$1.length) > 2 ? polymap : bimap;
output = input = null;
return scale;
}
function scale(x) {
return (output || (output = piecewise(domain, range$$1, clamp ? deinterpolateClamp(deinterpolate) : deinterpolate, interpolate$$1)))(+x);
}
scale.invert = function(y) {
return (input || (input = piecewise(range$$1, domain, deinterpolateLinear, clamp ? reinterpolateClamp(reinterpolate) : reinterpolate)))(+y);
};
scale.domain = function(_) {
return arguments.length ? (domain = map$3.call(_, number$2), rescale()) : domain.slice();
};
scale.range = function(_) {
return arguments.length ? (range$$1 = slice$5.call(_), rescale()) : range$$1.slice();
};
scale.rangeRound = function(_) {
return range$$1 = slice$5.call(_), interpolate$$1 = interpolateRound, rescale();
};
scale.clamp = function(_) {
return arguments.length ? (clamp = !!_, rescale()) : clamp;
};
scale.interpolate = function(_) {
return arguments.length ? (interpolate$$1 = _, rescale()) : interpolate$$1;
};
return rescale();
}
var tickFormat = function(domain, count, specifier) {
var start = domain[0],
stop = domain[domain.length - 1],
step = tickStep(start, stop, count == null ? 10 : count),
precision;
specifier = formatSpecifier(specifier == null ? ",f" : specifier);
switch (specifier.type) {
case "s": {
var value = Math.max(Math.abs(start), Math.abs(stop));
if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision;
return exports.formatPrefix(specifier, value);
}
case "":
case "e":
case "g":
case "p":
case "r": {
if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === "e");
break;
}
case "f":
case "%": {
if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === "%") * 2;
break;
}
}
return exports.format(specifier);
};
function linearish(scale) {
var domain = scale.domain;
scale.ticks = function(count) {
var d = domain();
return ticks(d[0], d[d.length - 1], count == null ? 10 : count);
};
scale.tickFormat = function(count, specifier) {
return tickFormat(domain(), count, specifier);
};
scale.nice = function(count) {
if (count == null) count = 10;
var d = domain(),
i0 = 0,
i1 = d.length - 1,
start = d[i0],
stop = d[i1],
step;
if (stop < start) {
step = start, start = stop, stop = step;
step = i0, i0 = i1, i1 = step;
}
step = tickIncrement(start, stop, count);
if (step > 0) {
start = Math.floor(start / step) * step;
stop = Math.ceil(stop / step) * step;
step = tickIncrement(start, stop, count);
} else if (step < 0) {
start = Math.ceil(start * step) / step;
stop = Math.floor(stop * step) / step;
step = tickIncrement(start, stop, count);
}
if (step > 0) {
d[i0] = Math.floor(start / step) * step;
d[i1] = Math.ceil(stop / step) * step;
domain(d);
} else if (step < 0) {
d[i0] = Math.ceil(start * step) / step;
d[i1] = Math.floor(stop * step) / step;
domain(d);
}
return scale;
};
return scale;
}
function linear$2() {
var scale = continuous(deinterpolateLinear, reinterpolate);
scale.copy = function() {
return copy(scale, linear$2());
};
return linearish(scale);
}
function identity$6() {
var domain = [0, 1];
function scale(x) {
return +x;
}
scale.invert = scale;
scale.domain = scale.range = function(_) {
return arguments.length ? (domain = map$3.call(_, number$2), scale) : domain.slice();
};
scale.copy = function() {
return identity$6().domain(domain);
};
return linearish(scale);
}
var nice = function(domain, interval) {
domain = domain.slice();
var i0 = 0,
i1 = domain.length - 1,
x0 = domain[i0],
x1 = domain[i1],
t;
if (x1 < x0) {
t = i0, i0 = i1, i1 = t;
t = x0, x0 = x1, x1 = t;
}
domain[i0] = interval.floor(x0);
domain[i1] = interval.ceil(x1);
return domain;
};
function deinterpolate(a, b) {
return (b = Math.log(b / a))
? function(x) { return Math.log(x / a) / b; }
: constant$9(b);
}
function reinterpolate$1(a, b) {
return a < 0
? function(t) { return -Math.pow(-b, t) * Math.pow(-a, 1 - t); }
: function(t) { return Math.pow(b, t) * Math.pow(a, 1 - t); };
}
function pow10(x) {
return isFinite(x) ? +("1e" + x) : x < 0 ? 0 : x;
}
function powp(base) {
return base === 10 ? pow10
: base === Math.E ? Math.exp
: function(x) { return Math.pow(base, x); };
}
function logp(base) {
return base === Math.E ? Math.log
: base === 10 && Math.log10
|| base === 2 && Math.log2
|| (base = Math.log(base), function(x) { return Math.log(x) / base; });
}
function reflect(f) {
return function(x) {
return -f(-x);
};
}
function log$1() {
var scale = continuous(deinterpolate, reinterpolate$1).domain([1, 10]),
domain = scale.domain,
base = 10,
logs = logp(10),
pows = powp(10);
function rescale() {
logs = logp(base), pows = powp(base);
if (domain()[0] < 0) logs = reflect(logs), pows = reflect(pows);
return scale;
}
scale.base = function(_) {
return arguments.length ? (base = +_, rescale()) : base;
};
scale.domain = function(_) {
return arguments.length ? (domain(_), rescale()) : domain();
};
scale.ticks = function(count) {
var d = domain(),
u = d[0],
v = d[d.length - 1],
r;
if (r = v < u) i = u, u = v, v = i;
var i = logs(u),
j = logs(v),
p,
k,
t,
n = count == null ? 10 : +count,
z = [];
if (!(base % 1) && j - i < n) {
i = Math.round(i) - 1, j = Math.round(j) + 1;
if (u > 0) for (; i < j; ++i) {
for (k = 1, p = pows(i); k < base; ++k) {
t = p * k;
if (t < u) continue;
if (t > v) break;
z.push(t);
}
} else for (; i < j; ++i) {
for (k = base - 1, p = pows(i); k >= 1; --k) {
t = p * k;
if (t < u) continue;
if (t > v) break;
z.push(t);
}
}
} else {
z = ticks(i, j, Math.min(j - i, n)).map(pows);
}
return r ? z.reverse() : z;
};
scale.tickFormat = function(count, specifier) {
if (specifier == null) specifier = base === 10 ? ".0e" : ",";
if (typeof specifier !== "function") specifier = exports.format(specifier);
if (count === Infinity) return specifier;
if (count == null) count = 10;
var k = Math.max(1, base * count / scale.ticks().length); // TODO fast estimate?
return function(d) {
var i = d / pows(Math.round(logs(d)));
if (i * base < base - 0.5) i *= base;
return i <= k ? specifier(d) : "";
};
};
scale.nice = function() {
return domain(nice(domain(), {
floor: function(x) { return pows(Math.floor(logs(x))); },
ceil: function(x) { return pows(Math.ceil(logs(x))); }
}));
};
scale.copy = function() {
return copy(scale, log$1().base(base));
};
return scale;
}
function raise$1(x, exponent) {
return x < 0 ? -Math.pow(-x, exponent) : Math.pow(x, exponent);
}
function pow$1() {
var exponent = 1,
scale = continuous(deinterpolate, reinterpolate),
domain = scale.domain;
function deinterpolate(a, b) {
return (b = raise$1(b, exponent) - (a = raise$1(a, exponent)))
? function(x) { return (raise$1(x, exponent) - a) / b; }
: constant$9(b);
}
function reinterpolate(a, b) {
b = raise$1(b, exponent) - (a = raise$1(a, exponent));
return function(t) { return raise$1(a + b * t, 1 / exponent); };
}
scale.exponent = function(_) {
return arguments.length ? (exponent = +_, domain(domain())) : exponent;
};
scale.copy = function() {
return copy(scale, pow$1().exponent(exponent));
};
return linearish(scale);
}
function sqrt$1() {
return pow$1().exponent(0.5);
}
function quantile$$1() {
var domain = [],
range$$1 = [],
thresholds = [];
function rescale() {
var i = 0, n = Math.max(1, range$$1.length);
thresholds = new Array(n - 1);
while (++i < n) thresholds[i - 1] = threshold(domain, i / n);
return scale;
}
function scale(x) {
if (!isNaN(x = +x)) return range$$1[bisectRight(thresholds, x)];
}
scale.invertExtent = function(y) {
var i = range$$1.indexOf(y);
return i < 0 ? [NaN, NaN] : [
i > 0 ? thresholds[i - 1] : domain[0],
i < thresholds.length ? thresholds[i] : domain[domain.length - 1]
];
};
scale.domain = function(_) {
if (!arguments.length) return domain.slice();
domain = [];
for (var i = 0, n = _.length, d; i < n; ++i) if (d = _[i], d != null && !isNaN(d = +d)) domain.push(d);
domain.sort(ascending);
return rescale();
};
scale.range = function(_) {
return arguments.length ? (range$$1 = slice$5.call(_), rescale()) : range$$1.slice();
};
scale.quantiles = function() {
return thresholds.slice();
};
scale.copy = function() {
return quantile$$1()
.domain(domain)
.range(range$$1);
};
return scale;
}
function quantize$1() {
var x0 = 0,
x1 = 1,
n = 1,
domain = [0.5],
range$$1 = [0, 1];
function scale(x) {
if (x <= x) return range$$1[bisectRight(domain, x, 0, n)];
}
function rescale() {
var i = -1;
domain = new Array(n);
while (++i < n) domain[i] = ((i + 1) * x1 - (i - n) * x0) / (n + 1);
return scale;
}
scale.domain = function(_) {
return arguments.length ? (x0 = +_[0], x1 = +_[1], rescale()) : [x0, x1];
};
scale.range = function(_) {
return arguments.length ? (n = (range$$1 = slice$5.call(_)).length - 1, rescale()) : range$$1.slice();
};
scale.invertExtent = function(y) {
var i = range$$1.indexOf(y);
return i < 0 ? [NaN, NaN]
: i < 1 ? [x0, domain[0]]
: i >= n ? [domain[n - 1], x1]
: [domain[i - 1], domain[i]];
};
scale.copy = function() {
return quantize$1()
.domain([x0, x1])
.range(range$$1);
};
return linearish(scale);
}
function threshold$1() {
var domain = [0.5],
range$$1 = [0, 1],
n = 1;
function scale(x) {
if (x <= x) return range$$1[bisectRight(domain, x, 0, n)];
}
scale.domain = function(_) {
return arguments.length ? (domain = slice$5.call(_), n = Math.min(domain.length, range$$1.length - 1), scale) : domain.slice();
};
scale.range = function(_) {
return arguments.length ? (range$$1 = slice$5.call(_), n = Math.min(domain.length, range$$1.length - 1), scale) : range$$1.slice();
};
scale.invertExtent = function(y) {
var i = range$$1.indexOf(y);
return [domain[i - 1], domain[i]];
};
scale.copy = function() {
return threshold$1()
.domain(domain)
.range(range$$1);
};
return scale;
}
var t0$1 = new Date;
var t1$1 = new Date;
function newInterval(floori, offseti, count, field) {
function interval(date) {
return floori(date = new Date(+date)), date;
}
interval.floor = interval;
interval.ceil = function(date) {
return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date;
};
interval.round = function(date) {
var d0 = interval(date),
d1 = interval.ceil(date);
return date - d0 < d1 - date ? d0 : d1;
};
interval.offset = function(date, step) {
return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date;
};
interval.range = function(start, stop, step) {
var range = [];
start = interval.ceil(start);
step = step == null ? 1 : Math.floor(step);
if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date
do range.push(new Date(+start)); while (offseti(start, step), floori(start), start < stop)
return range;
};
interval.filter = function(test) {
return newInterval(function(date) {
if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1);
}, function(date, step) {
if (date >= date) {
if (step < 0) while (++step <= 0) {
while (offseti(date, -1), !test(date)) {} // eslint-disable-line no-empty
} else while (--step >= 0) {
while (offseti(date, +1), !test(date)) {} // eslint-disable-line no-empty
}
}
});
};
if (count) {
interval.count = function(start, end) {
t0$1.setTime(+start), t1$1.setTime(+end);
floori(t0$1), floori(t1$1);
return Math.floor(count(t0$1, t1$1));
};
interval.every = function(step) {
step = Math.floor(step);
return !isFinite(step) || !(step > 0) ? null
: !(step > 1) ? interval
: interval.filter(field
? function(d) { return field(d) % step === 0; }
: function(d) { return interval.count(0, d) % step === 0; });
};
}
return interval;
}
var millisecond = newInterval(function() {
// noop
}, function(date, step) {
date.setTime(+date + step);
}, function(start, end) {
return end - start;
});
// An optimized implementation for this simple case.
millisecond.every = function(k) {
k = Math.floor(k);
if (!isFinite(k) || !(k > 0)) return null;
if (!(k > 1)) return millisecond;
return newInterval(function(date) {
date.setTime(Math.floor(date / k) * k);
}, function(date, step) {
date.setTime(+date + step * k);
}, function(start, end) {
return (end - start) / k;
});
};
var milliseconds = millisecond.range;
var durationSecond$1 = 1e3;
var durationMinute$1 = 6e4;
var durationHour$1 = 36e5;
var durationDay$1 = 864e5;
var durationWeek$1 = 6048e5;
var second = newInterval(function(date) {
date.setTime(Math.floor(date / durationSecond$1) * durationSecond$1);
}, function(date, step) {
date.setTime(+date + step * durationSecond$1);
}, function(start, end) {
return (end - start) / durationSecond$1;
}, function(date) {
return date.getUTCSeconds();
});
var seconds = second.range;
var minute = newInterval(function(date) {
date.setTime(Math.floor(date / durationMinute$1) * durationMinute$1);
}, function(date, step) {
date.setTime(+date + step * durationMinute$1);
}, function(start, end) {
return (end - start) / durationMinute$1;
}, function(date) {
return date.getMinutes();
});
var minutes = minute.range;
var hour = newInterval(function(date) {
var offset = date.getTimezoneOffset() * durationMinute$1 % durationHour$1;
if (offset < 0) offset += durationHour$1;
date.setTime(Math.floor((+date - offset) / durationHour$1) * durationHour$1 + offset);
}, function(date, step) {
date.setTime(+date + step * durationHour$1);
}, function(start, end) {
return (end - start) / durationHour$1;
}, function(date) {
return date.getHours();
});
var hours = hour.range;
var day = newInterval(function(date) {
date.setHours(0, 0, 0, 0);
}, function(date, step) {
date.setDate(date.getDate() + step);
}, function(start, end) {
return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute$1) / durationDay$1;
}, function(date) {
return date.getDate() - 1;
});
var days = day.range;
function weekday(i) {
return newInterval(function(date) {
date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7);
date.setHours(0, 0, 0, 0);
}, function(date, step) {
date.setDate(date.getDate() + step * 7);
}, function(start, end) {
return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute$1) / durationWeek$1;
});
}
var sunday = weekday(0);
var monday = weekday(1);
var tuesday = weekday(2);
var wednesday = weekday(3);
var thursday = weekday(4);
var friday = weekday(5);
var saturday = weekday(6);
var sundays = sunday.range;
var mondays = monday.range;
var tuesdays = tuesday.range;
var wednesdays = wednesday.range;
var thursdays = thursday.range;
var fridays = friday.range;
var saturdays = saturday.range;
var month = newInterval(function(date) {
date.setDate(1);
date.setHours(0, 0, 0, 0);
}, function(date, step) {
date.setMonth(date.getMonth() + step);
}, function(start, end) {
return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12;
}, function(date) {
return date.getMonth();
});
var months = month.range;
var year = newInterval(function(date) {
date.setMonth(0, 1);
date.setHours(0, 0, 0, 0);
}, function(date, step) {
date.setFullYear(date.getFullYear() + step);
}, function(start, end) {
return end.getFullYear() - start.getFullYear();
}, function(date) {
return date.getFullYear();
});
// An optimized implementation for this simple case.
year.every = function(k) {
return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) {
date.setFullYear(Math.floor(date.getFullYear() / k) * k);
date.setMonth(0, 1);
date.setHours(0, 0, 0, 0);
}, function(date, step) {
date.setFullYear(date.getFullYear() + step * k);
});
};
var years = year.range;
var utcMinute = newInterval(function(date) {
date.setUTCSeconds(0, 0);
}, function(date, step) {
date.setTime(+date + step * durationMinute$1);
}, function(start, end) {
return (end - start) / durationMinute$1;
}, function(date) {
return date.getUTCMinutes();
});
var utcMinutes = utcMinute.range;
var utcHour = newInterval(function(date) {
date.setUTCMinutes(0, 0, 0);
}, function(date, step) {
date.setTime(+date + step * durationHour$1);
}, function(start, end) {
return (end - start) / durationHour$1;
}, function(date) {
return date.getUTCHours();
});
var utcHours = utcHour.range;
var utcDay = newInterval(function(date) {
date.setUTCHours(0, 0, 0, 0);
}, function(date, step) {
date.setUTCDate(date.getUTCDate() + step);
}, function(start, end) {
return (end - start) / durationDay$1;
}, function(date) {
return date.getUTCDate() - 1;
});
var utcDays = utcDay.range;
function utcWeekday(i) {
return newInterval(function(date) {
date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7);
date.setUTCHours(0, 0, 0, 0);
}, function(date, step) {
date.setUTCDate(date.getUTCDate() + step * 7);
}, function(start, end) {
return (end - start) / durationWeek$1;
});
}
var utcSunday = utcWeekday(0);
var utcMonday = utcWeekday(1);
var utcTuesday = utcWeekday(2);
var utcWednesday = utcWeekday(3);
var utcThursday = utcWeekday(4);
var utcFriday = utcWeekday(5);
var utcSaturday = utcWeekday(6);
var utcSundays = utcSunday.range;
var utcMondays = utcMonday.range;
var utcTuesdays = utcTuesday.range;
var utcWednesdays = utcWednesday.range;
var utcThursdays = utcThursday.range;
var utcFridays = utcFriday.range;
var utcSaturdays = utcSaturday.range;
var utcMonth = newInterval(function(date) {
date.setUTCDate(1);
date.setUTCHours(0, 0, 0, 0);
}, function(date, step) {
date.setUTCMonth(date.getUTCMonth() + step);
}, function(start, end) {
return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12;
}, function(date) {
return date.getUTCMonth();
});
var utcMonths = utcMonth.range;
var utcYear = newInterval(function(date) {
date.setUTCMonth(0, 1);
date.setUTCHours(0, 0, 0, 0);
}, function(date, step) {
date.setUTCFullYear(date.getUTCFullYear() + step);
}, function(start, end) {
return end.getUTCFullYear() - start.getUTCFullYear();
}, function(date) {
return date.getUTCFullYear();
});
// An optimized implementation for this simple case.
utcYear.every = function(k) {
return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) {
date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k);
date.setUTCMonth(0, 1);
date.setUTCHours(0, 0, 0, 0);
}, function(date, step) {
date.setUTCFullYear(date.getUTCFullYear() + step * k);
});
};
var utcYears = utcYear.range;
function localDate(d) {
if (0 <= d.y && d.y < 100) {
var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L);
date.setFullYear(d.y);
return date;
}
return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L);
}
function utcDate(d) {
if (0 <= d.y && d.y < 100) {
var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L));
date.setUTCFullYear(d.y);
return date;
}
return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L));
}
function newYear(y) {
return {y: y, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0};
}
function formatLocale$1(locale) {
var locale_dateTime = locale.dateTime,
locale_date = locale.date,
locale_time = locale.time,
locale_periods = locale.periods,
locale_weekdays = locale.days,
locale_shortWeekdays = locale.shortDays,
locale_months = locale.months,
locale_shortMonths = locale.shortMonths;
var periodRe = formatRe(locale_periods),
periodLookup = formatLookup(locale_periods),
weekdayRe = formatRe(locale_weekdays),
weekdayLookup = formatLookup(locale_weekdays),
shortWeekdayRe = formatRe(locale_shortWeekdays),
shortWeekdayLookup = formatLookup(locale_shortWeekdays),
monthRe = formatRe(locale_months),
monthLookup = formatLookup(locale_months),
shortMonthRe = formatRe(locale_shortMonths),
shortMonthLookup = formatLookup(locale_shortMonths);
var formats = {
"a": formatShortWeekday,
"A": formatWeekday,
"b": formatShortMonth,
"B": formatMonth,
"c": null,
"d": formatDayOfMonth,
"e": formatDayOfMonth,
"H": formatHour24,
"I": formatHour12,
"j": formatDayOfYear,
"L": formatMilliseconds,
"m": formatMonthNumber,
"M": formatMinutes,
"p": formatPeriod,
"S": formatSeconds,
"U": formatWeekNumberSunday,
"w": formatWeekdayNumber,
"W": formatWeekNumberMonday,
"x": null,
"X": null,
"y": formatYear,
"Y": formatFullYear,
"Z": formatZone,
"%": formatLiteralPercent
};
var utcFormats = {
"a": formatUTCShortWeekday,
"A": formatUTCWeekday,
"b": formatUTCShortMonth,
"B": formatUTCMonth,
"c": null,
"d": formatUTCDayOfMonth,
"e": formatUTCDayOfMonth,
"H": formatUTCHour24,
"I": formatUTCHour12,
"j": formatUTCDayOfYear,
"L": formatUTCMilliseconds,
"m": formatUTCMonthNumber,
"M": formatUTCMinutes,
"p": formatUTCPeriod,
"S": formatUTCSeconds,
"U": formatUTCWeekNumberSunday,
"w": formatUTCWeekdayNumber,
"W": formatUTCWeekNumberMonday,
"x": null,
"X": null,
"y": formatUTCYear,
"Y": formatUTCFullYear,
"Z": formatUTCZone,
"%": formatLiteralPercent
};
var parses = {
"a": parseShortWeekday,
"A": parseWeekday,
"b": parseShortMonth,
"B": parseMonth,
"c": parseLocaleDateTime,
"d": parseDayOfMonth,
"e": parseDayOfMonth,
"H": parseHour24,
"I": parseHour24,
"j": parseDayOfYear,
"L": parseMilliseconds,
"m": parseMonthNumber,
"M": parseMinutes,
"p": parsePeriod,
"S": parseSeconds,
"U": parseWeekNumberSunday,
"w": parseWeekdayNumber,
"W": parseWeekNumberMonday,
"x": parseLocaleDate,
"X": parseLocaleTime,
"y": parseYear,
"Y": parseFullYear,
"Z": parseZone,
"%": parseLiteralPercent
};
// These recursive directive definitions must be deferred.
formats.x = newFormat(locale_date, formats);
formats.X = newFormat(locale_time, formats);
formats.c = newFormat(locale_dateTime, formats);
utcFormats.x = newFormat(locale_date, utcFormats);
utcFormats.X = newFormat(locale_time, utcFormats);
utcFormats.c = newFormat(locale_dateTime, utcFormats);
function newFormat(specifier, formats) {
return function(date) {
var string = [],
i = -1,
j = 0,
n = specifier.length,
c,
pad,
format;
if (!(date instanceof Date)) date = new Date(+date);
while (++i < n) {
if (specifier.charCodeAt(i) === 37) {
string.push(specifier.slice(j, i));
if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i);
else pad = c === "e" ? " " : "0";
if (format = formats[c]) c = format(date, pad);
string.push(c);
j = i + 1;
}
}
string.push(specifier.slice(j, i));
return string.join("");
};
}
function newParse(specifier, newDate) {
return function(string) {
var d = newYear(1900),
i = parseSpecifier(d, specifier, string += "", 0);
if (i != string.length) return null;
// The am-pm flag is 0 for AM, and 1 for PM.
if ("p" in d) d.H = d.H % 12 + d.p * 12;
// Convert day-of-week and week-of-year to day-of-year.
if ("W" in d || "U" in d) {
if (!("w" in d)) d.w = "W" in d ? 1 : 0;
var day$$1 = "Z" in d ? utcDate(newYear(d.y)).getUTCDay() : newDate(newYear(d.y)).getDay();
d.m = 0;
d.d = "W" in d ? (d.w + 6) % 7 + d.W * 7 - (day$$1 + 5) % 7 : d.w + d.U * 7 - (day$$1 + 6) % 7;
}
// If a time zone is specified, all fields are interpreted as UTC and then
// offset according to the specified time zone.
if ("Z" in d) {
d.H += d.Z / 100 | 0;
d.M += d.Z % 100;
return utcDate(d);
}
// Otherwise, all fields are in local time.
return newDate(d);
};
}
function parseSpecifier(d, specifier, string, j) {
var i = 0,
n = specifier.length,
m = string.length,
c,
parse;
while (i < n) {
if (j >= m) return -1;
c = specifier.charCodeAt(i++);
if (c === 37) {
c = specifier.charAt(i++);
parse = parses[c in pads ? specifier.charAt(i++) : c];
if (!parse || ((j = parse(d, string, j)) < 0)) return -1;
} else if (c != string.charCodeAt(j++)) {
return -1;
}
}
return j;
}
function parsePeriod(d, string, i) {
var n = periodRe.exec(string.slice(i));
return n ? (d.p = periodLookup[n[0].toLowerCase()], i + n[0].length) : -1;
}
function parseShortWeekday(d, string, i) {
var n = shortWeekdayRe.exec(string.slice(i));
return n ? (d.w = shortWeekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;
}
function parseWeekday(d, string, i) {
var n = weekdayRe.exec(string.slice(i));
return n ? (d.w = weekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;
}
function parseShortMonth(d, string, i) {
var n = shortMonthRe.exec(string.slice(i));
return n ? (d.m = shortMonthLookup[n[0].toLowerCase()], i + n[0].length) : -1;
}
function parseMonth(d, string, i) {
var n = monthRe.exec(string.slice(i));
return n ? (d.m = monthLookup[n[0].toLowerCase()], i + n[0].length) : -1;
}
function parseLocaleDateTime(d, string, i) {
return parseSpecifier(d, locale_dateTime, string, i);
}
function parseLocaleDate(d, string, i) {
return parseSpecifier(d, locale_date, string, i);
}
function parseLocaleTime(d, string, i) {
return parseSpecifier(d, locale_time, string, i);
}
function formatShortWeekday(d) {
return locale_shortWeekdays[d.getDay()];
}
function formatWeekday(d) {
return locale_weekdays[d.getDay()];
}
function formatShortMonth(d) {
return locale_shortMonths[d.getMonth()];
}
function formatMonth(d) {
return locale_months[d.getMonth()];
}
function formatPeriod(d) {
return locale_periods[+(d.getHours() >= 12)];
}
function formatUTCShortWeekday(d) {
return locale_shortWeekdays[d.getUTCDay()];
}
function formatUTCWeekday(d) {
return locale_weekdays[d.getUTCDay()];
}
function formatUTCShortMonth(d) {
return locale_shortMonths[d.getUTCMonth()];
}
function formatUTCMonth(d) {
return locale_months[d.getUTCMonth()];
}
function formatUTCPeriod(d) {
return locale_periods[+(d.getUTCHours() >= 12)];
}
return {
format: function(specifier) {
var f = newFormat(specifier += "", formats);
f.toString = function() { return specifier; };
return f;
},
parse: function(specifier) {
var p = newParse(specifier += "", localDate);
p.toString = function() { return specifier; };
return p;
},
utcFormat: function(specifier) {
var f = newFormat(specifier += "", utcFormats);
f.toString = function() { return specifier; };
return f;
},
utcParse: function(specifier) {
var p = newParse(specifier, utcDate);
p.toString = function() { return specifier; };
return p;
}
};
}
var pads = {"-": "", "_": " ", "0": "0"};
var numberRe = /^\s*\d+/;
var percentRe = /^%/;
var requoteRe = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;
function pad(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 requote(s) {
return s.replace(requoteRe, "\\$&");
}
function formatRe(names) {
return new RegExp("^(?:" + names.map(requote).join("|") + ")", "i");
}
function formatLookup(names) {
var map = {}, i = -1, n = names.length;
while (++i < n) map[names[i].toLowerCase()] = i;
return map;
}
function parseWeekdayNumber(d, string, i) {
var n = numberRe.exec(string.slice(i, i + 1));
return n ? (d.w = +n[0], i + n[0].length) : -1;
}
function parseWeekNumberSunday(d, string, i) {
var n = numberRe.exec(string.slice(i));
return n ? (d.U = +n[0], i + n[0].length) : -1;
}
function parseWeekNumberMonday(d, string, i) {
var n = numberRe.exec(string.slice(i));
return n ? (d.W = +n[0], i + n[0].length) : -1;
}
function parseFullYear(d, string, i) {
var n = numberRe.exec(string.slice(i, i + 4));
return n ? (d.y = +n[0], i + n[0].length) : -1;
}
function parseYear(d, string, i) {
var n = numberRe.exec(string.slice(i, i + 2));
return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1;
}
function parseZone(d, string, i) {
var n = /^(Z)|([+-]\d\d)(?:\:?(\d\d))?/.exec(string.slice(i, i + 6));
return n ? (d.Z = n[1] ? 0 : -(n[2] + (n[3] || "00")), i + n[0].length) : -1;
}
function parseMonthNumber(d, string, i) {
var n = numberRe.exec(string.slice(i, i + 2));
return n ? (d.m = n[0] - 1, i + n[0].length) : -1;
}
function parseDayOfMonth(d, string, i) {
var n = numberRe.exec(string.slice(i, i + 2));
return n ? (d.d = +n[0], i + n[0].length) : -1;
}
function parseDayOfYear(d, string, i) {
var n = numberRe.exec(string.slice(i, i + 3));
return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1;
}
function parseHour24(d, string, i) {
var n = numberRe.exec(string.slice(i, i + 2));
return n ? (d.H = +n[0], i + n[0].length) : -1;
}
function parseMinutes(d, string, i) {
var n = numberRe.exec(string.slice(i, i + 2));
return n ? (d.M = +n[0], i + n[0].length) : -1;
}
function parseSeconds(d, string, i) {
var n = numberRe.exec(string.slice(i, i + 2));
return n ? (d.S = +n[0], i + n[0].length) : -1;
}
function parseMilliseconds(d, string, i) {
var n = numberRe.exec(string.slice(i, i + 3));
return n ? (d.L = +n[0], i + n[0].length) : -1;
}
function parseLiteralPercent(d, string, i) {
var n = percentRe.exec(string.slice(i, i + 1));
return n ? i + n[0].length : -1;
}
function formatDayOfMonth(d, p) {
return pad(d.getDate(), p, 2);
}
function formatHour24(d, p) {
return pad(d.getHours(), p, 2);
}
function formatHour12(d, p) {
return pad(d.getHours() % 12 || 12, p, 2);
}
function formatDayOfYear(d, p) {
return pad(1 + day.count(year(d), d), p, 3);
}
function formatMilliseconds(d, p) {
return pad(d.getMilliseconds(), p, 3);
}
function formatMonthNumber(d, p) {
return pad(d.getMonth() + 1, p, 2);
}
function formatMinutes(d, p) {
return pad(d.getMinutes(), p, 2);
}
function formatSeconds(d, p) {
return pad(d.getSeconds(), p, 2);
}
function formatWeekNumberSunday(d, p) {
return pad(sunday.count(year(d), d), p, 2);
}
function formatWeekdayNumber(d) {
return d.getDay();
}
function formatWeekNumberMonday(d, p) {
return pad(monday.count(year(d), d), p, 2);
}
function formatYear(d, p) {
return pad(d.getFullYear() % 100, p, 2);
}
function formatFullYear(d, p) {
return pad(d.getFullYear() % 10000, p, 4);
}
function formatZone(d) {
var z = d.getTimezoneOffset();
return (z > 0 ? "-" : (z *= -1, "+"))
+ pad(z / 60 | 0, "0", 2)
+ pad(z % 60, "0", 2);
}
function formatUTCDayOfMonth(d, p) {
return pad(d.getUTCDate(), p, 2);
}
function formatUTCHour24(d, p) {
return pad(d.getUTCHours(), p, 2);
}
function formatUTCHour12(d, p) {
return pad(d.getUTCHours() % 12 || 12, p, 2);
}
function formatUTCDayOfYear(d, p) {
return pad(1 + utcDay.count(utcYear(d), d), p, 3);
}
function formatUTCMilliseconds(d, p) {
return pad(d.getUTCMilliseconds(), p, 3);
}
function formatUTCMonthNumber(d, p) {
return pad(d.getUTCMonth() + 1, p, 2);
}
function formatUTCMinutes(d, p) {
return pad(d.getUTCMinutes(), p, 2);
}
function formatUTCSeconds(d, p) {
return pad(d.getUTCSeconds(), p, 2);
}
function formatUTCWeekNumberSunday(d, p) {
return pad(utcSunday.count(utcYear(d), d), p, 2);
}
function formatUTCWeekdayNumber(d) {
return d.getUTCDay();
}
function formatUTCWeekNumberMonday(d, p) {
return pad(utcMonday.count(utcYear(d), d), p, 2);
}
function formatUTCYear(d, p) {
return pad(d.getUTCFullYear() % 100, p, 2);
}
function formatUTCFullYear(d, p) {
return pad(d.getUTCFullYear() % 10000, p, 4);
}
function formatUTCZone() {
return "+0000";
}
function formatLiteralPercent() {
return "%";
}
var locale$2;
defaultLocale$1({
dateTime: "%x, %X",
date: "%-m/%-d/%Y",
time: "%-I:%M:%S %p",
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"]
});
function defaultLocale$1(definition) {
locale$2 = formatLocale$1(definition);
exports.timeFormat = locale$2.format;
exports.timeParse = locale$2.parse;
exports.utcFormat = locale$2.utcFormat;
exports.utcParse = locale$2.utcParse;
return locale$2;
}
var isoSpecifier = "%Y-%m-%dT%H:%M:%S.%LZ";
function formatIsoNative(date) {
return date.toISOString();
}
var formatIso = Date.prototype.toISOString
? formatIsoNative
: exports.utcFormat(isoSpecifier);
function parseIsoNative(string) {
var date = new Date(string);
return isNaN(date) ? null : date;
}
var parseIso = +new Date("2000-01-01T00:00:00.000Z")
? parseIsoNative
: exports.utcParse(isoSpecifier);
var durationSecond = 1000;
var durationMinute = durationSecond * 60;
var durationHour = durationMinute * 60;
var durationDay = durationHour * 24;
var durationWeek = durationDay * 7;
var durationMonth = durationDay * 30;
var durationYear = durationDay * 365;
function date$1(t) {
return new Date(t);
}
function number$3(t) {
return t instanceof Date ? +t : +new Date(+t);
}
function calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format) {
var scale = continuous(deinterpolateLinear, reinterpolate),
invert = scale.invert,
domain = scale.domain;
var formatMillisecond = format(".%L"),
formatSecond = format(":%S"),
formatMinute = format("%I:%M"),
formatHour = format("%I %p"),
formatDay = format("%a %d"),
formatWeek = format("%b %d"),
formatMonth = format("%B"),
formatYear = format("%Y");
var tickIntervals = [
[second$$1, 1, durationSecond],
[second$$1, 5, 5 * durationSecond],
[second$$1, 15, 15 * durationSecond],
[second$$1, 30, 30 * durationSecond],
[minute$$1, 1, durationMinute],
[minute$$1, 5, 5 * durationMinute],
[minute$$1, 15, 15 * durationMinute],
[minute$$1, 30, 30 * durationMinute],
[ hour$$1, 1, durationHour ],
[ hour$$1, 3, 3 * durationHour ],
[ hour$$1, 6, 6 * durationHour ],
[ hour$$1, 12, 12 * durationHour ],
[ day$$1, 1, durationDay ],
[ day$$1, 2, 2 * durationDay ],
[ week, 1, durationWeek ],
[ month$$1, 1, durationMonth ],
[ month$$1, 3, 3 * durationMonth ],
[ year$$1, 1, durationYear ]
];
function tickFormat(date) {
return (second$$1(date) < date ? formatMillisecond
: minute$$1(date) < date ? formatSecond
: hour$$1(date) < date ? formatMinute
: day$$1(date) < date ? formatHour
: month$$1(date) < date ? (week(date) < date ? formatDay : formatWeek)
: year$$1(date) < date ? formatMonth
: formatYear)(date);
}
function tickInterval(interval, start, stop, step) {
if (interval == null) interval = 10;
// If a desired tick count is specified, pick a reasonable tick interval
// based on the extent of the domain and a rough estimate of tick size.
// Otherwise, assume interval is already a time interval and use it.
if (typeof interval === "number") {
var target = Math.abs(stop - start) / interval,
i = bisector(function(i) { return i[2]; }).right(tickIntervals, target);
if (i === tickIntervals.length) {
step = tickStep(start / durationYear, stop / durationYear, interval);
interval = year$$1;
} else if (i) {
i = tickIntervals[target / tickIntervals[i - 1][2] < tickIntervals[i][2] / target ? i - 1 : i];
step = i[1];
interval = i[0];
} else {
step = tickStep(start, stop, interval);
interval = millisecond$$1;
}
}
return step == null ? interval : interval.every(step);
}
scale.invert = function(y) {
return new Date(invert(y));
};
scale.domain = function(_) {
return arguments.length ? domain(map$3.call(_, number$3)) : domain().map(date$1);
};
scale.ticks = function(interval, step) {
var d = domain(),
t0 = d[0],
t1 = d[d.length - 1],
r = t1 < t0,
t;
if (r) t = t0, t0 = t1, t1 = t;
t = tickInterval(interval, t0, t1, step);
t = t ? t.range(t0, t1 + 1) : []; // inclusive stop
return r ? t.reverse() : t;
};
scale.tickFormat = function(count, specifier) {
return specifier == null ? tickFormat : format(specifier);
};
scale.nice = function(interval, step) {
var d = domain();
return (interval = tickInterval(interval, d[0], d[d.length - 1], step))
? domain(nice(d, interval))
: scale;
};
scale.copy = function() {
return copy(scale, calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format));
};
return scale;
}
var time = function() {
return calendar(year, month, sunday, day, hour, minute, second, millisecond, exports.timeFormat).domain([new Date(2000, 0, 1), new Date(2000, 0, 2)]);
};
var utcTime = function() {
return calendar(utcYear, utcMonth, utcSunday, utcDay, utcHour, utcMinute, second, millisecond, exports.utcFormat).domain([Date.UTC(2000, 0, 1), Date.UTC(2000, 0, 2)]);
};
var colors = function(s) {
return s.match(/.{6}/g).map(function(x) {
return "#" + x;
});
};
var category10 = colors("1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf");
var category20b = colors("393b795254a36b6ecf9c9ede6379398ca252b5cf6bcedb9c8c6d31bd9e39e7ba52e7cb94843c39ad494ad6616be7969c7b4173a55194ce6dbdde9ed6");
var category20c = colors("3182bd6baed69ecae1c6dbefe6550dfd8d3cfdae6bfdd0a231a35474c476a1d99bc7e9c0756bb19e9ac8bcbddcdadaeb636363969696bdbdbdd9d9d9");
var category20 = colors("1f77b4aec7e8ff7f0effbb782ca02c98df8ad62728ff98969467bdc5b0d58c564bc49c94e377c2f7b6d27f7f7fc7c7c7bcbd22dbdb8d17becf9edae5");
var cubehelix$3 = cubehelixLong(cubehelix(300, 0.5, 0.0), cubehelix(-240, 0.5, 1.0));
var warm = cubehelixLong(cubehelix(-100, 0.75, 0.35), cubehelix(80, 1.50, 0.8));
var cool = cubehelixLong(cubehelix(260, 0.75, 0.35), cubehelix(80, 1.50, 0.8));
var rainbow = cubehelix();
var rainbow$1 = function(t) {
if (t < 0 || t > 1) t -= Math.floor(t);
var ts = Math.abs(t - 0.5);
rainbow.h = 360 * t - 100;
rainbow.s = 1.5 - 1.5 * ts;
rainbow.l = 0.8 - 0.9 * ts;
return rainbow + "";
};
function ramp(range) {
var n = range.length;
return function(t) {
return range[Math.max(0, Math.min(n - 1, Math.floor(t * n)))];
};
}
var viridis = ramp(colors("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725"));
var magma = ramp(colors("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf"));
var inferno = ramp(colors("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4"));
var plasma = ramp(colors("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921"));
function sequential(interpolator) {
var x0 = 0,
x1 = 1,
clamp = false;
function scale(x) {
var t = (x - x0) / (x1 - x0);
return interpolator(clamp ? Math.max(0, Math.min(1, t)) : t);
}
scale.domain = function(_) {
return arguments.length ? (x0 = +_[0], x1 = +_[1], scale) : [x0, x1];
};
scale.clamp = function(_) {
return arguments.length ? (clamp = !!_, scale) : clamp;
};
scale.interpolator = function(_) {
return arguments.length ? (interpolator = _, scale) : interpolator;
};
scale.copy = function() {
return sequential(interpolator).domain([x0, x1]).clamp(clamp);
};
return linearish(scale);
}
var constant$10 = function(x) {
return function constant() {
return x;
};
};
var abs$1 = Math.abs;
var atan2$1 = Math.atan2;
var cos$2 = Math.cos;
var max$2 = Math.max;
var min$1 = Math.min;
var sin$2 = Math.sin;
var sqrt$2 = Math.sqrt;
var epsilon$3 = 1e-12;
var pi$4 = Math.PI;
var halfPi$3 = pi$4 / 2;
var tau$4 = 2 * pi$4;
function acos$1(x) {
return x > 1 ? 0 : x < -1 ? pi$4 : Math.acos(x);
}
function asin$1(x) {
return x >= 1 ? halfPi$3 : x <= -1 ? -halfPi$3 : Math.asin(x);
}
function arcInnerRadius(d) {
return d.innerRadius;
}
function arcOuterRadius(d) {
return d.outerRadius;
}
function arcStartAngle(d) {
return d.startAngle;
}
function arcEndAngle(d) {
return d.endAngle;
}
function arcPadAngle(d) {
return d && d.padAngle; // Note: optional!
}
function intersect(x0, y0, x1, y1, x2, y2, x3, y3) {
var x10 = x1 - x0, y10 = y1 - y0,
x32 = x3 - x2, y32 = y3 - y2,
t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / (y32 * x10 - x32 * y10);
return [x0 + t * x10, y0 + t * y10];
}
// Compute perpendicular offset line of length rc.
// http://mathworld.wolfram.com/Circle-LineIntersection.html
function cornerTangents(x0, y0, x1, y1, r1, rc, cw) {
var x01 = x0 - x1,
y01 = y0 - y1,
lo = (cw ? rc : -rc) / sqrt$2(x01 * x01 + y01 * y01),
ox = lo * y01,
oy = -lo * x01,
x11 = x0 + ox,
y11 = y0 + oy,
x10 = x1 + ox,
y10 = y1 + oy,
x00 = (x11 + x10) / 2,
y00 = (y11 + y10) / 2,
dx = x10 - x11,
dy = y10 - y11,
d2 = dx * dx + dy * dy,
r = r1 - rc,
D = x11 * y10 - x10 * y11,
d = (dy < 0 ? -1 : 1) * sqrt$2(max$2(0, 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 - x00,
dy0 = cy0 - y00,
dx1 = cx1 - x00,
dy1 = cy1 - y00;
// Pick the closer of the two intersection points.
// TODO Is there a faster way to determine which intersection to use?
if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1;
return {
cx: cx0,
cy: cy0,
x01: -ox,
y01: -oy,
x11: cx0 * (r1 / r - 1),
y11: cy0 * (r1 / r - 1)
};
}
var arc = function() {
var innerRadius = arcInnerRadius,
outerRadius = arcOuterRadius,
cornerRadius = constant$10(0),
padRadius = null,
startAngle = arcStartAngle,
endAngle = arcEndAngle,
padAngle = arcPadAngle,
context = null;
function arc() {
var buffer,
r,
r0 = +innerRadius.apply(this, arguments),
r1 = +outerRadius.apply(this, arguments),
a0 = startAngle.apply(this, arguments) - halfPi$3,
a1 = endAngle.apply(this, arguments) - halfPi$3,
da = abs$1(a1 - a0),
cw = a1 > a0;
if (!context) context = buffer = path();
// Ensure that the outer radius is always larger than the inner radius.
if (r1 < r0) r = r1, r1 = r0, r0 = r;
// Is it a point?
if (!(r1 > epsilon$3)) context.moveTo(0, 0);
// Or is it a circle or annulus?
else if (da > tau$4 - epsilon$3) {
context.moveTo(r1 * cos$2(a0), r1 * sin$2(a0));
context.arc(0, 0, r1, a0, a1, !cw);
if (r0 > epsilon$3) {
context.moveTo(r0 * cos$2(a1), r0 * sin$2(a1));
context.arc(0, 0, r0, a1, a0, cw);
}
}
// Or is it a circular or annular sector?
else {
var a01 = a0,
a11 = a1,
a00 = a0,
a10 = a1,
da0 = da,
da1 = da,
ap = padAngle.apply(this, arguments) / 2,
rp = (ap > epsilon$3) && (padRadius ? +padRadius.apply(this, arguments) : sqrt$2(r0 * r0 + r1 * r1)),
rc = min$1(abs$1(r1 - r0) / 2, +cornerRadius.apply(this, arguments)),
rc0 = rc,
rc1 = rc,
t0,
t1;
// Apply padding? Note that since r1 ≥ r0, da1 ≥ da0.
if (rp > epsilon$3) {
var p0 = asin$1(rp / r0 * sin$2(ap)),
p1 = asin$1(rp / r1 * sin$2(ap));
if ((da0 -= p0 * 2) > epsilon$3) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0;
else da0 = 0, a00 = a10 = (a0 + a1) / 2;
if ((da1 -= p1 * 2) > epsilon$3) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1;
else da1 = 0, a01 = a11 = (a0 + a1) / 2;
}
var x01 = r1 * cos$2(a01),
y01 = r1 * sin$2(a01),
x10 = r0 * cos$2(a10),
y10 = r0 * sin$2(a10);
// Apply rounded corners?
if (rc > epsilon$3) {
var x11 = r1 * cos$2(a11),
y11 = r1 * sin$2(a11),
x00 = r0 * cos$2(a00),
y00 = r0 * sin$2(a00);
// Restrict the corner radius according to the sector angle.
if (da < pi$4) {
var oc = da0 > epsilon$3 ? intersect(x01, y01, x00, y00, x11, y11, x10, y10) : [x10, y10],
ax = x01 - oc[0],
ay = y01 - oc[1],
bx = x11 - oc[0],
by = y11 - oc[1],
kc = 1 / sin$2(acos$1((ax * bx + ay * by) / (sqrt$2(ax * ax + ay * ay) * sqrt$2(bx * bx + by * by))) / 2),
lc = sqrt$2(oc[0] * oc[0] + oc[1] * oc[1]);
rc0 = min$1(rc, (r0 - lc) / (kc - 1));
rc1 = min$1(rc, (r1 - lc) / (kc + 1));
}
}
// Is the sector collapsed to a line?
if (!(da1 > epsilon$3)) context.moveTo(x01, y01);
// Does the sector’s outer ring have rounded corners?
else if (rc1 > epsilon$3) {
t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw);
t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw);
context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01);
// Have the corners merged?
if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, atan2$1(t0.y01, t0.x01), atan2$1(t1.y01, t1.x01), !cw);
// Otherwise, draw the two corners and the ring.
else {
context.arc(t0.cx, t0.cy, rc1, atan2$1(t0.y01, t0.x01), atan2$1(t0.y11, t0.x11), !cw);
context.arc(0, 0, r1, atan2$1(t0.cy + t0.y11, t0.cx + t0.x11), atan2$1(t1.cy + t1.y11, t1.cx + t1.x11), !cw);
context.arc(t1.cx, t1.cy, rc1, atan2$1(t1.y11, t1.x11), atan2$1(t1.y01, t1.x01), !cw);
}
}
// Or is the outer ring just a circular arc?
else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw);
// Is there no inner ring, and it’s a circular sector?
// Or perhaps it’s an annular sector collapsed due to padding?
if (!(r0 > epsilon$3) || !(da0 > epsilon$3)) context.lineTo(x10, y10);
// Does the sector’s inner ring (or point) have rounded corners?
else if (rc0 > epsilon$3) {
t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw);
t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw);
context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01);
// Have the corners merged?
if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, atan2$1(t0.y01, t0.x01), atan2$1(t1.y01, t1.x01), !cw);
// Otherwise, draw the two corners and the ring.
else {
context.arc(t0.cx, t0.cy, rc0, atan2$1(t0.y01, t0.x01), atan2$1(t0.y11, t0.x11), !cw);
context.arc(0, 0, r0, atan2$1(t0.cy + t0.y11, t0.cx + t0.x11), atan2$1(t1.cy + t1.y11, t1.cx + t1.x11), cw);
context.arc(t1.cx, t1.cy, rc0, atan2$1(t1.y11, t1.x11), atan2$1(t1.y01, t1.x01), !cw);
}
}
// Or is the inner ring just a circular arc?
else context.arc(0, 0, r0, a10, a00, cw);
}
context.closePath();
if (buffer) return context = null, buffer + "" || null;
}
arc.centroid = function() {
var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2,
a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi$4 / 2;
return [cos$2(a) * r, sin$2(a) * r];
};
arc.innerRadius = function(_) {
return arguments.length ? (innerRadius = typeof _ === "function" ? _ : constant$10(+_), arc) : innerRadius;
};
arc.outerRadius = function(_) {
return arguments.length ? (outerRadius = typeof _ === "function" ? _ : constant$10(+_), arc) : outerRadius;
};
arc.cornerRadius = function(_) {
return arguments.length ? (cornerRadius = typeof _ === "function" ? _ : constant$10(+_), arc) : cornerRadius;
};
arc.padRadius = function(_) {
return arguments.length ? (padRadius = _ == null ? null : typeof _ === "function" ? _ : constant$10(+_), arc) : padRadius;
};
arc.startAngle = function(_) {
return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$10(+_), arc) : startAngle;
};
arc.endAngle = function(_) {
return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$10(+_), arc) : endAngle;
};
arc.padAngle = function(_) {
return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant$10(+_), arc) : padAngle;
};
arc.context = function(_) {
return arguments.length ? ((context = _ == null ? null : _), arc) : context;
};
return arc;
};
function Linear(context) {
this._context = context;
}
Linear.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._point = 0;
},
lineEnd: function() {
if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
this._line = 1 - this._line;
},
point: function(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
case 1: this._point = 2; // proceed
default: this._context.lineTo(x, y); break;
}
}
};
var curveLinear = function(context) {
return new Linear(context);
};
function x$3(p) {
return p[0];
}
function y$3(p) {
return p[1];
}
var line = function() {
var x$$1 = x$3,
y$$1 = y$3,
defined = constant$10(true),
context = null,
curve = curveLinear,
output = null;
function line(data) {
var i,
n = data.length,
d,
defined0 = false,
buffer;
if (context == null) output = curve(buffer = path());
for (i = 0; i <= n; ++i) {
if (!(i < n && defined(d = data[i], i, data)) === defined0) {
if (defined0 = !defined0) output.lineStart();
else output.lineEnd();
}
if (defined0) output.point(+x$$1(d, i, data), +y$$1(d, i, data));
}
if (buffer) return output = null, buffer + "" || null;
}
line.x = function(_) {
return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant$10(+_), line) : x$$1;
};
line.y = function(_) {
return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant$10(+_), line) : y$$1;
};
line.defined = function(_) {
return arguments.length ? (defined = typeof _ === "function" ? _ : constant$10(!!_), line) : defined;
};
line.curve = function(_) {
return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve;
};
line.context = function(_) {
return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context;
};
return line;
};
var area$2 = function() {
var x0 = x$3,
x1 = null,
y0 = constant$10(0),
y1 = y$3,
defined = constant$10(true),
context = null,
curve = curveLinear,
output = null;
function area(data) {
var i,
j,
k,
n = data.length,
d,
defined0 = false,
buffer,
x0z = new Array(n),
y0z = new Array(n);
if (context == null) output = curve(buffer = path());
for (i = 0; i <= n; ++i) {
if (!(i < n && defined(d = data[i], i, data)) === defined0) {
if (defined0 = !defined0) {
j = i;
output.areaStart();
output.lineStart();
} else {
output.lineEnd();
output.lineStart();
for (k = i - 1; k >= j; --k) {
output.point(x0z[k], y0z[k]);
}
output.lineEnd();
output.areaEnd();
}
}
if (defined0) {
x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data);
output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]);
}
}
if (buffer) return output = null, buffer + "" || null;
}
function arealine() {
return line().defined(defined).curve(curve).context(context);
}
area.x = function(_) {
return arguments.length ? (x0 = typeof _ === "function" ? _ : constant$10(+_), x1 = null, area) : x0;
};
area.x0 = function(_) {
return arguments.length ? (x0 = typeof _ === "function" ? _ : constant$10(+_), area) : x0;
};
area.x1 = function(_) {
return arguments.length ? (x1 = _ == null ? null : typeof _ === "function" ? _ : constant$10(+_), area) : x1;
};
area.y = function(_) {
return arguments.length ? (y0 = typeof _ === "function" ? _ : constant$10(+_), y1 = null, area) : y0;
};
area.y0 = function(_) {
return arguments.length ? (y0 = typeof _ === "function" ? _ : constant$10(+_), area) : y0;
};
area.y1 = function(_) {
return arguments.length ? (y1 = _ == null ? null : typeof _ === "function" ? _ : constant$10(+_), area) : y1;
};
area.lineX0 =
area.lineY0 = function() {
return arealine().x(x0).y(y0);
};
area.lineY1 = function() {
return arealine().x(x0).y(y1);
};
area.lineX1 = function() {
return arealine().x(x1).y(y0);
};
area.defined = function(_) {
return arguments.length ? (defined = typeof _ === "function" ? _ : constant$10(!!_), area) : defined;
};
area.curve = function(_) {
return arguments.length ? (curve = _, context != null && (output = curve(context)), area) : curve;
};
area.context = function(_) {
return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context;
};
return area;
};
var descending$1 = function(a, b) {
return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
};
var identity$7 = function(d) {
return d;
};
var pie = function() {
var value = identity$7,
sortValues = descending$1,
sort = null,
startAngle = constant$10(0),
endAngle = constant$10(tau$4),
padAngle = constant$10(0);
function pie(data) {
var i,
n = data.length,
j,
k,
sum = 0,
index = new Array(n),
arcs = new Array(n),
a0 = +startAngle.apply(this, arguments),
da = Math.min(tau$4, Math.max(-tau$4, endAngle.apply(this, arguments) - a0)),
a1,
p = Math.min(Math.abs(da) / n, padAngle.apply(this, arguments)),
pa = p * (da < 0 ? -1 : 1),
v;
for (i = 0; i < n; ++i) {
if ((v = arcs[index[i] = i] = +value(data[i], i, data)) > 0) {
sum += v;
}
}
// Optionally sort the arcs by previously-computed values or by data.
if (sortValues != null) index.sort(function(i, j) { return sortValues(arcs[i], arcs[j]); });
else if (sort != null) index.sort(function(i, j) { return sort(data[i], data[j]); });
// Compute the arcs! They are stored in the original data's order.
for (i = 0, k = sum ? (da - n * pa) / sum : 0; i < n; ++i, a0 = a1) {
j = index[i], v = arcs[j], a1 = a0 + (v > 0 ? v * k : 0) + pa, arcs[j] = {
data: data[j],
index: i,
value: v,
startAngle: a0,
endAngle: a1,
padAngle: p
};
}
return arcs;
}
pie.value = function(_) {
return arguments.length ? (value = typeof _ === "function" ? _ : constant$10(+_), pie) : value;
};
pie.sortValues = function(_) {
return arguments.length ? (sortValues = _, sort = null, pie) : sortValues;
};
pie.sort = function(_) {
return arguments.length ? (sort = _, sortValues = null, pie) : sort;
};
pie.startAngle = function(_) {
return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$10(+_), pie) : startAngle;
};
pie.endAngle = function(_) {
return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$10(+_), pie) : endAngle;
};
pie.padAngle = function(_) {
return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant$10(+_), pie) : padAngle;
};
return pie;
};
var curveRadialLinear = curveRadial(curveLinear);
function Radial(curve) {
this._curve = curve;
}
Radial.prototype = {
areaStart: function() {
this._curve.areaStart();
},
areaEnd: function() {
this._curve.areaEnd();
},
lineStart: function() {
this._curve.lineStart();
},
lineEnd: function() {
this._curve.lineEnd();
},
point: function(a, r) {
this._curve.point(r * Math.sin(a), r * -Math.cos(a));
}
};
function curveRadial(curve) {
function radial(context) {
return new Radial(curve(context));
}
radial._curve = curve;
return radial;
}
function lineRadial(l) {
var c = l.curve;
l.angle = l.x, delete l.x;
l.radius = l.y, delete l.y;
l.curve = function(_) {
return arguments.length ? c(curveRadial(_)) : c()._curve;
};
return l;
}
var lineRadial$1 = function() {
return lineRadial(line().curve(curveRadialLinear));
};
var areaRadial = function() {
var a = area$2().curve(curveRadialLinear),
c = a.curve,
x0 = a.lineX0,
x1 = a.lineX1,
y0 = a.lineY0,
y1 = a.lineY1;
a.angle = a.x, delete a.x;
a.startAngle = a.x0, delete a.x0;
a.endAngle = a.x1, delete a.x1;
a.radius = a.y, delete a.y;
a.innerRadius = a.y0, delete a.y0;
a.outerRadius = a.y1, delete a.y1;
a.lineStartAngle = function() { return lineRadial(x0()); }, delete a.lineX0;
a.lineEndAngle = function() { return lineRadial(x1()); }, delete a.lineX1;
a.lineInnerRadius = function() { return lineRadial(y0()); }, delete a.lineY0;
a.lineOuterRadius = function() { return lineRadial(y1()); }, delete a.lineY1;
a.curve = function(_) {
return arguments.length ? c(curveRadial(_)) : c()._curve;
};
return a;
};
var pointRadial = function(x, y) {
return [(y = +y) * Math.cos(x -= Math.PI / 2), y * Math.sin(x)];
};
var slice$6 = Array.prototype.slice;
function linkSource(d) {
return d.source;
}
function linkTarget(d) {
return d.target;
}
function link$2(curve) {
var source = linkSource,
target = linkTarget,
x$$1 = x$3,
y$$1 = y$3,
context = null;
function link() {
var buffer, argv = slice$6.call(arguments), s = source.apply(this, argv), t = target.apply(this, argv);
if (!context) context = buffer = path();
curve(context, +x$$1.apply(this, (argv[0] = s, argv)), +y$$1.apply(this, argv), +x$$1.apply(this, (argv[0] = t, argv)), +y$$1.apply(this, argv));
if (buffer) return context = null, buffer + "" || null;
}
link.source = function(_) {
return arguments.length ? (source = _, link) : source;
};
link.target = function(_) {
return arguments.length ? (target = _, link) : target;
};
link.x = function(_) {
return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant$10(+_), link) : x$$1;
};
link.y = function(_) {
return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant$10(+_), link) : y$$1;
};
link.context = function(_) {
return arguments.length ? ((context = _ == null ? null : _), link) : context;
};
return link;
}
function curveHorizontal(context, x0, y0, x1, y1) {
context.moveTo(x0, y0);
context.bezierCurveTo(x0 = (x0 + x1) / 2, y0, x0, y1, x1, y1);
}
function curveVertical(context, x0, y0, x1, y1) {
context.moveTo(x0, y0);
context.bezierCurveTo(x0, y0 = (y0 + y1) / 2, x1, y0, x1, y1);
}
function curveRadial$1(context, x0, y0, x1, y1) {
var p0 = pointRadial(x0, y0),
p1 = pointRadial(x0, y0 = (y0 + y1) / 2),
p2 = pointRadial(x1, y0),
p3 = pointRadial(x1, y1);
context.moveTo(p0[0], p0[1]);
context.bezierCurveTo(p1[0], p1[1], p2[0], p2[1], p3[0], p3[1]);
}
function linkHorizontal() {
return link$2(curveHorizontal);
}
function linkVertical() {
return link$2(curveVertical);
}
function linkRadial() {
var l = link$2(curveRadial$1);
l.angle = l.x, delete l.x;
l.radius = l.y, delete l.y;
return l;
}
var circle$2 = {
draw: function(context, size) {
var r = Math.sqrt(size / pi$4);
context.moveTo(r, 0);
context.arc(0, 0, r, 0, tau$4);
}
};
var cross$2 = {
draw: function(context, size) {
var r = Math.sqrt(size / 5) / 2;
context.moveTo(-3 * r, -r);
context.lineTo(-r, -r);
context.lineTo(-r, -3 * r);
context.lineTo(r, -3 * r);
context.lineTo(r, -r);
context.lineTo(3 * r, -r);
context.lineTo(3 * r, r);
context.lineTo(r, r);
context.lineTo(r, 3 * r);
context.lineTo(-r, 3 * r);
context.lineTo(-r, r);
context.lineTo(-3 * r, r);
context.closePath();
}
};
var tan30 = Math.sqrt(1 / 3);
var tan30_2 = tan30 * 2;
var diamond = {
draw: function(context, size) {
var y = Math.sqrt(size / tan30_2),
x = y * tan30;
context.moveTo(0, -y);
context.lineTo(x, 0);
context.lineTo(0, y);
context.lineTo(-x, 0);
context.closePath();
}
};
var ka = 0.89081309152928522810;
var kr = Math.sin(pi$4 / 10) / Math.sin(7 * pi$4 / 10);
var kx = Math.sin(tau$4 / 10) * kr;
var ky = -Math.cos(tau$4 / 10) * kr;
var star = {
draw: function(context, size) {
var r = Math.sqrt(size * ka),
x = kx * r,
y = ky * r;
context.moveTo(0, -r);
context.lineTo(x, y);
for (var i = 1; i < 5; ++i) {
var a = tau$4 * i / 5,
c = Math.cos(a),
s = Math.sin(a);
context.lineTo(s * r, -c * r);
context.lineTo(c * x - s * y, s * x + c * y);
}
context.closePath();
}
};
var square = {
draw: function(context, size) {
var w = Math.sqrt(size),
x = -w / 2;
context.rect(x, x, w, w);
}
};
var sqrt3 = Math.sqrt(3);
var triangle = {
draw: function(context, size) {
var y = -Math.sqrt(size / (sqrt3 * 3));
context.moveTo(0, y * 2);
context.lineTo(-sqrt3 * y, -y);
context.lineTo(sqrt3 * y, -y);
context.closePath();
}
};
var c = -0.5;
var s = Math.sqrt(3) / 2;
var k = 1 / Math.sqrt(12);
var a = (k / 2 + 1) * 3;
var wye = {
draw: function(context, size) {
var r = Math.sqrt(size / a),
x0 = r / 2,
y0 = r * k,
x1 = x0,
y1 = r * k + r,
x2 = -x1,
y2 = y1;
context.moveTo(x0, y0);
context.lineTo(x1, y1);
context.lineTo(x2, y2);
context.lineTo(c * x0 - s * y0, s * x0 + c * y0);
context.lineTo(c * x1 - s * y1, s * x1 + c * y1);
context.lineTo(c * x2 - s * y2, s * x2 + c * y2);
context.lineTo(c * x0 + s * y0, c * y0 - s * x0);
context.lineTo(c * x1 + s * y1, c * y1 - s * x1);
context.lineTo(c * x2 + s * y2, c * y2 - s * x2);
context.closePath();
}
};
var symbols = [
circle$2,
cross$2,
diamond,
square,
star,
triangle,
wye
];
var symbol = function() {
var type = constant$10(circle$2),
size = constant$10(64),
context = null;
function symbol() {
var buffer;
if (!context) context = buffer = path();
type.apply(this, arguments).draw(context, +size.apply(this, arguments));
if (buffer) return context = null, buffer + "" || null;
}
symbol.type = function(_) {
return arguments.length ? (type = typeof _ === "function" ? _ : constant$10(_), symbol) : type;
};
symbol.size = function(_) {
return arguments.length ? (size = typeof _ === "function" ? _ : constant$10(+_), symbol) : size;
};
symbol.context = function(_) {
return arguments.length ? (context = _ == null ? null : _, symbol) : context;
};
return symbol;
};
var noop$2 = function() {};
function point$2(that, x, y) {
that._context.bezierCurveTo(
(2 * that._x0 + that._x1) / 3,
(2 * that._y0 + that._y1) / 3,
(that._x0 + 2 * that._x1) / 3,
(that._y0 + 2 * that._y1) / 3,
(that._x0 + 4 * that._x1 + x) / 6,
(that._y0 + 4 * that._y1 + y) / 6
);
}
function Basis(context) {
this._context = context;
}
Basis.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._x0 = this._x1 =
this._y0 = this._y1 = NaN;
this._point = 0;
},
lineEnd: function() {
switch (this._point) {
case 3: point$2(this, this._x1, this._y1); // proceed
case 2: this._context.lineTo(this._x1, this._y1); break;
}
if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
this._line = 1 - this._line;
},
point: function(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
case 1: this._point = 2; break;
case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // proceed
default: point$2(this, x, y); break;
}
this._x0 = this._x1, this._x1 = x;
this._y0 = this._y1, this._y1 = y;
}
};
var basis$2 = function(context) {
return new Basis(context);
};
function BasisClosed(context) {
this._context = context;
}
BasisClosed.prototype = {
areaStart: noop$2,
areaEnd: noop$2,
lineStart: function() {
this._x0 = this._x1 = this._x2 = this._x3 = this._x4 =
this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = NaN;
this._point = 0;
},
lineEnd: function() {
switch (this._point) {
case 1: {
this._context.moveTo(this._x2, this._y2);
this._context.closePath();
break;
}
case 2: {
this._context.moveTo((this._x2 + 2 * this._x3) / 3, (this._y2 + 2 * this._y3) / 3);
this._context.lineTo((this._x3 + 2 * this._x2) / 3, (this._y3 + 2 * this._y2) / 3);
this._context.closePath();
break;
}
case 3: {
this.point(this._x2, this._y2);
this.point(this._x3, this._y3);
this.point(this._x4, this._y4);
break;
}
}
},
point: function(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1; this._x2 = x, this._y2 = y; break;
case 1: this._point = 2; this._x3 = x, this._y3 = y; break;
case 2: this._point = 3; this._x4 = x, this._y4 = y; this._context.moveTo((this._x0 + 4 * this._x1 + x) / 6, (this._y0 + 4 * this._y1 + y) / 6); break;
default: point$2(this, x, y); break;
}
this._x0 = this._x1, this._x1 = x;
this._y0 = this._y1, this._y1 = y;
}
};
var basisClosed$1 = function(context) {
return new BasisClosed(context);
};
function BasisOpen(context) {
this._context = context;
}
BasisOpen.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._x0 = this._x1 =
this._y0 = this._y1 = NaN;
this._point = 0;
},
lineEnd: function() {
if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
this._line = 1 - this._line;
},
point: function(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1; break;
case 1: this._point = 2; break;
case 2: this._point = 3; var x0 = (this._x0 + 4 * this._x1 + x) / 6, y0 = (this._y0 + 4 * this._y1 + y) / 6; this._line ? this._context.lineTo(x0, y0) : this._context.moveTo(x0, y0); break;
case 3: this._point = 4; // proceed
default: point$2(this, x, y); break;
}
this._x0 = this._x1, this._x1 = x;
this._y0 = this._y1, this._y1 = y;
}
};
var basisOpen = function(context) {
return new BasisOpen(context);
};
function Bundle(context, beta) {
this._basis = new Basis(context);
this._beta = beta;
}
Bundle.prototype = {
lineStart: function() {
this._x = [];
this._y = [];
this._basis.lineStart();
},
lineEnd: function() {
var x = this._x,
y = this._y,
j = x.length - 1;
if (j > 0) {
var x0 = x[0],
y0 = y[0],
dx = x[j] - x0,
dy = y[j] - y0,
i = -1,
t;
while (++i <= j) {
t = i / j;
this._basis.point(
this._beta * x[i] + (1 - this._beta) * (x0 + t * dx),
this._beta * y[i] + (1 - this._beta) * (y0 + t * dy)
);
}
}
this._x = this._y = null;
this._basis.lineEnd();
},
point: function(x, y) {
this._x.push(+x);
this._y.push(+y);
}
};
var bundle = ((function custom(beta) {
function bundle(context) {
return beta === 1 ? new Basis(context) : new Bundle(context, beta);
}
bundle.beta = function(beta) {
return custom(+beta);
};
return bundle;
}))(0.85);
function point$3(that, x, y) {
that._context.bezierCurveTo(
that._x1 + that._k * (that._x2 - that._x0),
that._y1 + that._k * (that._y2 - that._y0),
that._x2 + that._k * (that._x1 - x),
that._y2 + that._k * (that._y1 - y),
that._x2,
that._y2
);
}
function Cardinal(context, tension) {
this._context = context;
this._k = (1 - tension) / 6;
}
Cardinal.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._x0 = this._x1 = this._x2 =
this._y0 = this._y1 = this._y2 = NaN;
this._point = 0;
},
lineEnd: function() {
switch (this._point) {
case 2: this._context.lineTo(this._x2, this._y2); break;
case 3: point$3(this, this._x1, this._y1); break;
}
if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
this._line = 1 - this._line;
},
point: function(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
case 1: this._point = 2; this._x1 = x, this._y1 = y; break;
case 2: this._point = 3; // proceed
default: point$3(this, x, y); break;
}
this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
}
};
var cardinal = ((function custom(tension) {
function cardinal(context) {
return new Cardinal(context, tension);
}
cardinal.tension = function(tension) {
return custom(+tension);
};
return cardinal;
}))(0);
function CardinalClosed(context, tension) {
this._context = context;
this._k = (1 - tension) / 6;
}
CardinalClosed.prototype = {
areaStart: noop$2,
areaEnd: noop$2,
lineStart: function() {
this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =
this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;
this._point = 0;
},
lineEnd: function() {
switch (this._point) {
case 1: {
this._context.moveTo(this._x3, this._y3);
this._context.closePath();
break;
}
case 2: {
this._context.lineTo(this._x3, this._y3);
this._context.closePath();
break;
}
case 3: {
this.point(this._x3, this._y3);
this.point(this._x4, this._y4);
this.point(this._x5, this._y5);
break;
}
}
},
point: function(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1; this._x3 = x, this._y3 = y; break;
case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;
case 2: this._point = 3; this._x5 = x, this._y5 = y; break;
default: point$3(this, x, y); break;
}
this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
}
};
var cardinalClosed = ((function custom(tension) {
function cardinal(context) {
return new CardinalClosed(context, tension);
}
cardinal.tension = function(tension) {
return custom(+tension);
};
return cardinal;
}))(0);
function CardinalOpen(context, tension) {
this._context = context;
this._k = (1 - tension) / 6;
}
CardinalOpen.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._x0 = this._x1 = this._x2 =
this._y0 = this._y1 = this._y2 = NaN;
this._point = 0;
},
lineEnd: function() {
if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
this._line = 1 - this._line;
},
point: function(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1; break;
case 1: this._point = 2; break;
case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;
case 3: this._point = 4; // proceed
default: point$3(this, x, y); break;
}
this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
}
};
var cardinalOpen = ((function custom(tension) {
function cardinal(context) {
return new CardinalOpen(context, tension);
}
cardinal.tension = function(tension) {
return custom(+tension);
};
return cardinal;
}))(0);
function point$4(that, x, y) {
var x1 = that._x1,
y1 = that._y1,
x2 = that._x2,
y2 = that._y2;
if (that._l01_a > epsilon$3) {
var a = 2 * that._l01_2a + 3 * that._l01_a * that._l12_a + that._l12_2a,
n = 3 * that._l01_a * (that._l01_a + that._l12_a);
x1 = (x1 * a - that._x0 * that._l12_2a + that._x2 * that._l01_2a) / n;
y1 = (y1 * a - that._y0 * that._l12_2a + that._y2 * that._l01_2a) / n;
}
if (that._l23_a > epsilon$3) {
var b = 2 * that._l23_2a + 3 * that._l23_a * that._l12_a + that._l12_2a,
m = 3 * that._l23_a * (that._l23_a + that._l12_a);
x2 = (x2 * b + that._x1 * that._l23_2a - x * that._l12_2a) / m;
y2 = (y2 * b + that._y1 * that._l23_2a - y * that._l12_2a) / m;
}
that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2);
}
function CatmullRom(context, alpha) {
this._context = context;
this._alpha = alpha;
}
CatmullRom.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._x0 = this._x1 = this._x2 =
this._y0 = this._y1 = this._y2 = NaN;
this._l01_a = this._l12_a = this._l23_a =
this._l01_2a = this._l12_2a = this._l23_2a =
this._point = 0;
},
lineEnd: function() {
switch (this._point) {
case 2: this._context.lineTo(this._x2, this._y2); break;
case 3: this.point(this._x2, this._y2); break;
}
if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
this._line = 1 - this._line;
},
point: function(x, y) {
x = +x, y = +y;
if (this._point) {
var x23 = this._x2 - x,
y23 = this._y2 - y;
this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
}
switch (this._point) {
case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
case 1: this._point = 2; break;
case 2: this._point = 3; // proceed
default: point$4(this, x, y); break;
}
this._l01_a = this._l12_a, this._l12_a = this._l23_a;
this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
}
};
var catmullRom = ((function custom(alpha) {
function catmullRom(context) {
return alpha ? new CatmullRom(context, alpha) : new Cardinal(context, 0);
}
catmullRom.alpha = function(alpha) {
return custom(+alpha);
};
return catmullRom;
}))(0.5);
function CatmullRomClosed(context, alpha) {
this._context = context;
this._alpha = alpha;
}
CatmullRomClosed.prototype = {
areaStart: noop$2,
areaEnd: noop$2,
lineStart: function() {
this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =
this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;
this._l01_a = this._l12_a = this._l23_a =
this._l01_2a = this._l12_2a = this._l23_2a =
this._point = 0;
},
lineEnd: function() {
switch (this._point) {
case 1: {
this._context.moveTo(this._x3, this._y3);
this._context.closePath();
break;
}
case 2: {
this._context.lineTo(this._x3, this._y3);
this._context.closePath();
break;
}
case 3: {
this.point(this._x3, this._y3);
this.point(this._x4, this._y4);
this.point(this._x5, this._y5);
break;
}
}
},
point: function(x, y) {
x = +x, y = +y;
if (this._point) {
var x23 = this._x2 - x,
y23 = this._y2 - y;
this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
}
switch (this._point) {
case 0: this._point = 1; this._x3 = x, this._y3 = y; break;
case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;
case 2: this._point = 3; this._x5 = x, this._y5 = y; break;
default: point$4(this, x, y); break;
}
this._l01_a = this._l12_a, this._l12_a = this._l23_a;
this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
}
};
var catmullRomClosed = ((function custom(alpha) {
function catmullRom(context) {
return alpha ? new CatmullRomClosed(context, alpha) : new CardinalClosed(context, 0);
}
catmullRom.alpha = function(alpha) {
return custom(+alpha);
};
return catmullRom;
}))(0.5);
function CatmullRomOpen(context, alpha) {
this._context = context;
this._alpha = alpha;
}
CatmullRomOpen.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._x0 = this._x1 = this._x2 =
this._y0 = this._y1 = this._y2 = NaN;
this._l01_a = this._l12_a = this._l23_a =
this._l01_2a = this._l12_2a = this._l23_2a =
this._point = 0;
},
lineEnd: function() {
if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
this._line = 1 - this._line;
},
point: function(x, y) {
x = +x, y = +y;
if (this._point) {
var x23 = this._x2 - x,
y23 = this._y2 - y;
this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
}
switch (this._point) {
case 0: this._point = 1; break;
case 1: this._point = 2; break;
case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;
case 3: this._point = 4; // proceed
default: point$4(this, x, y); break;
}
this._l01_a = this._l12_a, this._l12_a = this._l23_a;
this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
}
};
var catmullRomOpen = ((function custom(alpha) {
function catmullRom(context) {
return alpha ? new CatmullRomOpen(context, alpha) : new CardinalOpen(context, 0);
}
catmullRom.alpha = function(alpha) {
return custom(+alpha);
};
return catmullRom;
}))(0.5);
function LinearClosed(context) {
this._context = context;
}
LinearClosed.prototype = {
areaStart: noop$2,
areaEnd: noop$2,
lineStart: function() {
this._point = 0;
},
lineEnd: function() {
if (this._point) this._context.closePath();
},
point: function(x, y) {
x = +x, y = +y;
if (this._point) this._context.lineTo(x, y);
else this._point = 1, this._context.moveTo(x, y);
}
};
var linearClosed = function(context) {
return new LinearClosed(context);
};
function sign$1(x) {
return x < 0 ? -1 : 1;
}
// Calculate the slopes of the tangents (Hermite-type interpolation) based on
// the following paper: Steffen, M. 1990. A Simple Method for Monotonic
// Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO.
// NOV(II), P. 443, 1990.
function slope3(that, x2, y2) {
var h0 = that._x1 - that._x0,
h1 = x2 - that._x1,
s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0),
s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0),
p = (s0 * h1 + s1 * h0) / (h0 + h1);
return (sign$1(s0) + sign$1(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0;
}
// Calculate a one-sided slope.
function slope2(that, t) {
var h = that._x1 - that._x0;
return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t;
}
// According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations
// "you can express cubic Hermite interpolation in terms of cubic Bézier curves
// with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1".
function point$5(that, t0, t1) {
var x0 = that._x0,
y0 = that._y0,
x1 = that._x1,
y1 = that._y1,
dx = (x1 - x0) / 3;
that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1);
}
function MonotoneX(context) {
this._context = context;
}
MonotoneX.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._x0 = this._x1 =
this._y0 = this._y1 =
this._t0 = NaN;
this._point = 0;
},
lineEnd: function() {
switch (this._point) {
case 2: this._context.lineTo(this._x1, this._y1); break;
case 3: point$5(this, this._t0, slope2(this, this._t0)); break;
}
if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
this._line = 1 - this._line;
},
point: function(x, y) {
var t1 = NaN;
x = +x, y = +y;
if (x === this._x1 && y === this._y1) return; // Ignore coincident points.
switch (this._point) {
case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
case 1: this._point = 2; break;
case 2: this._point = 3; point$5(this, slope2(this, t1 = slope3(this, x, y)), t1); break;
default: point$5(this, this._t0, t1 = slope3(this, x, y)); break;
}
this._x0 = this._x1, this._x1 = x;
this._y0 = this._y1, this._y1 = y;
this._t0 = t1;
}
};
function MonotoneY(context) {
this._context = new ReflectContext(context);
}
(MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) {
MonotoneX.prototype.point.call(this, y, x);
};
function ReflectContext(context) {
this._context = context;
}
ReflectContext.prototype = {
moveTo: function(x, y) { this._context.moveTo(y, x); },
closePath: function() { this._context.closePath(); },
lineTo: function(x, y) { this._context.lineTo(y, x); },
bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); }
};
function monotoneX(context) {
return new MonotoneX(context);
}
function monotoneY(context) {
return new MonotoneY(context);
}
function Natural(context) {
this._context = context;
}
Natural.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._x = [];
this._y = [];
},
lineEnd: function() {
var x = this._x,
y = this._y,
n = x.length;
if (n) {
this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]);
if (n === 2) {
this._context.lineTo(x[1], y[1]);
} else {
var px = controlPoints(x),
py = controlPoints(y);
for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) {
this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]);
}
}
}
if (this._line || (this._line !== 0 && n === 1)) this._context.closePath();
this._line = 1 - this._line;
this._x = this._y = null;
},
point: function(x, y) {
this._x.push(+x);
this._y.push(+y);
}
};
// See https://www.particleincell.com/2012/bezier-splines/ for derivation.
function controlPoints(x) {
var i,
n = x.length - 1,
m,
a = new Array(n),
b = new Array(n),
r = new Array(n);
a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1];
for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1];
a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n];
for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1];
a[n - 1] = r[n - 1] / b[n - 1];
for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i];
b[n - 1] = (x[n] + a[n - 1]) / 2;
for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1];
return [a, b];
}
var natural = function(context) {
return new Natural(context);
};
function Step(context, t) {
this._context = context;
this._t = t;
}
Step.prototype = {
areaStart: function() {
this._line = 0;
},
areaEnd: function() {
this._line = NaN;
},
lineStart: function() {
this._x = this._y = NaN;
this._point = 0;
},
lineEnd: function() {
if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y);
if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line;
},
point: function(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
case 1: this._point = 2; // proceed
default: {
if (this._t <= 0) {
this._context.lineTo(this._x, y);
this._context.lineTo(x, y);
} else {
var x1 = this._x * (1 - this._t) + x * this._t;
this._context.lineTo(x1, this._y);
this._context.lineTo(x1, y);
}
break;
}
}
this._x = x, this._y = y;
}
};
var step = function(context) {
return new Step(context, 0.5);
};
function stepBefore(context) {
return new Step(context, 0);
}
function stepAfter(context) {
return new Step(context, 1);
}
var none$1 = function(series, order) {
if (!((n = series.length) > 1)) return;
for (var i = 1, j, s0, s1 = series[order[0]], n, m = s1.length; i < n; ++i) {
s0 = s1, s1 = series[order[i]];
for (j = 0; j < m; ++j) {
s1[j][1] += s1[j][0] = isNaN(s0[j][1]) ? s0[j][0] : s0[j][1];
}
}
};
var none$2 = function(series) {
var n = series.length, o = new Array(n);
while (--n >= 0) o[n] = n;
return o;
};
function stackValue(d, key) {
return d[key];
}
var stack = function() {
var keys = constant$10([]),
order = none$2,
offset = none$1,
value = stackValue;
function stack(data) {
var kz = keys.apply(this, arguments),
i,
m = data.length,
n = kz.length,
sz = new Array(n),
oz;
for (i = 0; i < n; ++i) {
for (var ki = kz[i], si = sz[i] = new Array(m), j = 0, sij; j < m; ++j) {
si[j] = sij = [0, +value(data[j], ki, j, data)];
sij.data = data[j];
}
si.key = ki;
}
for (i = 0, oz = order(sz); i < n; ++i) {
sz[oz[i]].index = i;
}
offset(sz, oz);
return sz;
}
stack.keys = function(_) {
return arguments.length ? (keys = typeof _ === "function" ? _ : constant$10(slice$6.call(_)), stack) : keys;
};
stack.value = function(_) {
return arguments.length ? (value = typeof _ === "function" ? _ : constant$10(+_), stack) : value;
};
stack.order = function(_) {
return arguments.length ? (order = _ == null ? none$2 : typeof _ === "function" ? _ : constant$10(slice$6.call(_)), stack) : order;
};
stack.offset = function(_) {
return arguments.length ? (offset = _ == null ? none$1 : _, stack) : offset;
};
return stack;
};
var expand = function(series, order) {
if (!((n = series.length) > 0)) return;
for (var i, n, j = 0, m = series[0].length, y; j < m; ++j) {
for (y = i = 0; i < n; ++i) y += series[i][j][1] || 0;
if (y) for (i = 0; i < n; ++i) series[i][j][1] /= y;
}
none$1(series, order);
};
var diverging = function(series, order) {
if (!((n = series.length) > 1)) return;
for (var i, j = 0, d, dy, yp, yn, n, m = series[order[0]].length; j < m; ++j) {
for (yp = yn = 0, i = 0; i < n; ++i) {
if ((dy = (d = series[order[i]][j])[1] - d[0]) >= 0) {
d[0] = yp, d[1] = yp += dy;
} else if (dy < 0) {
d[1] = yn, d[0] = yn += dy;
} else {
d[0] = yp;
}
}
}
};
var silhouette = function(series, order) {
if (!((n = series.length) > 0)) return;
for (var j = 0, s0 = series[order[0]], n, m = s0.length; j < m; ++j) {
for (var i = 0, y = 0; i < n; ++i) y += series[i][j][1] || 0;
s0[j][1] += s0[j][0] = -y / 2;
}
none$1(series, order);
};
var wiggle = function(series, order) {
if (!((n = series.length) > 0) || !((m = (s0 = series[order[0]]).length) > 0)) return;
for (var y = 0, j = 1, s0, m, n; j < m; ++j) {
for (var i = 0, s1 = 0, s2 = 0; i < n; ++i) {
var si = series[order[i]],
sij0 = si[j][1] || 0,
sij1 = si[j - 1][1] || 0,
s3 = (sij0 - sij1) / 2;
for (var k = 0; k < i; ++k) {
var sk = series[order[k]],
skj0 = sk[j][1] || 0,
skj1 = sk[j - 1][1] || 0;
s3 += skj0 - skj1;
}
s1 += sij0, s2 += s3 * sij0;
}
s0[j - 1][1] += s0[j - 1][0] = y;
if (s1) y -= s2 / s1;
}
s0[j - 1][1] += s0[j - 1][0] = y;
none$1(series, order);
};
var ascending$2 = function(series) {
var sums = series.map(sum$2);
return none$2(series).sort(function(a, b) { return sums[a] - sums[b]; });
};
function sum$2(series) {
var s = 0, i = -1, n = series.length, v;
while (++i < n) if (v = +series[i][1]) s += v;
return s;
}
var descending$2 = function(series) {
return ascending$2(series).reverse();
};
var insideOut = function(series) {
var n = series.length,
i,
j,
sums = series.map(sum$2),
order = none$2(series).sort(function(a, b) { return sums[b] - sums[a]; }),
top = 0,
bottom = 0,
tops = [],
bottoms = [];
for (i = 0; i < n; ++i) {
j = order[i];
if (top < bottom) {
top += sums[j];
tops.push(j);
} else {
bottom += sums[j];
bottoms.push(j);
}
}
return bottoms.reverse().concat(tops);
};
var reverse = function(series) {
return none$2(series).reverse();
};
var constant$11 = function(x) {
return function() {
return x;
};
};
function x$4(d) {
return d[0];
}
function y$4(d) {
return d[1];
}
function RedBlackTree() {
this._ = null; // root node
}
function RedBlackNode(node) {
node.U = // parent node
node.C = // color - true for red, false for black
node.L = // left node
node.R = // right node
node.P = // previous node
node.N = null; // next node
}
RedBlackTree.prototype = {
constructor: RedBlackTree,
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 = RedBlackFirst(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) {
RedBlackRotateLeft(this, parent);
after = parent;
parent = after.U;
}
parent.C = false;
grandpa.C = true;
RedBlackRotateRight(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) {
RedBlackRotateRight(this, parent);
after = parent;
parent = after.U;
}
parent.C = false;
grandpa.C = true;
RedBlackRotateLeft(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 = RedBlackFirst(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;
RedBlackRotateLeft(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;
RedBlackRotateRight(this, sibling);
sibling = parent.R;
}
sibling.C = parent.C;
parent.C = sibling.R.C = false;
RedBlackRotateLeft(this, parent);
node = this._;
break;
}
} else {
sibling = parent.L;
if (sibling.C) {
sibling.C = false;
parent.C = true;
RedBlackRotateRight(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;
RedBlackRotateLeft(this, sibling);
sibling = parent.L;
}
sibling.C = parent.C;
parent.C = sibling.L.C = false;
RedBlackRotateRight(this, parent);
node = this._;
break;
}
}
sibling.C = true;
node = parent;
parent = parent.U;
} while (!node.C);
if (node) node.C = false;
}
};
function RedBlackRotateLeft(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 RedBlackRotateRight(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 RedBlackFirst(node) {
while (node.L) node = node.L;
return node;
}
function createEdge(left, right, v0, v1) {
var edge = [null, null],
index = edges.push(edge) - 1;
edge.left = left;
edge.right = right;
if (v0) setEdgeEnd(edge, left, right, v0);
if (v1) setEdgeEnd(edge, right, left, v1);
cells[left.index].halfedges.push(index);
cells[right.index].halfedges.push(index);
return edge;
}
function createBorderEdge(left, v0, v1) {
var edge = [v0, v1];
edge.left = left;
return edge;
}
function setEdgeEnd(edge, left, right, vertex) {
if (!edge[0] && !edge[1]) {
edge[0] = vertex;
edge.left = left;
edge.right = right;
} else if (edge.left === right) {
edge[1] = vertex;
} else {
edge[0] = vertex;
}
}
// Liang–Barsky line clipping.
function clipEdge(edge, x0, y0, x1, y1) {
var a = edge[0],
b = edge[1],
ax = a[0],
ay = a[1],
bx = b[0],
by = b[1],
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) && !(t1 < 1)) return true; // TODO Better check?
if (t0 > 0) edge[0] = [ax + t0 * dx, ay + t0 * dy];
if (t1 < 1) edge[1] = [ax + t1 * dx, ay + t1 * dy];
return true;
}
function connectEdge(edge, x0, y0, x1, y1) {
var v1 = edge[1];
if (v1) return true;
var v0 = edge[0],
left = edge.left,
right = edge.right,
lx = left[0],
ly = left[1],
rx = right[0],
ry = right[1],
fx = (lx + rx) / 2,
fy = (ly + ry) / 2,
fm,
fb;
if (ry === ly) {
if (fx < x0 || fx >= x1) return;
if (lx > rx) {
if (!v0) v0 = [fx, y0];
else if (v0[1] >= y1) return;
v1 = [fx, y1];
} else {
if (!v0) v0 = [fx, y1];
else if (v0[1] < y0) return;
v1 = [fx, y0];
}
} else {
fm = (lx - rx) / (ry - ly);
fb = fy - fm * fx;
if (fm < -1 || fm > 1) {
if (lx > rx) {
if (!v0) v0 = [(y0 - fb) / fm, y0];
else if (v0[1] >= y1) return;
v1 = [(y1 - fb) / fm, y1];
} else {
if (!v0) v0 = [(y1 - fb) / fm, y1];
else if (v0[1] < y0) return;
v1 = [(y0 - fb) / fm, y0];
}
} else {
if (ly < ry) {
if (!v0) v0 = [x0, fm * x0 + fb];
else if (v0[0] >= x1) return;
v1 = [x1, fm * x1 + fb];
} else {
if (!v0) v0 = [x1, fm * x1 + fb];
else if (v0[0] < x0) return;
v1 = [x0, fm * x0 + fb];
}
}
}
edge[0] = v0;
edge[1] = v1;
return true;
}
function clipEdges(x0, y0, x1, y1) {
var i = edges.length,
edge;
while (i--) {
if (!connectEdge(edge = edges[i], x0, y0, x1, y1)
|| !clipEdge(edge, x0, y0, x1, y1)
|| !(Math.abs(edge[0][0] - edge[1][0]) > epsilon$4
|| Math.abs(edge[0][1] - edge[1][1]) > epsilon$4)) {
delete edges[i];
}
}
}
function createCell(site) {
return cells[site.index] = {
site: site,
halfedges: []
};
}
function cellHalfedgeAngle(cell, edge) {
var site = cell.site,
va = edge.left,
vb = edge.right;
if (site === vb) vb = va, va = site;
if (vb) return Math.atan2(vb[1] - va[1], vb[0] - va[0]);
if (site === va) va = edge[1], vb = edge[0];
else va = edge[0], vb = edge[1];
return Math.atan2(va[0] - vb[0], vb[1] - va[1]);
}
function cellHalfedgeStart(cell, edge) {
return edge[+(edge.left !== cell.site)];
}
function cellHalfedgeEnd(cell, edge) {
return edge[+(edge.left === cell.site)];
}
function sortCellHalfedges() {
for (var i = 0, n = cells.length, cell, halfedges, j, m; i < n; ++i) {
if ((cell = cells[i]) && (m = (halfedges = cell.halfedges).length)) {
var index = new Array(m),
array = new Array(m);
for (j = 0; j < m; ++j) index[j] = j, array[j] = cellHalfedgeAngle(cell, edges[halfedges[j]]);
index.sort(function(i, j) { return array[j] - array[i]; });
for (j = 0; j < m; ++j) array[j] = halfedges[index[j]];
for (j = 0; j < m; ++j) halfedges[j] = array[j];
}
}
}
function clipCells(x0, y0, x1, y1) {
var nCells = cells.length,
iCell,
cell,
site,
iHalfedge,
halfedges,
nHalfedges,
start,
startX,
startY,
end,
endX,
endY,
cover = true;
for (iCell = 0; iCell < nCells; ++iCell) {
if (cell = cells[iCell]) {
site = cell.site;
halfedges = cell.halfedges;
iHalfedge = halfedges.length;
// Remove any dangling clipped edges.
while (iHalfedge--) {
if (!edges[halfedges[iHalfedge]]) {
halfedges.splice(iHalfedge, 1);
}
}
// Insert any border edges as necessary.
iHalfedge = 0, nHalfedges = halfedges.length;
while (iHalfedge < nHalfedges) {
end = cellHalfedgeEnd(cell, edges[halfedges[iHalfedge]]), endX = end[0], endY = end[1];
start = cellHalfedgeStart(cell, edges[halfedges[++iHalfedge % nHalfedges]]), startX = start[0], startY = start[1];
if (Math.abs(endX - startX) > epsilon$4 || Math.abs(endY - startY) > epsilon$4) {
halfedges.splice(iHalfedge, 0, edges.push(createBorderEdge(site, end,
Math.abs(endX - x0) < epsilon$4 && y1 - endY > epsilon$4 ? [x0, Math.abs(startX - x0) < epsilon$4 ? startY : y1]
: Math.abs(endY - y1) < epsilon$4 && x1 - endX > epsilon$4 ? [Math.abs(startY - y1) < epsilon$4 ? startX : x1, y1]
: Math.abs(endX - x1) < epsilon$4 && endY - y0 > epsilon$4 ? [x1, Math.abs(startX - x1) < epsilon$4 ? startY : y0]
: Math.abs(endY - y0) < epsilon$4 && endX - x0 > epsilon$4 ? [Math.abs(startY - y0) < epsilon$4 ? startX : x0, y0]
: null)) - 1);
++nHalfedges;
}
}
if (nHalfedges) cover = false;
}
}
// If there weren’t any edges, have the closest site cover the extent.
// It doesn’t matter which corner of the extent we measure!
if (cover) {
var dx, dy, d2, dc = Infinity;
for (iCell = 0, cover = null; iCell < nCells; ++iCell) {
if (cell = cells[iCell]) {
site = cell.site;
dx = site[0] - x0;
dy = site[1] - y0;
d2 = dx * dx + dy * dy;
if (d2 < dc) dc = d2, cover = cell;
}
}
if (cover) {
var v00 = [x0, y0], v01 = [x0, y1], v11 = [x1, y1], v10 = [x1, y0];
cover.halfedges.push(
edges.push(createBorderEdge(site = cover.site, v00, v01)) - 1,
edges.push(createBorderEdge(site, v01, v11)) - 1,
edges.push(createBorderEdge(site, v11, v10)) - 1,
edges.push(createBorderEdge(site, v10, v00)) - 1
);
}
}
// Lastly delete any cells with no edges; these were entirely clipped.
for (iCell = 0; iCell < nCells; ++iCell) {
if (cell = cells[iCell]) {
if (!cell.halfedges.length) {
delete cells[iCell];
}
}
}
}
var circlePool = [];
var firstCircle;
function Circle() {
RedBlackNode(this);
this.x =
this.y =
this.arc =
this.site =
this.cy = null;
}
function attachCircle(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[0],
by = cSite[1],
ax = lSite[0] - bx,
ay = lSite[1] - by,
cx = rSite[0] - bx,
cy = rSite[1] - by;
var d = 2 * (ax * cy - ay * cx);
if (d >= -epsilon2$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;
var circle = circlePool.pop() || new Circle;
circle.arc = arc;
circle.site = cSite;
circle.x = x + bx;
circle.y = (circle.cy = y + by) + Math.sqrt(x * x + y * y); // y bottom
arc.circle = circle;
var before = null,
node = circles._;
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; }
}
}
circles.insert(before, circle);
if (!before) firstCircle = circle;
}
function detachCircle(arc) {
var circle = arc.circle;
if (circle) {
if (!circle.P) firstCircle = circle.N;
circles.remove(circle);
circlePool.push(circle);
RedBlackNode(circle);
arc.circle = null;
}
}
var beachPool = [];
function Beach() {
RedBlackNode(this);
this.edge =
this.site =
this.circle = null;
}
function createBeach(site) {
var beach = beachPool.pop() || new Beach;
beach.site = site;
return beach;
}
function detachBeach(beach) {
detachCircle(beach);
beaches.remove(beach);
beachPool.push(beach);
RedBlackNode(beach);
}
function removeBeach(beach) {
var circle = beach.circle,
x = circle.x,
y = circle.cy,
vertex = [x, y],
previous = beach.P,
next = beach.N,
disappearing = [beach];
detachBeach(beach);
var lArc = previous;
while (lArc.circle
&& Math.abs(x - lArc.circle.x) < epsilon$4
&& Math.abs(y - lArc.circle.cy) < epsilon$4) {
previous = lArc.P;
disappearing.unshift(lArc);
detachBeach(lArc);
lArc = previous;
}
disappearing.unshift(lArc);
detachCircle(lArc);
var rArc = next;
while (rArc.circle
&& Math.abs(x - rArc.circle.x) < epsilon$4
&& Math.abs(y - rArc.circle.cy) < epsilon$4) {
next = rArc.N;
disappearing.push(rArc);
detachBeach(rArc);
rArc = next;
}
disappearing.push(rArc);
detachCircle(rArc);
var nArcs = disappearing.length,
iArc;
for (iArc = 1; iArc < nArcs; ++iArc) {
rArc = disappearing[iArc];
lArc = disappearing[iArc - 1];
setEdgeEnd(rArc.edge, lArc.site, rArc.site, vertex);
}
lArc = disappearing[0];
rArc = disappearing[nArcs - 1];
rArc.edge = createEdge(lArc.site, rArc.site, null, vertex);
attachCircle(lArc);
attachCircle(rArc);
}
function addBeach(site) {
var x = site[0],
directrix = site[1],
lArc,
rArc,
dxl,
dxr,
node = beaches._;
while (node) {
dxl = leftBreakPoint(node, directrix) - x;
if (dxl > epsilon$4) node = node.L; else {
dxr = x - rightBreakPoint(node, directrix);
if (dxr > epsilon$4) {
if (!node.R) {
lArc = node;
break;
}
node = node.R;
} else {
if (dxl > -epsilon$4) {
lArc = node.P;
rArc = node;
} else if (dxr > -epsilon$4) {
lArc = node;
rArc = node.N;
} else {
lArc = rArc = node;
}
break;
}
}
}
createCell(site);
var newArc = createBeach(site);
beaches.insert(lArc, newArc);
if (!lArc && !rArc) return;
if (lArc === rArc) {
detachCircle(lArc);
rArc = createBeach(lArc.site);
beaches.insert(newArc, rArc);
newArc.edge = rArc.edge = createEdge(lArc.site, newArc.site);
attachCircle(lArc);
attachCircle(rArc);
return;
}
if (!rArc) { // && lArc
newArc.edge = createEdge(lArc.site, newArc.site);
return;
}
// else lArc !== rArc
detachCircle(lArc);
detachCircle(rArc);
var lSite = lArc.site,
ax = lSite[0],
ay = lSite[1],
bx = site[0] - ax,
by = site[1] - ay,
rSite = rArc.site,
cx = rSite[0] - ax,
cy = rSite[1] - ay,
d = 2 * (bx * cy - by * cx),
hb = bx * bx + by * by,
hc = cx * cx + cy * cy,
vertex = [(cy * hb - by * hc) / d + ax, (bx * hc - cx * hb) / d + ay];
setEdgeEnd(rArc.edge, lSite, rSite, vertex);
newArc.edge = createEdge(lSite, site, null, vertex);
rArc.edge = createEdge(site, rSite, null, vertex);
attachCircle(lArc);
attachCircle(rArc);
}
function leftBreakPoint(arc, directrix) {
var site = arc.site,
rfocx = site[0],
rfocy = site[1],
pby2 = rfocy - directrix;
if (!pby2) return rfocx;
var lArc = arc.P;
if (!lArc) return -Infinity;
site = lArc.site;
var lfocx = site[0],
lfocy = site[1],
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 rightBreakPoint(arc, directrix) {
var rArc = arc.N;
if (rArc) return leftBreakPoint(rArc, directrix);
var site = arc.site;
return site[1] === directrix ? site[0] : Infinity;
}
var epsilon$4 = 1e-6;
var epsilon2$2 = 1e-12;
var beaches;
var cells;
var circles;
var edges;
function triangleArea(a, b, c) {
return (a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1]);
}
function lexicographic(a, b) {
return b[1] - a[1]
|| b[0] - a[0];
}
function Diagram(sites, extent) {
var site = sites.sort(lexicographic).pop(),
x,
y,
circle;
edges = [];
cells = new Array(sites.length);
beaches = new RedBlackTree;
circles = new RedBlackTree;
while (true) {
circle = firstCircle;
if (site && (!circle || site[1] < circle.y || (site[1] === circle.y && site[0] < circle.x))) {
if (site[0] !== x || site[1] !== y) {
addBeach(site);
x = site[0], y = site[1];
}
site = sites.pop();
} else if (circle) {
removeBeach(circle.arc);
} else {
break;
}
}
sortCellHalfedges();
if (extent) {
var x0 = +extent[0][0],
y0 = +extent[0][1],
x1 = +extent[1][0],
y1 = +extent[1][1];
clipEdges(x0, y0, x1, y1);
clipCells(x0, y0, x1, y1);
}
this.edges = edges;
this.cells = cells;
beaches =
circles =
edges =
cells = null;
}
Diagram.prototype = {
constructor: Diagram,
polygons: function() {
var edges = this.edges;
return this.cells.map(function(cell) {
var polygon = cell.halfedges.map(function(i) { return cellHalfedgeStart(cell, edges[i]); });
polygon.data = cell.site.data;
return polygon;
});
},
triangles: function() {
var triangles = [],
edges = this.edges;
this.cells.forEach(function(cell, i) {
if (!(m = (halfedges = cell.halfedges).length)) return;
var site = cell.site,
halfedges,
j = -1,
m,
s0,
e1 = edges[halfedges[m - 1]],
s1 = e1.left === site ? e1.right : e1.left;
while (++j < m) {
s0 = s1;
e1 = edges[halfedges[j]];
s1 = e1.left === site ? e1.right : e1.left;
if (s0 && s1 && i < s0.index && i < s1.index && triangleArea(site, s0, s1) < 0) {
triangles.push([site.data, s0.data, s1.data]);
}
}
});
return triangles;
},
links: function() {
return this.edges.filter(function(edge) {
return edge.right;
}).map(function(edge) {
return {
source: edge.left.data,
target: edge.right.data
};
});
},
find: function(x, y, radius) {
var that = this, i0, i1 = that._found || 0, n = that.cells.length, cell;
// Use the previously-found cell, or start with an arbitrary one.
while (!(cell = that.cells[i1])) if (++i1 >= n) return null;
var dx = x - cell.site[0], dy = y - cell.site[1], d2 = dx * dx + dy * dy;
// Traverse the half-edges to find a closer cell, if any.
do {
cell = that.cells[i0 = i1], i1 = null;
cell.halfedges.forEach(function(e) {
var edge = that.edges[e], v = edge.left;
if ((v === cell.site || !v) && !(v = edge.right)) return;
var vx = x - v[0], vy = y - v[1], v2 = vx * vx + vy * vy;
if (v2 < d2) d2 = v2, i1 = v.index;
});
} while (i1 !== null);
that._found = i0;
return radius == null || d2 <= radius * radius ? cell.site : null;
}
};
var voronoi = function() {
var x$$1 = x$4,
y$$1 = y$4,
extent = null;
function voronoi(data) {
return new Diagram(data.map(function(d, i) {
var s = [Math.round(x$$1(d, i, data) / epsilon$4) * epsilon$4, Math.round(y$$1(d, i, data) / epsilon$4) * epsilon$4];
s.index = i;
s.data = d;
return s;
}), extent);
}
voronoi.polygons = function(data) {
return voronoi(data).polygons();
};
voronoi.links = function(data) {
return voronoi(data).links();
};
voronoi.triangles = function(data) {
return voronoi(data).triangles();
};
voronoi.x = function(_) {
return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant$11(+_), voronoi) : x$$1;
};
voronoi.y = function(_) {
return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant$11(+_), voronoi) : y$$1;
};
voronoi.extent = function(_) {
return arguments.length ? (extent = _ == null ? null : [[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]], voronoi) : extent && [[extent[0][0], extent[0][1]], [extent[1][0], extent[1][1]]];
};
voronoi.size = function(_) {
return arguments.length ? (extent = _ == null ? null : [[0, 0], [+_[0], +_[1]]], voronoi) : extent && [extent[1][0] - extent[0][0], extent[1][1] - extent[0][1]];
};
return voronoi;
};
var constant$12 = function(x) {
return function() {
return x;
};
};
function ZoomEvent(target, type, transform) {
this.target = target;
this.type = type;
this.transform = transform;
}
function Transform(k, x, y) {
this.k = k;
this.x = x;
this.y = y;
}
Transform.prototype = {
constructor: Transform,
scale: function(k) {
return k === 1 ? this : new Transform(this.k * k, this.x, this.y);
},
translate: function(x, y) {
return x === 0 & y === 0 ? this : new Transform(this.k, this.x + this.k * x, this.y + this.k * y);
},
apply: function(point) {
return [point[0] * this.k + this.x, point[1] * this.k + this.y];
},
applyX: function(x) {
return x * this.k + this.x;
},
applyY: function(y) {
return y * this.k + this.y;
},
invert: function(location) {
return [(location[0] - this.x) / this.k, (location[1] - this.y) / this.k];
},
invertX: function(x) {
return (x - this.x) / this.k;
},
invertY: function(y) {
return (y - this.y) / this.k;
},
rescaleX: function(x) {
return x.copy().domain(x.range().map(this.invertX, this).map(x.invert, x));
},
rescaleY: function(y) {
return y.copy().domain(y.range().map(this.invertY, this).map(y.invert, y));
},
toString: function() {
return "translate(" + this.x + "," + this.y + ") scale(" + this.k + ")";
}
};
var identity$8 = new Transform(1, 0, 0);
transform$1.prototype = Transform.prototype;
function transform$1(node) {
return node.__zoom || identity$8;
}
function nopropagation$2() {
exports.event.stopImmediatePropagation();
}
var noevent$2 = function() {
exports.event.preventDefault();
exports.event.stopImmediatePropagation();
};
// Ignore right-click, since that should open the context menu.
function defaultFilter$2() {
return !exports.event.button;
}
function defaultExtent$1() {
var e = this, w, h;
if (e instanceof SVGElement) {
e = e.ownerSVGElement || e;
w = e.width.baseVal.value;
h = e.height.baseVal.value;
} else {
w = e.clientWidth;
h = e.clientHeight;
}
return [[0, 0], [w, h]];
}
function defaultTransform() {
return this.__zoom || identity$8;
}
function defaultWheelDelta() {
return -exports.event.deltaY * (exports.event.deltaMode ? 120 : 1) / 500;
}
function touchable$1() {
return "ontouchstart" in this;
}
var zoom = function() {
var filter = defaultFilter$2,
extent = defaultExtent$1,
wheelDelta = defaultWheelDelta,
k0 = 0,
k1 = Infinity,
x0 = -k1,
x1 = k1,
y0 = x0,
y1 = x1,
duration = 250,
interpolate$$1 = interpolateZoom,
gestures = [],
listeners = dispatch("start", "zoom", "end"),
touchstarting,
touchending,
touchDelay = 500,
wheelDelay = 150,
clickDistance2 = 0;
function zoom(selection$$1) {
selection$$1
.property("__zoom", defaultTransform)
.on("wheel.zoom", wheeled)
.on("mousedown.zoom", mousedowned)
.on("dblclick.zoom", dblclicked)
.filter(touchable$1)
.on("touchstart.zoom", touchstarted)
.on("touchmove.zoom", touchmoved)
.on("touchend.zoom touchcancel.zoom", touchended)
.style("touch-action", "none")
.style("-webkit-tap-highlight-color", "rgba(0,0,0,0)");
}
zoom.transform = function(collection, transform) {
var selection$$1 = collection.selection ? collection.selection() : collection;
selection$$1.property("__zoom", defaultTransform);
if (collection !== selection$$1) {
schedule(collection, transform);
} else {
selection$$1.interrupt().each(function() {
gesture(this, arguments)
.start()
.zoom(null, typeof transform === "function" ? transform.apply(this, arguments) : transform)
.end();
});
}
};
zoom.scaleBy = function(selection$$1, k) {
zoom.scaleTo(selection$$1, function() {
var k0 = this.__zoom.k,
k1 = typeof k === "function" ? k.apply(this, arguments) : k;
return k0 * k1;
});
};
zoom.scaleTo = function(selection$$1, k) {
zoom.transform(selection$$1, function() {
var e = extent.apply(this, arguments),
t0 = this.__zoom,
p0 = centroid(e),
p1 = t0.invert(p0),
k1 = typeof k === "function" ? k.apply(this, arguments) : k;
return constrain(translate(scale(t0, k1), p0, p1), e);
});
};
zoom.translateBy = function(selection$$1, x, y) {
zoom.transform(selection$$1, function() {
return constrain(this.__zoom.translate(
typeof x === "function" ? x.apply(this, arguments) : x,
typeof y === "function" ? y.apply(this, arguments) : y
), extent.apply(this, arguments));
});
};
zoom.translateTo = function(selection$$1, x, y) {
zoom.transform(selection$$1, function() {
var e = extent.apply(this, arguments),
t = this.__zoom,
p = centroid(e);
return constrain(identity$8.translate(p[0], p[1]).scale(t.k).translate(
typeof x === "function" ? -x.apply(this, arguments) : -x,
typeof y === "function" ? -y.apply(this, arguments) : -y
), e);
});
};
function scale(transform, k) {
k = Math.max(k0, Math.min(k1, k));
return k === transform.k ? transform : new Transform(k, transform.x, transform.y);
}
function translate(transform, p0, p1) {
var x = p0[0] - p1[0] * transform.k, y = p0[1] - p1[1] * transform.k;
return x === transform.x && y === transform.y ? transform : new Transform(transform.k, x, y);
}
function constrain(transform, extent) {
var dx0 = transform.invertX(extent[0][0]) - x0,
dx1 = transform.invertX(extent[1][0]) - x1,
dy0 = transform.invertY(extent[0][1]) - y0,
dy1 = transform.invertY(extent[1][1]) - y1;
return transform.translate(
dx1 > dx0 ? (dx0 + dx1) / 2 : Math.min(0, dx0) || Math.max(0, dx1),
dy1 > dy0 ? (dy0 + dy1) / 2 : Math.min(0, dy0) || Math.max(0, dy1)
);
}
function centroid(extent) {
return [(+extent[0][0] + +extent[1][0]) / 2, (+extent[0][1] + +extent[1][1]) / 2];
}
function schedule(transition$$1, transform, center) {
transition$$1
.on("start.zoom", function() { gesture(this, arguments).start(); })
.on("interrupt.zoom end.zoom", function() { gesture(this, arguments).end(); })
.tween("zoom", function() {
var that = this,
args = arguments,
g = gesture(that, args),
e = extent.apply(that, args),
p = center || centroid(e),
w = Math.max(e[1][0] - e[0][0], e[1][1] - e[0][1]),
a = that.__zoom,
b = typeof transform === "function" ? transform.apply(that, args) : transform,
i = interpolate$$1(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k));
return function(t) {
if (t === 1) t = b; // Avoid rounding error on end.
else { var l = i(t), k = w / l[2]; t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k); }
g.zoom(null, t);
};
});
}
function gesture(that, args) {
for (var i = 0, n = gestures.length, g; i < n; ++i) {
if ((g = gestures[i]).that === that) {
return g;
}
}
return new Gesture(that, args);
}
function Gesture(that, args) {
this.that = that;
this.args = args;
this.index = -1;
this.active = 0;
this.extent = extent.apply(that, args);
}
Gesture.prototype = {
start: function() {
if (++this.active === 1) {
this.index = gestures.push(this) - 1;
this.emit("start");
}
return this;
},
zoom: function(key, transform) {
if (this.mouse && key !== "mouse") this.mouse[1] = transform.invert(this.mouse[0]);
if (this.touch0 && key !== "touch") this.touch0[1] = transform.invert(this.touch0[0]);
if (this.touch1 && key !== "touch") this.touch1[1] = transform.invert(this.touch1[0]);
this.that.__zoom = transform;
this.emit("zoom");
return this;
},
end: function() {
if (--this.active === 0) {
gestures.splice(this.index, 1);
this.index = -1;
this.emit("end");
}
return this;
},
emit: function(type) {
customEvent(new ZoomEvent(zoom, type, this.that.__zoom), listeners.apply, listeners, [type, this.that, this.args]);
}
};
function wheeled() {
if (!filter.apply(this, arguments)) return;
var g = gesture(this, arguments),
t = this.__zoom,
k = Math.max(k0, Math.min(k1, t.k * Math.pow(2, wheelDelta.apply(this, arguments)))),
p = mouse(this);
// If the mouse is in the same location as before, reuse it.
// If there were recent wheel events, reset the wheel idle timeout.
if (g.wheel) {
if (g.mouse[0][0] !== p[0] || g.mouse[0][1] !== p[1]) {
g.mouse[1] = t.invert(g.mouse[0] = p);
}
clearTimeout(g.wheel);
}
// If this wheel event won’t trigger a transform change, ignore it.
else if (t.k === k) return;
// Otherwise, capture the mouse point and location at the start.
else {
g.mouse = [p, t.invert(p)];
interrupt(this);
g.start();
}
noevent$2();
g.wheel = setTimeout(wheelidled, wheelDelay);
g.zoom("mouse", constrain(translate(scale(t, k), g.mouse[0], g.mouse[1]), g.extent));
function wheelidled() {
g.wheel = null;
g.end();
}
}
function mousedowned() {
if (touchending || !filter.apply(this, arguments)) return;
var g = gesture(this, arguments),
v = select(exports.event.view).on("mousemove.zoom", mousemoved, true).on("mouseup.zoom", mouseupped, true),
p = mouse(this),
x0 = exports.event.clientX,
y0 = exports.event.clientY;
dragDisable(exports.event.view);
nopropagation$2();
g.mouse = [p, this.__zoom.invert(p)];
interrupt(this);
g.start();
function mousemoved() {
noevent$2();
if (!g.moved) {
var dx = exports.event.clientX - x0, dy = exports.event.clientY - y0;
g.moved = dx * dx + dy * dy > clickDistance2;
}
g.zoom("mouse", constrain(translate(g.that.__zoom, g.mouse[0] = mouse(g.that), g.mouse[1]), g.extent));
}
function mouseupped() {
v.on("mousemove.zoom mouseup.zoom", null);
yesdrag(exports.event.view, g.moved);
noevent$2();
g.end();
}
}
function dblclicked() {
if (!filter.apply(this, arguments)) return;
var t0 = this.__zoom,
p0 = mouse(this),
p1 = t0.invert(p0),
k1 = t0.k * (exports.event.shiftKey ? 0.5 : 2),
t1 = constrain(translate(scale(t0, k1), p0, p1), extent.apply(this, arguments));
noevent$2();
if (duration > 0) select(this).transition().duration(duration).call(schedule, t1, p0);
else select(this).call(zoom.transform, t1);
}
function touchstarted() {
if (!filter.apply(this, arguments)) return;
var g = gesture(this, arguments),
touches$$1 = exports.event.changedTouches,
started,
n = touches$$1.length, i, t, p;
nopropagation$2();
for (i = 0; i < n; ++i) {
t = touches$$1[i], p = touch(this, touches$$1, t.identifier);
p = [p, this.__zoom.invert(p), t.identifier];
if (!g.touch0) g.touch0 = p, started = true;
else if (!g.touch1) g.touch1 = p;
}
// If this is a dbltap, reroute to the (optional) dblclick.zoom handler.
if (touchstarting) {
touchstarting = clearTimeout(touchstarting);
if (!g.touch1) {
g.end();
p = select(this).on("dblclick.zoom");
if (p) p.apply(this, arguments);
return;
}
}
if (started) {
touchstarting = setTimeout(function() { touchstarting = null; }, touchDelay);
interrupt(this);
g.start();
}
}
function touchmoved() {
var g = gesture(this, arguments),
touches$$1 = exports.event.changedTouches,
n = touches$$1.length, i, t, p, l;
noevent$2();
if (touchstarting) touchstarting = clearTimeout(touchstarting);
for (i = 0; i < n; ++i) {
t = touches$$1[i], p = touch(this, touches$$1, t.identifier);
if (g.touch0 && g.touch0[2] === t.identifier) g.touch0[0] = p;
else if (g.touch1 && g.touch1[2] === t.identifier) g.touch1[0] = p;
}
t = g.that.__zoom;
if (g.touch1) {
var p0 = g.touch0[0], l0 = g.touch0[1],
p1 = g.touch1[0], l1 = g.touch1[1],
dp = (dp = p1[0] - p0[0]) * dp + (dp = p1[1] - p0[1]) * dp,
dl = (dl = l1[0] - l0[0]) * dl + (dl = l1[1] - l0[1]) * dl;
t = scale(t, Math.sqrt(dp / dl));
p = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2];
l = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2];
}
else if (g.touch0) p = g.touch0[0], l = g.touch0[1];
else return;
g.zoom("touch", constrain(translate(t, p, l), g.extent));
}
function touchended() {
var g = gesture(this, arguments),
touches$$1 = exports.event.changedTouches,
n = touches$$1.length, i, t;
nopropagation$2();
if (touchending) clearTimeout(touchending);
touchending = setTimeout(function() { touchending = null; }, touchDelay);
for (i = 0; i < n; ++i) {
t = touches$$1[i];
if (g.touch0 && g.touch0[2] === t.identifier) delete g.touch0;
else if (g.touch1 && g.touch1[2] === t.identifier) delete g.touch1;
}
if (g.touch1 && !g.touch0) g.touch0 = g.touch1, delete g.touch1;
if (g.touch0) g.touch0[1] = this.__zoom.invert(g.touch0[0]);
else g.end();
}
zoom.wheelDelta = function(_) {
return arguments.length ? (wheelDelta = typeof _ === "function" ? _ : constant$12(+_), zoom) : wheelDelta;
};
zoom.filter = function(_) {
return arguments.length ? (filter = typeof _ === "function" ? _ : constant$12(!!_), zoom) : filter;
};
zoom.extent = function(_) {
return arguments.length ? (extent = typeof _ === "function" ? _ : constant$12([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), zoom) : extent;
};
zoom.scaleExtent = function(_) {
return arguments.length ? (k0 = +_[0], k1 = +_[1], zoom) : [k0, k1];
};
zoom.translateExtent = function(_) {
return arguments.length ? (x0 = +_[0][0], x1 = +_[1][0], y0 = +_[0][1], y1 = +_[1][1], zoom) : [[x0, y0], [x1, y1]];
};
zoom.duration = function(_) {
return arguments.length ? (duration = +_, zoom) : duration;
};
zoom.interpolate = function(_) {
return arguments.length ? (interpolate$$1 = _, zoom) : interpolate$$1;
};
zoom.on = function() {
var value = listeners.on.apply(listeners, arguments);
return value === listeners ? zoom : value;
};
zoom.clickDistance = function(_) {
return arguments.length ? (clickDistance2 = (_ = +_) * _, zoom) : Math.sqrt(clickDistance2);
};
return zoom;
};
var translateSelection = function(xy) {
return this.attr('transform', function(d,i) {
return 'translate('+[typeof xy == 'function' ? xy.call(this, d,i) : xy]+')';
});
};
var parseAttributes = function(name) {
if (typeof name === "string") {
var attr = {},
parts = name.split(/([\.#])/g), p;
name = parts.shift();
while ((p = parts.shift())) {
if (p == '.') attr['class'] = attr['class'] ? attr['class'] + ' ' + parts.shift() : parts.shift();
else if (p == '#') attr.id = parts.shift();
}
return {tag: name, attr: attr};
}
return name;
};
var append = function(name) {
var n = parseAttributes(name), s;
name = creator(n.tag);
s = this.select(function() {
return this.appendChild(name.apply(this, arguments));
});
//attrs not provided by default in v4
for (var key in n.attr) { s.attr(key, n.attr[key]); }
return s;
};
function constantNull$1() {
return null;
}
var insert = function(name, before) {
var n = parseAttributes(name),
create = creator(n.tag),
select$$1 = before == null ? constantNull$1 : typeof before === "function" ? before : selector(before);
var s = this.select(function() {
return this.insertBefore(create.apply(this, arguments), select$$1.apply(this, arguments) || null);
});
//attrs not provided by default in v4
for (var key in n.attr) { s.attr(key, n.attr[key]); }
return s;
};
var parent = function() {
var parents = [];
return this.filter(function() {
if (parents.indexOf(this.parentNode) > -1) return false;
parents.push(this.parentNode);
return true;
}).select(function() {
return this.parentNode;
});
};
var selectAppend = function(name) {
var select$$1 = selector(name),
n = parseAttributes(name), s;
name = creator(n.tag);
s = this.select(function() {
return select$$1.apply(this, arguments) ||
this.appendChild(name.apply(this, arguments));
});
//attrs not provided by default in v4
for (var key in n.attr) { s.attr(key, n.attr[key]); }
return s;
};
var tspans = function(lines, lh) {
return this.selectAll('tspan')
.data(function(d) {
return (typeof(lines) == 'function' ? lines(d) : lines)
.map(function(l) {
return { line: l, parent: d };
});
})
.enter()
.append('tspan')
.text(function(d) { return d.line; })
.attr('x', 0)
.attr('dy', function(d, i) { return i ? (typeof(lh) == 'function' ? lh(d.parent, d.line, i) : lh) || 15 : 0; });
};
var appendMany = function(data, name){
return this.selectAll(null).data(data).enter().append(name);
};
var at = function(name, value) {
if (typeof(name) == 'object'){
for (var key in name){
this.attr(key.replace(/([a-z\d])([A-Z])/g, '$1-$2').toLowerCase(), name[key]);
}
return this;
} else{
return arguments.length == 1 ? this.attr(name) : this.attr(name, value);
}
};
function f(){
var functions = arguments;
//convert all string arguments into field accessors
var i = 0, l = functions.length;
while (i < l) {
if (typeof(functions[i]) === 'string' || typeof(functions[i]) === 'number'){
functions[i] = (function(str){ return function(d){ return d[str]; }; })(functions[i]);
}
i++;
}
//return composition of functions
return function(d) {
var i=0, l = functions.length;
while (i++ < l) d = functions[i-1].call(this, d);
return d;
};
}
f.not = function(d){ return !d; };
f.run = function(d){ return d(); };
f.objToFn = function(obj, defaultVal){
if (arguments.length == 1) defaultVal = undefined;
return function(str){
return typeof(obj[str]) !== undefined ? obj[str] : defaultVal;
};
};
var st = function(name, value) {
if (typeof(name) == 'object'){
for (var key in name){
addStyle(this, key, name[key]);
}
return this;
} else {
return arguments.length == 1 ? this.style(name) : addStyle(this, name, value);
}
function addStyle(sel, style, value){
style = style.replace(/([a-z\d])([A-Z])/g, '$1-$2').toLowerCase();
var pxStyles = 'top left bottom right padding-top padding-left padding-bottom padding-right border-top b-width border-left-width border-botto-width m border-right-width margin-top margin-left margin-bottom margin-right font-size width height stroke-width line-height margin padding border max-width min-width';
if (~pxStyles.indexOf(style) ){
sel.style(style, typeof value == 'function' ? wrapPx(value) : addPx(value));
} else{
sel.style(style, value);
}
return sel;
}
function addPx(d){ return d.match ? d : d + 'px'; }
function wrapPx(fn){
return function(){
var val = fn.apply(this, arguments);
return addPx(val)
}
}
};
// while this might not be reprentative for all fonts, it is
// still better than assuming every character has the same width
// (set monospace=true if you want to bypass this)
var CHAR_W = {
A:7,a:7,B:8,b:7,C:8,c:6,D:9,d:7,E:7,e:7,F:7,f:4,G:9,g:7,H:9,h:7,I:3,i:3,J:5,j:3,K:8,k:6,L:7,l:3,M:11,
m:11,N:9,n:7,O:9,o:7,P:8,p:7,Q:9,q:7,R:8,r:4,S:8,s:6,T:7,t:4,U:9,u:7,V:7,v:6,W:11,w:9,X:7,x:6,Y:7,y:6,Z:7,z:5,
'.':2,',':2,':':2,';':2
};
var wordwrap = function(line, maxCharactersPerLine, minCharactersPerLine, monospace) {
var l, lines = [], w = [], words = [], w1, maxChars, minChars, maxLineW, minLineW;
w1 = line.split(' ');
w1.forEach(function(s, i) {
var w2 = s.split('-');
if (w2.length > 1) {
w2.forEach(function(t, j) {
w.push(t + (j < w2.length - 1 ? '-' : ''));
});
} else {
w.push(s + (i < w1.length - 1 ? ' ' : ''));
}
});
maxChars = maxCharactersPerLine || 40;
minChars = minCharactersPerLine || Math.max(3, Math.min(maxChars * 0.5, 0.75 * w.map(word_len).sort(num_asc)[Math.round(w.length / 2)]));
maxLineW = maxChars * CHAR_W.a;
minLineW = minChars * CHAR_W.a;
l = 0;
w.forEach(function(d) {
var ww = sum(d.split('').map(char_w));
if (l + ww > maxLineW && l > minLineW) {
lines.push(words.join(''));
words.length = 0;
l = 0;
}
l += ww;
return words.push(d);
});
if (words.length) {
lines.push(words.join(''));
}
return lines.filter(function(d) {
return d !== '';
});
function char_w(c) { return !monospace && CHAR_W[c] || CHAR_W.a; }
function word_len(d) { return d.length; }
function num_asc(a, b) { return a - b; }
};
var ascendingKey = function(key) {
return typeof key == 'function' ? function (a, b) {
return key(a) < key(b) ? -1 : key(a) > key(b) ? 1 : key(a) >= key(b) ? 0 : NaN;
} : function (a, b) {
return a[key] < b[key] ? -1 : a[key] > b[key] ? 1 : a[key] >= b[key] ? 0 : NaN;
};
};
var descendingKey = function(key) {
return typeof key == 'function' ? function (a, b) {
return key(b) < key(a) ? -1 : key(b) > key(a) ? 1 : key(b) >= key(a) ? 0 : NaN;
} : function (a, b) {
return b[key] < a[key] ? -1 : b[key] > a[key] ? 1 : b[key] >= a[key] ? 0 : NaN;
};
};
var conventions = function(c){
c = c || {};
c.margin = c.margin || {top: 20, right: 20, bottom: 20, left: 20}
;['top', 'right', 'bottom', 'left'].forEach(function(d){
if (!c.margin[d] && c.margin[d] != 0) c.margin[d] = 20 ;
});
var parentNode = c.parentSel && c.parentSel.node();
c.totalWidth = c.totalWidth || parentNode && parentNode.offsetWidth || 960;
c.totalHeight = c.totalHeight || parentNode && parentNode.offsetHeight || 500;
c.width = c.width || c.totalWidth - c.margin.left - c.margin.right;
c.height = c.height || c.totalHeight - c.margin.top - c.margin.bottom;
c.totalWidth = c.width + c.margin.left + c.margin.right;
c.totalHeight = c.height + c.margin.top + c.margin.bottom;
c.parentSel = c.parentSel || select('body');
c.rootsvg = c.parentSel.append('svg');
c.svg = c.rootsvg
.attr('width', c.totalWidth)
.attr('height', c.totalHeight)
.append('g')
.attr('transform', 'translate(' + c.margin.left + ',' + c.margin.top + ')');
c.x = c.x || linear$2().range([0, c.width]);
c.y = c.y || linear$2().range([c.height, 0]);
c.xAxis = c.xAxis || axisBottom().scale(c.x);
c.yAxis = c.yAxis || axisLeft().scale(c.y);
c.drawAxis = function(){
c.svg.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(0,' + c.height + ')')
.call(c.xAxis);
c.svg.append('g')
.attr('class', 'y axis')
.call(c.yAxis);
};
return c;
};
var clamp = function(min, d, max) {
return Math.max(min, Math.min(max, d))
};
var attachTooltip = function(sel, tooltipSel, fieldFns){
if (!sel.size()) return;
tooltipSel = tooltipSel || select('.tooltip');
sel
.on('mouseover.attachTooltip', ttDisplay)
.on('mousemove.attachTooltip', ttMove)
.on('mouseout.attachTooltip', ttHide)
.on('click.attachTooltip', function(d){ console.log(d); });
var d = sel.datum();
fieldFns = fieldFns || d3keys(d)
.filter(function(str){
return (typeof d[str] != 'object') && (d[str] != 'array');
})
.map(function(str){
return function(d){ return str + ': <b>' + d[str] + '</b>'; };
});
function ttDisplay(d){
tooltipSel
.classed('tooltip-hidden', false)
.html('')
.appendMany(fieldFns, 'div')
.html(function(fn){ return fn(d); });
select(this).classed('tooltipped', true);
}
function ttMove(d){
if (!tooltipSel.size()) return;
var e = exports.event,
x = e.clientX,
y = e.clientY,
bb = tooltipSel.node().getBoundingClientRect(),
left = clamp(20, (x-bb.width/2), window.innerWidth - bb.width - 20),
top = innerHeight - y > 200 ? y + 20 : y - bb.height - 20;
tooltipSel
.style('left', left +'px')
.style('top', top + 'px');
}
function ttHide(d){
tooltipSel.classed('tooltip-hidden', true);
selectAll('.tooltipped').classed('tooltipped', false);
}
};
var loadData = function(){
var q = queue();
var args = [].slice.call(arguments);
var files = args.slice(0, args.length - 1);
var cb = args[args.length - 1];
files.forEach(function(d){
var type = d.split('?')[0].split('.').reverse()[0];
var loadFn = {csv: csv$1, tsv: tsv$1, json: json}[type];
if (!loadFn) return cb(new Error('Invalid type', d));
q.defer(loadFn, d) ;
});
q.awaitAll(cb);
};
var nestBy = function(array, key){
return nest().key(key).entries(array).map(function(d){
d.values.key = d.key;
return d.values;
});
};
var round = function(n, p) {
return p ? Math.round(n * (p = Math.pow(10, p))) / p : Math.round(n);
};
// Clips the specified subject polygon to the specified clip polygon;
// requires the clip polygon to be counterclockwise and convex.
// https://en.wikipedia.org/wiki/Sutherland–Hodgman_algorithm
var polygonClip = function(clip, subject) {
var input,
closed = polygonClosed(subject),
i = -1,
n = clip.length - polygonClosed(clip),
j,
m,
a = clip[n - 1],
b,
c,
d;
while (++i < n) {
input = subject.slice();
subject.length = 0;
b = clip[i];
c = input[(m = input.length - closed) - 1];
j = -1;
while (++j < m) {
d = input[j];
if (polygonInside(d, a, b)) {
if (!polygonInside(c, a, b)) {
subject.push(polygonIntersect(c, d, a, b));
}
subject.push(d);
} else if (polygonInside(c, a, b)) {
subject.push(polygonIntersect(c, d, a, b));
}
c = d;
}
if (closed) subject.push(subject[0]);
a = b;
}
return subject;
};
function polygonInside(p, a, b) {
return (b[0] - a[0]) * (p[1] - a[1]) < (b[1] - a[1]) * (p[0] - a[0]);
}
// Intersect two infinite lines cd and ab.
function 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];
}
// Returns true if the polygon is closed.
function polygonClosed(coordinates) {
var a = coordinates[0],
b = coordinates[coordinates.length - 1];
return !(a[0] - b[0] || a[1] - b[1]);
}
selection.prototype.translate = translateSelection;
transition.prototype.translate = translateSelection;
selection.prototype.append = append;
selection.prototype.insert = insert;
selection.prototype.parent = parent;
selection.prototype.selectAppend = selectAppend;
selection.prototype.tspans = tspans;
selection.prototype.appendMany = appendMany;
selection.prototype.at = at;
selection.prototype.st = st;
transition.prototype.at = at;
transition.prototype.st = st;
selection.prototype.prop = selection.prototype.property;
// export {
// geoNaturalEarth,
// geoSatellite
// } from "d3-geo-projection"
// export * from "graph-scroll"
// change default dates
var nytLocale = {
"dateTime": "%x, %X",
"date": "%-m/%-d/%Y",
"time": "%-I:%M:%S %p",
"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.", "March", "April", "May", "June", "July", "Aug.", "Sept.", "Oct.", "Nov.", "Dec."]
};
defaultLocale$1(nytLocale);
exports.version = version;
exports.bisect = bisectRight;
exports.bisectRight = bisectRight;
exports.bisectLeft = bisectLeft;
exports.ascending = ascending;
exports.bisector = bisector;
exports.cross = cross;
exports.descending = descending;
exports.deviation = deviation;
exports.extent = extent;
exports.histogram = histogram;
exports.thresholdFreedmanDiaconis = freedmanDiaconis;
exports.thresholdScott = scott;
exports.thresholdSturges = sturges;
exports.max = max;
exports.mean = mean;
exports.median = median;
exports.merge = merge;
exports.min = min;
exports.pairs = pairs;
exports.permute = permute;
exports.quantile = threshold;
exports.range = sequence;
exports.scan = scan;
exports.shuffle = shuffle;
exports.sum = sum;
exports.ticks = ticks;
exports.tickIncrement = tickIncrement;
exports.tickStep = tickStep;
exports.transpose = transpose;
exports.variance = variance;
exports.zip = zip;
exports.axisTop = axisTop;
exports.axisRight = axisRight;
exports.axisBottom = axisBottom;
exports.axisLeft = axisLeft;
exports.brush = brush;
exports.brushX = brushX;
exports.brushY = brushY;
exports.brushSelection = brushSelection;
exports.chord = chord;
exports.ribbon = ribbon;
exports.nest = nest;
exports.set = set$2;
exports.map = map$1;
exports.keys = d3keys;
exports.values = values;
exports.entries = entries;
exports.color = color;
exports.rgb = rgb;
exports.hsl = hsl;
exports.lab = lab;
exports.hcl = hcl;
exports.cubehelix = cubehelix;
exports.dispatch = dispatch;
exports.drag = drag;
exports.dragDisable = dragDisable;
exports.dragEnable = yesdrag;
exports.dsvFormat = dsv;
exports.csvParse = csvParse;
exports.csvParseRows = csvParseRows;
exports.csvFormat = csvFormat;
exports.csvFormatRows = csvFormatRows;
exports.tsvParse = tsvParse;
exports.tsvParseRows = tsvParseRows;
exports.tsvFormat = tsvFormat;
exports.tsvFormatRows = tsvFormatRows;
exports.easeLinear = linear$1;
exports.easeQuad = quadInOut;
exports.easeQuadIn = quadIn;
exports.easeQuadOut = quadOut;
exports.easeQuadInOut = quadInOut;
exports.easeCubic = cubicInOut;
exports.easeCubicIn = cubicIn;
exports.easeCubicOut = cubicOut;
exports.easeCubicInOut = cubicInOut;
exports.easePoly = polyInOut;
exports.easePolyIn = polyIn;
exports.easePolyOut = polyOut;
exports.easePolyInOut = polyInOut;
exports.easeSin = sinInOut;
exports.easeSinIn = sinIn;
exports.easeSinOut = sinOut;
exports.easeSinInOut = sinInOut;
exports.easeExp = expInOut;
exports.easeExpIn = expIn;
exports.easeExpOut = expOut;
exports.easeExpInOut = expInOut;
exports.easeCircle = circleInOut;
exports.easeCircleIn = circleIn;
exports.easeCircleOut = circleOut;
exports.easeCircleInOut = circleInOut;
exports.easeBounce = bounceOut;
exports.easeBounceIn = bounceIn;
exports.easeBounceOut = bounceOut;
exports.easeBounceInOut = bounceInOut;
exports.easeBack = backInOut;
exports.easeBackIn = backIn;
exports.easeBackOut = backOut;
exports.easeBackInOut = backInOut;
exports.easeElastic = elasticOut;
exports.easeElasticIn = elasticIn;
exports.easeElasticOut = elasticOut;
exports.easeElasticInOut = elasticInOut;
exports.forceCenter = center$1;
exports.forceCollide = collide;
exports.forceLink = link;
exports.forceManyBody = manyBody;
exports.forceSimulation = simulation;
exports.forceX = x$2;
exports.forceY = y$2;
exports.formatDefaultLocale = defaultLocale;
exports.formatLocale = formatLocale;
exports.formatSpecifier = formatSpecifier;
exports.precisionFixed = precisionFixed;
exports.precisionPrefix = precisionPrefix;
exports.precisionRound = precisionRound;
exports.geoArea = area;
exports.geoBounds = bounds;
exports.geoCentroid = centroid;
exports.geoCircle = circle;
exports.geoClipExtent = extent$1;
exports.geoContains = contains;
exports.geoDistance = distance;
exports.geoGraticule = graticule;
exports.geoGraticule10 = graticule10;
exports.geoInterpolate = interpolate$1;
exports.geoLength = length$1;
exports.geoPath = index$1;
exports.geoAlbers = albers;
exports.geoAlbersUsa = albersUsa;
exports.geoAzimuthalEqualArea = azimuthalEqualArea;
exports.geoAzimuthalEqualAreaRaw = azimuthalEqualAreaRaw;
exports.geoAzimuthalEquidistant = azimuthalEquidistant;
exports.geoAzimuthalEquidistantRaw = azimuthalEquidistantRaw;
exports.geoConicConformal = conicConformal;
exports.geoConicConformalRaw = conicConformalRaw;
exports.geoConicEqualArea = conicEqualArea;
exports.geoConicEqualAreaRaw = conicEqualAreaRaw;
exports.geoConicEquidistant = conicEquidistant;
exports.geoConicEquidistantRaw = conicEquidistantRaw;
exports.geoEquirectangular = equirectangular;
exports.geoEquirectangularRaw = equirectangularRaw;
exports.geoGnomonic = gnomonic;
exports.geoGnomonicRaw = gnomonicRaw;
exports.geoIdentity = identity$5;
exports.geoProjection = projection;
exports.geoProjectionMutator = projectionMutator;
exports.geoMercator = mercator;
exports.geoMercatorRaw = mercatorRaw;
exports.geoOrthographic = orthographic;
exports.geoOrthographicRaw = orthographicRaw;
exports.geoStereographic = stereographic;
exports.geoStereographicRaw = stereographicRaw;
exports.geoTransverseMercator = transverseMercator;
exports.geoTransverseMercatorRaw = transverseMercatorRaw;
exports.geoRotation = rotation;
exports.geoStream = geoStream;
exports.geoTransform = transform;
exports.cluster = cluster;
exports.hierarchy = hierarchy;
exports.pack = index$2;
exports.packSiblings = siblings;
exports.packEnclose = enclose;
exports.partition = partition;
exports.stratify = stratify;
exports.tree = tree;
exports.treemap = index$3;
exports.treemapBinary = binary;
exports.treemapDice = treemapDice;
exports.treemapSlice = treemapSlice;
exports.treemapSliceDice = sliceDice;
exports.treemapSquarify = squarify;
exports.treemapResquarify = resquarify;
exports.interpolate = interpolateValue;
exports.interpolateArray = array$1;
exports.interpolateBasis = basis$1;
exports.interpolateBasisClosed = basisClosed;
exports.interpolateDate = date;
exports.interpolateNumber = reinterpolate;
exports.interpolateObject = object;
exports.interpolateRound = interpolateRound;
exports.interpolateString = interpolateString;
exports.interpolateTransformCss = interpolateTransformCss;
exports.interpolateTransformSvg = interpolateTransformSvg;
exports.interpolateZoom = interpolateZoom;
exports.interpolateRgb = interpolateRgb;
exports.interpolateRgbBasis = rgbBasis;
exports.interpolateRgbBasisClosed = rgbBasisClosed;
exports.interpolateHsl = hsl$2;
exports.interpolateHslLong = hslLong;
exports.interpolateLab = lab$1;
exports.interpolateHcl = hcl$2;
exports.interpolateHclLong = hclLong;
exports.interpolateCubehelix = cubehelix$2;
exports.interpolateCubehelixLong = cubehelixLong;
exports.quantize = quantize;
exports.path = path;
exports.polygonArea = area$1;
exports.polygonCentroid = centroid$1;
exports.polygonHull = hull;
exports.polygonContains = contains$1;
exports.polygonLength = length$2;
exports.quadtree = quadtree;
exports.queue = queue;
exports.randomUniform = uniform;
exports.randomNormal = normal;
exports.randomLogNormal = logNormal;
exports.randomBates = bates;
exports.randomIrwinHall = irwinHall;
exports.randomExponential = exponential$1;
exports.request = request;
exports.html = html;
exports.json = json;
exports.text = text;
exports.xml = xml;
exports.csv = csv$1;
exports.tsv = tsv$1;
exports.scaleBand = band;
exports.scalePoint = point$1;
exports.scaleIdentity = identity$6;
exports.scaleLinear = linear$2;
exports.scaleLog = log$1;
exports.scaleOrdinal = ordinal;
exports.scaleImplicit = implicit;
exports.scalePow = pow$1;
exports.scaleSqrt = sqrt$1;
exports.scaleQuantile = quantile$$1;
exports.scaleQuantize = quantize$1;
exports.scaleThreshold = threshold$1;
exports.scaleTime = time;
exports.scaleUtc = utcTime;
exports.schemeCategory10 = category10;
exports.schemeCategory20b = category20b;
exports.schemeCategory20c = category20c;
exports.schemeCategory20 = category20;
exports.interpolateCubehelixDefault = cubehelix$3;
exports.interpolateRainbow = rainbow$1;
exports.interpolateWarm = warm;
exports.interpolateCool = cool;
exports.interpolateViridis = viridis;
exports.interpolateMagma = magma;
exports.interpolateInferno = inferno;
exports.interpolatePlasma = plasma;
exports.scaleSequential = sequential;
exports.creator = creator;
exports.local = local$1;
exports.matcher = matcher$1;
exports.mouse = mouse;
exports.namespace = namespace;
exports.namespaces = namespaces;
exports.select = select;
exports.selectAll = selectAll;
exports.selection = selection;
exports.selector = selector;
exports.selectorAll = selectorAll;
exports.style = styleValue;
exports.touch = touch;
exports.touches = touches;
exports.window = defaultView;
exports.customEvent = customEvent;
exports.arc = arc;
exports.area = area$2;
exports.line = line;
exports.pie = pie;
exports.areaRadial = areaRadial;
exports.radialArea = areaRadial;
exports.lineRadial = lineRadial$1;
exports.radialLine = lineRadial$1;
exports.pointRadial = pointRadial;
exports.linkHorizontal = linkHorizontal;
exports.linkVertical = linkVertical;
exports.linkRadial = linkRadial;
exports.symbol = symbol;
exports.symbols = symbols;
exports.symbolCircle = circle$2;
exports.symbolCross = cross$2;
exports.symbolDiamond = diamond;
exports.symbolSquare = square;
exports.symbolStar = star;
exports.symbolTriangle = triangle;
exports.symbolWye = wye;
exports.curveBasisClosed = basisClosed$1;
exports.curveBasisOpen = basisOpen;
exports.curveBasis = basis$2;
exports.curveBundle = bundle;
exports.curveCardinalClosed = cardinalClosed;
exports.curveCardinalOpen = cardinalOpen;
exports.curveCardinal = cardinal;
exports.curveCatmullRomClosed = catmullRomClosed;
exports.curveCatmullRomOpen = catmullRomOpen;
exports.curveCatmullRom = catmullRom;
exports.curveLinearClosed = linearClosed;
exports.curveLinear = curveLinear;
exports.curveMonotoneX = monotoneX;
exports.curveMonotoneY = monotoneY;
exports.curveNatural = natural;
exports.curveStep = step;
exports.curveStepAfter = stepAfter;
exports.curveStepBefore = stepBefore;
exports.stack = stack;
exports.stackOffsetExpand = expand;
exports.stackOffsetDiverging = diverging;
exports.stackOffsetNone = none$1;
exports.stackOffsetSilhouette = silhouette;
exports.stackOffsetWiggle = wiggle;
exports.stackOrderAscending = ascending$2;
exports.stackOrderDescending = descending$2;
exports.stackOrderInsideOut = insideOut;
exports.stackOrderNone = none$2;
exports.stackOrderReverse = reverse;
exports.timeInterval = newInterval;
exports.timeMillisecond = millisecond;
exports.timeMilliseconds = milliseconds;
exports.utcMillisecond = millisecond;
exports.utcMilliseconds = milliseconds;
exports.timeSecond = second;
exports.timeSeconds = seconds;
exports.utcSecond = second;
exports.utcSeconds = seconds;
exports.timeMinute = minute;
exports.timeMinutes = minutes;
exports.timeHour = hour;
exports.timeHours = hours;
exports.timeDay = day;
exports.timeDays = days;
exports.timeWeek = sunday;
exports.timeWeeks = sundays;
exports.timeSunday = sunday;
exports.timeSundays = sundays;
exports.timeMonday = monday;
exports.timeMondays = mondays;
exports.timeTuesday = tuesday;
exports.timeTuesdays = tuesdays;
exports.timeWednesday = wednesday;
exports.timeWednesdays = wednesdays;
exports.timeThursday = thursday;
exports.timeThursdays = thursdays;
exports.timeFriday = friday;
exports.timeFridays = fridays;
exports.timeSaturday = saturday;
exports.timeSaturdays = saturdays;
exports.timeMonth = month;
exports.timeMonths = months;
exports.timeYear = year;
exports.timeYears = years;
exports.utcMinute = utcMinute;
exports.utcMinutes = utcMinutes;
exports.utcHour = utcHour;
exports.utcHours = utcHours;
exports.utcDay = utcDay;
exports.utcDays = utcDays;
exports.utcWeek = utcSunday;
exports.utcWeeks = utcSundays;
exports.utcSunday = utcSunday;
exports.utcSundays = utcSundays;
exports.utcMonday = utcMonday;
exports.utcMondays = utcMondays;
exports.utcTuesday = utcTuesday;
exports.utcTuesdays = utcTuesdays;
exports.utcWednesday = utcWednesday;
exports.utcWednesdays = utcWednesdays;
exports.utcThursday = utcThursday;
exports.utcThursdays = utcThursdays;
exports.utcFriday = utcFriday;
exports.utcFridays = utcFridays;
exports.utcSaturday = utcSaturday;
exports.utcSaturdays = utcSaturdays;
exports.utcMonth = utcMonth;
exports.utcMonths = utcMonths;
exports.utcYear = utcYear;
exports.utcYears = utcYears;
exports.timeFormatDefaultLocale = defaultLocale$1;
exports.timeFormatLocale = formatLocale$1;
exports.isoFormat = formatIso;
exports.isoParse = parseIso;
exports.now = now;
exports.timer = timer;
exports.timerFlush = timerFlush;
exports.timeout = timeout$1;
exports.interval = interval$1;
exports.transition = transition;
exports.active = active;
exports.interrupt = interrupt;
exports.voronoi = voronoi;
exports.zoom = zoom;
exports.zoomTransform = transform$1;
exports.zoomIdentity = identity$8;
exports.wordwrap = wordwrap;
exports.parseAttributes = parseAttributes;
exports.f = f;
exports.ascendingKey = ascendingKey;
exports.descendingKey = descendingKey;
exports.conventions = conventions;
exports.attachTooltip = attachTooltip;
exports.loadData = loadData;
exports.nestBy = nestBy;
exports.round = round;
exports.clamp = clamp;
exports.polygonClip = polygonClip;
Object.defineProperty(exports, '__esModule', { value: true });
})));
tournmentName bracketName matchName gameName gameId blue red winner loser timestamp
NA 2016 Summer Split na_2016_regionals match-a NV|TL|G1|d38334c5ac894897a5dbe 72ba3e59-8cf7-46d9-ae37-ce2262f76414 TL NV NV TL 1472939099084
NA 2016 Summer Split na_2016_regionals match-a NV|TL|G2|d38334c5ac894897a5dbe 5a9f6442-d1e7-4370-8a99-8449559afb41 TL NV NV TL 1472939896911
NA 2016 Summer Split na_2016_regionals match-a NV|TL|G3|d38334c5ac894897a5dbe 00a63f01-c6c1-4fba-9888-c2028b666bc8 NV TL NV TL 1472943750059
NA 2016 Summer Split na_2016_regionals match-b C9|NV|G1|0f64f57bc8f54d6697f2f 36003741-8138-41a1-97c2-e45a91d0e0a6 C9 NV C9 NV 1473026579795
NA 2016 Summer Split na_2016_regionals match-b C9|NV|G2|0f64f57bc8f54d6697f2f d9790510-a6e2-4611-96e5-d0034f8f8f57 NV C9 C9 NV 1473027254376
NA 2016 Summer Split na_2016_regionals match-b C9|NV|G3|0f64f57bc8f54d6697f2f 8d0be023-1d20-4d7c-ba7e-1375885fb757 C9 NV C9 NV 1473030169754
NA 2016 Summer Split na_2016_regionals match-c C9|IMT|G1|e4954fff115944969cbb c3e4e55d-fa8c-4dd8-a29b-d4f51c23efb7 IMT C9 C9 IMT 1473120066088
NA 2016 Summer Split na_2016_regionals match-c C9|IMT|G2|e4954fff115944969cbb c5379eb2-e983-486b-ba5c-d7583701af63 C9 IMT C9 IMT 1473120078239
NA 2016 Summer Split na_2016_regionals match-c C9|IMT|G3|e4954fff115944969cbb 86abc116-e0b1-4b8f-8a89-38eedee6f66c IMT C9 IMT C9 1473123319055
NA 2016 Summer Split na_2016_regionals match-c C9|IMT|G4|e4954fff115944969cbb 9007d2d3-52ba-45dc-9323-0e4381a0299a C9 IMT C9 IMT 1473126240970
NA 2016 Summer Split na_2016_summer_playoffs third-place CLG|IMT|G1|1437cd7b156c4bdba6a 8df8d12a-e32e-4304-9321-93ecd1a312b5 IMT CLG CLG IMT 1472341519893
NA 2016 Summer Split na_2016_summer_playoffs third-place CLG|IMT|G2|1437cd7b156c4bdba6a 30aedd2b-fcf6-4871-a72b-8aaf24f7bb9d CLG IMT IMT CLG 1472341501611
NA 2016 Summer Split na_2016_summer_playoffs third-place CLG|IMT|G3|1437cd7b156c4bdba6a 3f761043-0c4a-452e-b368-325166273df8 CLG IMT IMT CLG 1472345562310
NA 2016 Summer Split na_2016_summer_playoffs third-place CLG|IMT|G4|1437cd7b156c4bdba6a e1878d25-e2be-4953-bae5-985c6f1788b4 CLG IMT CLG IMT 1472350692485
NA 2016 Summer Split na_2016_summer_playoffs third-place CLG|IMT|G5|1437cd7b156c4bdba6a 1e606198-0fbd-4708-9838-269585136fa2 IMT CLG IMT CLG 1472354834457
NA 2016 Summer Split na_2016_summer_playoffs quarter-final-1 CLG|TL|G1|1c9007279bae436da316 6e09b10c-0b1f-4285-b155-bc54b71e90d9 CLG TL CLG TL 1471236925577
NA 2016 Summer Split na_2016_summer_playoffs quarter-final-1 CLG|TL|G2|1c9007279bae436da316 387c64e3-c255-4a22-b818-f38938a1b05a CLG TL CLG TL 1471236944247
NA 2016 Summer Split na_2016_summer_playoffs quarter-final-1 CLG|TL|G3|1c9007279bae436da316 cd36bb7c-9a32-4f95-9a7e-737e4eaeea3e CLG TL TL CLG 1471236964530
NA 2016 Summer Split na_2016_summer_playoffs quarter-final-1 CLG|TL|G4|1c9007279bae436da316 6b9aa8ab-dcf1-4369-a0a3-952c64caa5c3 CLG TL CLG TL 1471236995608
NA 2016 Summer Split na_2016_summer_playoffs quarter-final-2 C9|NV|G1|b7b9ac87468b436e8f10e a660f16d-f703-4dd2-bf4b-7cc5e699be6a C9 NV NV C9 1471237182270
NA 2016 Summer Split na_2016_summer_playoffs quarter-final-2 C9|NV|G2|b7b9ac87468b436e8f10e 533a72df-04bf-4a05-ab0b-497f9bf75917 C9 NV C9 NV 1471236850295
NA 2016 Summer Split na_2016_summer_playoffs quarter-final-2 C9|NV|G3|b7b9ac87468b436e8f10e c81d145a-bead-4ae9-b1eb-ed7cb8f43a35 C9 NV C9 NV 1471236869379
NA 2016 Summer Split na_2016_summer_playoffs quarter-final-2 C9|NV|G4|b7b9ac87468b436e8f10e 45bdad75-7cdf-4cd1-8683-17892bd2a474 C9 NV C9 NV 1471236897528
NA 2016 Summer Split na_2016_summer_playoffs semi-final-1 CLG|TSM|G1r2|cd92158052684ee2a bf0967d7-6a76-49e7-8555-f79c758452f9 TSM CLG TSM CLG 1471817939293
NA 2016 Summer Split na_2016_summer_playoffs semi-final-1 CLG|TSM|G2|cd92158052684ee2a51 5e4b2ea0-d163-4ca5-a500-e0deb469ba29 CLG TSM TSM CLG 1471822380128
NA 2016 Summer Split na_2016_summer_playoffs semi-final-1 CLG|TSM|G3|cd92158052684ee2a51 5a6027e8-3ce5-45cd-aee1-3d0f9dfb260a TSM CLG TSM CLG 1471827153032
NA 2016 Summer Split na_2016_summer_playoffs grand-final C9|TSM|G1|38404ccc13be4c6dbc41 c9543527-e1fd-4ce1-9ee3-8c297a2380db TSM C9 C9 TSM 1472423961548
NA 2016 Summer Split na_2016_summer_playoffs grand-final C9|TSM|G2|38404ccc13be4c6dbc41 ad8572ff-3ac6-4ca1-9173-99d05a7ef924 C9 TSM TSM C9 1472425305016
NA 2016 Summer Split na_2016_summer_playoffs grand-final C9|TSM|G3|38404ccc13be4c6dbc41 51c5ec5c-4365-4ead-9661-a50ef9a57e98 TSM C9 TSM C9 1472427774117
NA 2016 Summer Split na_2016_summer_playoffs grand-final C9|TSM|G4|38404ccc13be4c6dbc41 d31bae97-2936-401b-a787-f73abb7fa7fd C9 TSM TSM C9 1472437981425
NA 2016 Summer Split na_2016_summer_playoffs semi-final-2 C9|IMT|G1|28a6bba558794666897e 133b385d-91b0-4dbe-9037-520f171394b2 IMT C9 IMT C9 1471733242345
NA 2016 Summer Split na_2016_summer_playoffs semi-final-2 C9|IMT|G2|28a6bba558794666897e 24ec9fa0-60bf-4766-91b2-502be5bceb84 C9 IMT C9 IMT 1471738000143
NA 2016 Summer Split na_2016_summer_playoffs semi-final-2 C9|IMT|G3|28a6bba558794666897e de37c259-9022-4371-b16e-55492671b358 IMT C9 C9 IMT 1471741385420
NA 2016 Summer Split na_2016_summer_playoffs semi-final-2 C9|IMT|G4|28a6bba558794666897e 2a2b1b34-8419-417e-91fa-214c8ae6858c C9 IMT IMT C9 1471744263962
NA 2016 Summer Split na_2016_summer_playoffs semi-final-2 C9|IMT|G5r2|28a6bba55879466689 827c383a-c6af-4e7a-8d9f-b755a870bbe9 IMT C9 C9 IMT 1471753597335
NA 2016 Summer Split regular_season IMT-vs-APX APX|IMT|G1|dbdbc5cb900949a5bbf 042b1616-8729-417b-92d1-f5df779131dc IMT APX IMT APX 1467499882826
NA 2016 Summer Split regular_season IMT-vs-APX APX|IMT|G2|dbdbc5cb900949a5bbf 400147b3-6b1e-4d9a-9def-e3fa903a1494 APX IMT IMT APX 1467517529378
NA 2016 Summer Split regular_season NRG-vs-APX APX|NRG|G1|45cf2345b936410281c c61fef7e-c58e-41c1-8276-4b8fa3ac6a3f NRG APX APX NRG 1468101791101
NA 2016 Summer Split regular_season NRG-vs-APX APX|NRG|G2|45cf2345b936410281c ecadc486-fae1-4522-9ddb-6a7f75fb02c4 APX NRG APX NRG 1468108749997
NA 2016 Summer Split regular_season FOX-vs-TL FOX|TL|G1|47ee45b7cb6e4f4ba16a ecd40ad3-6ff5-4a98-96c5-74401c2ade04 FOX TL TL FOX 1465780692112
NA 2016 Summer Split regular_season FOX-vs-TL FOX|TL|G2|47ee45b7cb6e4f4ba16a e00cc26d-9e2e-41b1-8dd5-edc25fd76bd3 TL FOX TL FOX 1465783639093
NA 2016 Summer Split regular_season P1-vs-FOX FOX|P1|G1|ac516825d74947089c00 b46dac09-eb41-45ae-a42d-aa08938f10f2 P1 FOX FOX P1 1468099529701
NA 2016 Summer Split regular_season P1-vs-FOX FOX|P1|G2|ac516825d74947089c00 cceffa0f-357f-4a5e-bb4f-a6bfecc357e4 FOX P1 P1 FOX 1468102577045
NA 2016 Summer Split regular_season P1-vs-FOX FOX|P1|G3|ac516825d74947089c00 7f6040fb-e9d4-417b-8fad-4c5f5b45fda8 P1 FOX P1 FOX 1468108837129
NA 2016 Summer Split regular_season FOX-vs-CLG CLG|FOX|G1|d1c3bd4b9a124de7b21 981a70df-467d-415c-ad9e-1ff341c320df FOX CLG CLG FOX 1469401916620
NA 2016 Summer Split regular_season FOX-vs-CLG CLG|FOX|G2|d1c3bd4b9a124de7b21 2091f102-3e3d-4eb7-98a6-49bccbf15c42 CLG FOX CLG FOX 1469406383956
NA 2016 Summer Split regular_season NV-vs-TSM NV|TSM|G1|29907f39b6a04b4d8c47 73908644-310d-4500-881f-d720b2f054e3 NV TSM TSM NV 1466977082530
NA 2016 Summer Split regular_season NV-vs-TSM NV|TSM|G2|29907f39b6a04b4d8c47 e7085467-8ce2-425a-b8ed-cfe40e4026cd TSM NV TSM NV 1466979346118
NA 2016 Summer Split regular_season APX-vs-IMT APX|IMT|G1|6dae9ea854fa405195e a032c1b6-7efe-41a8-a058-0a761eb559e8 APX IMT IMT APX 1469317110770
NA 2016 Summer Split regular_season APX-vs-IMT APX|IMT|G2|6dae9ea854fa405195e a05cb9cc-3709-4b0c-88d6-2465150f869a IMT APX IMT APX 1469318863497
NA 2016 Summer Split regular_season IMT-vs-TSM IMT|TSM|G1|e63f76abf29c41c9857 040de5ba-ee48-477e-9116-94e10db693ec IMT TSM TSM IMT 1469841501952
NA 2016 Summer Split regular_season IMT-vs-TSM IMT|TSM|G2|e63f76abf29c41c9857 f5aeebaa-3752-488d-9608-e3a3edaf1bdd TSM IMT TSM IMT 1469845838779
NA 2016 Summer Split regular_season C9-vs-TL C9|TL|G1|62b5a0f1b49d46d49db0c b867b2c5-da41-4872-a7a7-b04a147af70b C9 TL C9 TL 1467427948815
NA 2016 Summer Split regular_season C9-vs-TL C9|TL|G2r2|62b5a0f1b49d46d49db 5ebbaeaf-9697-422a-acf1-21389976cd29 TL C9 TL C9 1467443822118
NA 2016 Summer Split regular_season C9-vs-TL C9|TL|G3|62b5a0f1b49d46d49db0c f3b39c40-bf14-4ba7-a039-b3bdc591faab C9 TL TL C9 1467437019264
NA 2016 Summer Split regular_season APX-vs-CLG APX|CLG|G1|a4dac265d60144129f9 9344019a-1bb5-4ef4-ad92-63900d678c35 APX CLG APX CLG 1465167692434
NA 2016 Summer Split regular_season APX-vs-CLG APX|CLG|G2|a4dac265d60144129f9 55544358-b528-4ba4-a252-64d4a5a185fe CLG APX CLG APX 1465167953653
NA 2016 Summer Split regular_season APX-vs-CLG APX|CLG|G3|a4dac265d60144129f9 c4db7513-b922-44b1-bf53-a4e4afdc3a56 APX CLG APX CLG 1465172594994
NA 2016 Summer Split regular_season P1-vs-IMT IMT|P1|G1|6d6f411e336c40d48c4c 015e41c3-1906-43ed-af9f-e6400d0c280c P1 IMT P1 IMT 1469924579654
NA 2016 Summer Split regular_season P1-vs-IMT IMT|P1|G2|6d6f411e336c40d48c4c 27d0cd70-8411-48ea-9e2a-bd9618875d84 IMT P1 IMT P1 1469925636095
NA 2016 Summer Split regular_season P1-vs-IMT IMT|P1|G3|6d6f411e336c40d48c4c c6ecf43b-c278-41d5-b115-2f3d0b181ef7 P1 IMT IMT P1 1469931313198
NA 2016 Summer Split regular_season C9-vs-NRG C9|NRG|G1|25b49032edf84002bce6 71626909-b196-408b-ba80-19e0cf07755d C9 NRG C9 NRG 1466976761125
NA 2016 Summer Split regular_season C9-vs-NRG C9|NRG|G2|25b49032edf84002bce6 3371d58c-6c12-4313-aea8-4e18a9030b07 NRG C9 C9 NRG 1466979629662
NA 2016 Summer Split regular_season C9-vs-NV C9|NV|G1|a01248b074264db484e8a e524c216-30bf-47eb-8755-27c1ed3d95b6 C9 NV C9 NV 1466890665529
NA 2016 Summer Split regular_season C9-vs-NV C9|NV|G2|a01248b074264db484e8a 50017fbb-0e7e-4f44-8ccf-c5c3db3426d5 NV C9 C9 NV 1466894177927
NA 2016 Summer Split regular_season NRG-vs-TSM NRG|TSM|G1|5b814971749f41b69f8 b724f4b6-2400-4ec7-93e6-5d2c8a4774f2 NRG TSM TSM NRG 1466373375279
NA 2016 Summer Split regular_season NRG-vs-TSM NRG|TSM|G2|5b814971749f41b69f8 25b8a3d8-f79c-430c-85a5-7255caa96541 TSM NRG TSM NRG 1466374051876
NA 2016 Summer Split regular_season TSM-vs-C9 C9|TSM|G1|04c3197615a042739623 e0ea204b-5288-4ce8-9249-86c90fe0cda3 TSM C9 TSM C9 1468031939708
NA 2016 Summer Split regular_season TSM-vs-C9 C9|TSM|G2|04c3197615a042739623 f3d408b4-1a59-4e62-9c78-1c1716c710ea C9 TSM TSM C9 1468036400891
NA 2016 Summer Split regular_season NRG-vs-P1 NRG|P1|G1|28fc7453efcb4eb39461 3be51a18-25ac-41d8-866e-f3906280c730 NRG P1 NRG P1 1466903603347
NA 2016 Summer Split regular_season NRG-vs-P1 NRG|P1|G2|28fc7453efcb4eb39461 b5ae6b0f-7285-4244-8534-7e40985ceb42 P1 NRG P1 NRG 1466908311324
NA 2016 Summer Split regular_season NRG-vs-P1 NRG|P1|G3|28fc7453efcb4eb39461 2a25df97-ae00-4026-b46d-ef4a5f6da24f NRG P1 NRG P1 1466913094385
NA 2016 Summer Split regular_season C9-vs-APX APX|C9|G1|0834a750478244daa297 394919cc-bbb9-4fed-a139-b1aa02f88948 C9 APX APX C9 1468710826198
NA 2016 Summer Split regular_season C9-vs-APX APX|C9|G2|0834a750478244daa297 221c178f-5495-4884-85f4-f4a0cb84c538 APX C9 C9 APX 1468719124823
NA 2016 Summer Split regular_season C9-vs-APX APX|C9|G3|0834a750478244daa297 c9b2b0f8-2321-4c52-af33-646c6e67cfda C9 APX C9 APX 1468719825359
NA 2016 Summer Split regular_season TL-vs-P1 P1|TL|G1|1d5574f3fb554d9ba5a0d 230909d9-656d-43a1-a8de-a9b956535439 TL P1 TL P1 1466225301766
NA 2016 Summer Split regular_season TL-vs-P1 P1|TL|G2|1d5574f3fb554d9ba5a0d b1923df5-f849-42b0-9b18-20ea57f7c626 P1 TL TL P1 1466229859492
NA 2016 Summer Split regular_season IMT-vs-NV IMT|NV|G1|ff9f7ce8ffbe41efb555 bee97655-8c8e-45cc-995f-33d6847eb176 IMT NV IMT NV 1466289918334
NA 2016 Summer Split regular_season IMT-vs-NV IMT|NV|G2|ff9f7ce8ffbe41efb555 4c93f691-69a4-4a15-b00a-359193e4ffdd NV IMT IMT NV 1466291675109
NA 2016 Summer Split regular_season IMT-vs-TL IMT|TL|G1|6051b60b067947139a37 21e7e37d-116d-4f12-9f04-fe0210a01f7e IMT TL IMT TL 1466897075219
NA 2016 Summer Split regular_season IMT-vs-TL IMT|TL|G2|6051b60b067947139a37 fc18cd7e-506d-4497-aa6e-bcfc125f2e60 TL IMT IMT TL 1466902073889
NA 2016 Summer Split regular_season P1-vs-NV NV|P1|G1|869388af33e14bb1b5a78 8a4da304-ec28-4f9a-8f4a-f195d44aa801 P1 NV NV P1 1469847524704
NA 2016 Summer Split regular_season P1-vs-NV NV|P1|G2|869388af33e14bb1b5a78 4d4b7a56-2854-4506-a7c5-2dee01219c57 NV P1 P1 NV 1469849626719
NA 2016 Summer Split regular_season P1-vs-NV NV|P1|G3|869388af33e14bb1b5a78 4e0e1093-5e07-4376-869d-ebc9c293e6f2 P1 NV P1 NV 1469849630742
NA 2016 Summer Split regular_season TSM-vs-P1 P1|TSM|G1|f019f46e2e194e099c07 1596b2a9-0876-4216-8569-7922ed907237 TSM P1 TSM P1 1469318234799
NA 2016 Summer Split regular_season TSM-vs-P1 P1|TSM|G2|f019f46e2e194e099c07 21bc66bc-eb3a-4d39-9999-7f668476cfdc P1 TSM P1 TSM 1469321659583
NA 2016 Summer Split regular_season TSM-vs-P1 P1|TSM|G3|f019f46e2e194e099c07 f393a06c-c0dd-48e2-aa2d-abaecae7646c TSM P1 P1 TSM 1469326992519
NA 2016 Summer Split regular_season NV-vs-APX APX|NV|G1|f529bff8371e46dcad92 b5ba9f59-a070-4c47-8ec1-389c297b7039 NV APX APX NV 1468797511863
NA 2016 Summer Split regular_season NV-vs-APX APX|NV|G2|f529bff8371e46dcad92 2d5d2899-6763-46df-b124-0a5c37315cfc APX NV NV APX 1468799154763
NA 2016 Summer Split regular_season NV-vs-APX APX|NV|G3|f529bff8371e46dcad92 2120424e-9d44-4795-9c31-d2600e049e43 NV APX NV APX 1468803819771
NA 2016 Summer Split regular_season FOX-vs-C9 C9|FOX|G1|65134d3b983448899f5c 5e3f98f1-a328-4280-9eea-e919106825b1 FOX C9 FOX C9 1465177457987
NA 2016 Summer Split regular_season FOX-vs-C9 C9|FOX|G2|65134d3b983448899f5c 4d83ddab-77da-451a-b7c2-112d21a69eea C9 FOX C9 FOX 1465177710779
NA 2016 Summer Split regular_season FOX-vs-C9 C9|FOX|G3|65134d3b983448899f5c 15063fbd-b94f-4fc4-9332-c94045840ada FOX C9 C9 FOX 1465181515014
NA 2016 Summer Split regular_season APX-vs-NV APX|NV|G1|8506e37ffb9741578b40 3362774d-cbf0-441d-b0ff-16a79be34636 APX NV NV APX 1465624851367
NA 2016 Summer Split regular_season APX-vs-NV APX|NV|G2|8506e37ffb9741578b40 6d4f9160-5d06-4ce2-a6dd-0085d51dfe69 NV APX APX NV 1465626459746
NA 2016 Summer Split regular_season APX-vs-NV APX|NV|G3|8506e37ffb9741578b40 cee115b5-87d2-4b4c-a33b-e3dcc75a8b95 APX NV NV APX 1465629778429
NA 2016 Summer Split regular_season APX-vs-NRG APX|NRG|G1|6ff48a4d3d2844ba8b3 48c69f04-f87c-40b3-89b3-5572da9f1432 APX NRG APX NRG 1465087571731
NA 2016 Summer Split regular_season APX-vs-NRG APX|NRG|G2|6ff48a4d3d2844ba8b3 c8b3423f-f513-49e9-8b14-ba0923360113 NRG APX APX NRG 1465092325777
NA 2016 Summer Split regular_season TL-vs-TSM TL|TSM|G1|2b5b4a4a5e574891a6af 161b8664-4a3a-4b38-9376-e4a82595dfcd TL TSM TSM TL 1468799130677
NA 2016 Summer Split regular_season TL-vs-TSM TL|TSM|G2|2b5b4a4a5e574891a6af 84605cf9-50e5-4935-a95c-1180d31d4b45 TSM TL TSM TL 1468803992400
NA 2016 Summer Split regular_season TL-vs-NRG NRG|TL|G1|84d17c3dd4a4480aac25 5ffde0b1-9130-40c7-b994-7f031ff05e51 TL NRG TL NRG 1466295836433
NA 2016 Summer Split regular_season TL-vs-NRG NRG|TL|G2|84d17c3dd4a4480aac25 da3dab5e-292b-4839-8a1a-75904c691a7a NRG TL NRG TL 1466299426943
NA 2016 Summer Split regular_season TL-vs-NRG NRG|TL|G3|84d17c3dd4a4480aac25 6c372027-260a-4b7d-9144-a253b00d67f9 TL NRG TL NRG 1466301342285
NA 2016 Summer Split regular_season NV-vs-FOX FOX|NV|G1|a7ac2f0010d34bf0bc45 0d287773-a22d-4243-a80f-97782a0352e4 NV FOX NV FOX 1470011468927
NA 2016 Summer Split regular_season NV-vs-FOX FOX|NV|G2|a7ac2f0010d34bf0bc45 760d0004-c0cd-4fa1-8153-0f8f1b7fbe44 FOX NV NV FOX 1470015331543
NA 2016 Summer Split regular_season TSM-vs-FOX FOX|TSM|G1|4ea7b6cf88b34a45a03 7cda15bf-fd83-441c-b1a0-0fbeb99a0e4d TSM FOX FOX TSM 1466892203718
NA 2016 Summer Split regular_season TSM-vs-FOX FOX|TSM|G2|4ea7b6cf88b34a45a03 3e2b3503-775b-442d-964d-aac34e9a4f61 FOX TSM TSM FOX 1466893806244
NA 2016 Summer Split regular_season TSM-vs-FOX FOX|TSM|G3|4ea7b6cf88b34a45a03 6bf7d54c-699d-4f88-8394-06f105e1b24d TSM FOX TSM FOX 1466896952519
NA 2016 Summer Split regular_season TL-vs-CLG CLG|TL|G1|f7cda0963fff4433aecd 2b1f5382-2486-4f14-8294-a5ce8d55895d TL CLG TL CLG 1465682150535
NA 2016 Summer Split regular_season TL-vs-CLG CLG|TL|G2|f7cda0963fff4433aecd 055dc289-aad3-430a-8498-7a88f12495fe CLG TL CLG TL 1465682165019
NA 2016 Summer Split regular_season TL-vs-CLG CLG|TL|G3|f7cda0963fff4433aecd 9000b8a1-843d-40d1-b24c-b87ea2ca429e TL CLG CLG TL 1465686468473
NA 2016 Summer Split regular_season FOX-vs-NRG FOX|NRG|G1|15e443dfd97048fca6d eba6dea3-a03d-4537-b192-6883cd849da4 FOX NRG NRG FOX 1467583082886
NA 2016 Summer Split regular_season FOX-vs-NRG FOX|NRG|G2|15e443dfd97048fca6d 1931941a-658c-4526-b897-80f5ddec2605 NRG FOX NRG FOX 1467586120012
NA 2016 Summer Split regular_season FOX-vs-TSM FOX|TSM|G1|b584e264d1bf40628e8 556d1023-9a27-43b8-8664-1b021bfc7921 FOX TSM TSM FOX 1468707578272
NA 2016 Summer Split regular_season FOX-vs-TSM FOX|TSM|G2|b584e264d1bf40628e8 71142b7b-c7f8-45da-837f-fbf77cd8463e TSM FOX TSM FOX 1468707859595
NA 2016 Summer Split regular_season NRG-vs-CLG CLG|NRG|G1|c8bd38c23d91497e99d 9dbfa609-9cc7-4774-9927-fac6bc373a1e NRG CLG CLG NRG 1467496369466
NA 2016 Summer Split regular_season NRG-vs-CLG CLG|NRG|G2|c8bd38c23d91497e99d 41fd278c-1923-41fb-8e17-a6175775da74 CLG NRG CLG NRG 1467496395115
NA 2016 Summer Split regular_season NV-vs-IMT IMT|NV|G1|692c98d97abd4583ab46 f9f9c055-0a78-40b6-b5f6-300fc618f818 NV IMT IMT NV 1468039435893
NA 2016 Summer Split regular_season NV-vs-IMT IMT|NV|G2|692c98d97abd4583ab46 929496cc-91c1-4543-80b6-da265feb5483 IMT NV IMT NV 1468042214491
NA 2016 Summer Split regular_season FOX-vs-IMT FOX|IMT|G1|b74722ffd96a4168acc 85d89cf2-ebbd-48ce-b3c9-c37b2181be5a FOX IMT IMT FOX 1466377767331
NA 2016 Summer Split regular_season FOX-vs-IMT FOX|IMT|G2|b74722ffd96a4168acc 9c5e3351-3e2b-4dcf-82f7-db1a45540c68 IMT FOX IMT FOX 1466387051198
NA 2016 Summer Split regular_season TSM-vs-APX APX|TSM|G1|f8e1e01587bf415eb8a 00f46dc1-a365-473e-bcbe-159ef237eb47 TSM APX TSM APX 1465691227605
NA 2016 Summer Split regular_season TSM-vs-APX APX|TSM|G2|f8e1e01587bf415eb8a 3487620d-7bb8-4734-8daf-c3954e293f64 APX TSM TSM APX 1465695058676
NA 2016 Summer Split regular_season FOX-vs-P1 FOX|P1|G1|a6ac9ba99b504657bd8c e31185fa-391a-48d3-a823-aa56e6b1a49f FOX P1 FOX P1 1465081087838
NA 2016 Summer Split regular_season FOX-vs-P1 FOX|P1|G2|a6ac9ba99b504657bd8c 0356066f-1b66-4b72-b501-88c962fabed8 P1 FOX FOX P1 1465083036650
NA 2016 Summer Split regular_season TSM-vs-TL TL|TSM|G1|a1216fafca8347a5ad2b b966fb1f-c246-414a-ae2e-8b88bcf81c1d TSM TL TSM TL 1465162481186
NA 2016 Summer Split regular_season TSM-vs-TL TL|TSM|G2|a1216fafca8347a5ad2b 638dab01-dd00-41af-b341-04b9381d9d14 TL TSM TSM TL 1465165279132
NA 2016 Summer Split regular_season NRG-vs-IMT IMT|NRG|G1|8ad5a66c96874be6ac1 a82051ba-91a8-43a1-9b32-15597cb904cc NRG IMT NRG IMT 1465615144728
NA 2016 Summer Split regular_season NRG-vs-IMT IMT|NRG|G2|8ad5a66c96874be6ac1 8e62ddd8-cb76-4684-b677-ec4b66ebb883 IMT NRG IMT NRG 1465614551097
NA 2016 Summer Split regular_season NRG-vs-IMT IMT|NRG|G3|8ad5a66c96874be6ac1 a64f709b-32c2-45f8-88b7-4c9e82a40a2a NRG IMT IMT NRG 1465618738704
NA 2016 Summer Split regular_season P1-vs-TL P1|TL|G1|bdb55f1b7cbb42009b9c2 80bc5107-dd8b-4bec-a184-6c4b8dab752d P1 TL TL P1 1468710843727
NA 2016 Summer Split regular_season P1-vs-TL P1|TL|G2|bdb55f1b7cbb42009b9c2 6ccc18f2-c5d3-4eab-9658-7e4cbc7abd19 TL P1 TL P1 1468719367780
NA 2016 Summer Split regular_season NRG-vs-C9 C9|NRG|G1|e3052ff3f000402caf40 899fff61-9672-4f28-b1a4-40a4728d63d0 NRG C9 C9 NRG 1468186943751
NA 2016 Summer Split regular_season NRG-vs-C9 C9|NRG|G2|e3052ff3f000402caf40 c3c16afd-ad81-47fd-84e6-54112e6f6ed3 C9 NRG C9 NRG 1468701149065
NA 2016 Summer Split regular_season NRG-vs-TL NRG|TL|G1|4dc4efa40dc64320b126 ea163091-0334-49e7-954d-84fb83ba4036 NRG TL TL NRG 1469395961850
NA 2016 Summer Split regular_season NRG-vs-TL NRG|TL|G2|4dc4efa40dc64320b126 2e550e43-d324-4a7a-89b4-9b115a780340 TL NRG TL NRG 1469397734525
NA 2016 Summer Split regular_season C9-vs-P1 C9|P1|G1|51c4e895932e477db9ca3 f97d88e4-638c-4713-8600-5deebc1684de C9 P1 C9 P1 1469402143347
NA 2016 Summer Split regular_season C9-vs-P1 C9|P1|G2|51c4e895932e477db9ca3 d8a081c5-3ee2-4393-8bf0-2808e5bad03f P1 C9 C9 P1 1469406582060
NA 2016 Summer Split regular_season APX-vs-TL APX|TL|G1|f737186945ff4e47bc81 49b62592-e8d7-4ad4-97df-480065d4007d APX TL APX TL 1469915717375
NA 2016 Summer Split regular_season APX-vs-TL APX|TL|G2|f737186945ff4e47bc81 0fa4bbb6-c0f1-47f6-8b09-d5e86dfbd934 TL APX TL APX 1469916965282
NA 2016 Summer Split regular_season APX-vs-TL APX|TL|G3|f737186945ff4e47bc81 67f99875-b413-4a6e-9aab-db745fbf3f9f APX TL APX TL 1469920796627
NA 2016 Summer Split regular_season NV-vs-CLG CLG|NV|G1|848dd1555dad4210a449 431a06f2-7f04-4ae1-8e1a-0f8818fe353b NV CLG CLG NV 1468111002427
NA 2016 Summer Split regular_season NV-vs-CLG CLG|NV|G2|848dd1555dad4210a449 833f514e-9627-4df0-864a-08bdcdefb9d1 CLG NV CLG NV 1468120691929
NA 2016 Summer Split regular_season CLG-vs-FOX CLG|FOX|G1|17528151decf4bc886e a3b525d5-6a57-43ae-81f1-bcc1bf41dd83 CLG FOX CLG FOX 1466286468010
NA 2016 Summer Split regular_season CLG-vs-FOX CLG|FOX|G2|17528151decf4bc886e 161809c1-fbca-40e5-93ea-af147f348530 FOX CLG CLG FOX 1466289934785
NA 2016 Summer Split regular_season IMT-vs-FOX FOX|IMT|G1|bf0123be729043128fb c1a2d930-3a1f-41c9-a9f3-eda96e86bf75 IMT FOX IMT FOX 1468791048976
NA 2016 Summer Split regular_season IMT-vs-FOX FOX|IMT|G2|bf0123be729043128fb 90498e49-6d94-40c4-95eb-6f6c847e2bbd FOX IMT IMT FOX 1468793107911
NA 2016 Summer Split regular_season P1-vs-C9 C9|P1|G1|39ac612671534b61baa28 fb1877ea-3d5a-41d1-8f4b-bc0d082c6c15 P1 C9 C9 P1 1465690986151
NA 2016 Summer Split regular_season P1-vs-C9 C9|P1|G2|39ac612671534b61baa28 ba7eba62-9b0e-4fb3-963e-498b5d1b6711 C9 P1 P1 C9 1465698813304
NA 2016 Summer Split regular_season P1-vs-C9 C9|P1|G3|39ac612671534b61baa28 8233f036-6214-417c-95a5-5e8f6f1bd74e P1 C9 C9 P1 1465700263054
NA 2016 Summer Split regular_season NV-vs-TL NV|TL|G1|a117be1ccd364b3ea6cf6 ae0baafa-fd39-430c-9115-d7b29753e9ae NV TL NV TL 1465089953344
NA 2016 Summer Split regular_season NV-vs-TL NV|TL|G2|a117be1ccd364b3ea6cf6 b372838c-2b74-4c23-b3cc-e8010c99383a TL NV NV TL 1465092701976
NA 2016 Summer Split regular_season APX-vs-TSM APX|TSM|G1|7d329c46c28c40c8b97 619a2a7c-8f6b-4d68-b408-f3ecd6dc517d APX TSM TSM APX 1468186666426
NA 2016 Summer Split regular_season APX-vs-TSM APX|TSM|G2|7d329c46c28c40c8b97 0fafe79c-de2d-4b44-9d3b-15685e120ce7 TSM APX TSM APX 1468191017625
NA 2016 Summer Split regular_season TL-vs-C9 C9|TL|G1|979342e56a264891b1605 f7d00c31-f730-4d36-b9a2-ac56e60c2563 TL C9 C9 TL 1470009031278
NA 2016 Summer Split regular_season TL-vs-C9 C9|TL|G2|979342e56a264891b1605 dc9f7d0c-e876-40ac-aadf-d602ef5b408e C9 TL C9 TL 1470012421689
NA 2016 Summer Split regular_season CLG-vs-NV CLG|NV|G1|9b095b8c824c4662a6cb eb9a98f8-7ebc-4563-80e1-ec612e419fe5 CLG NV CLG NV 1466386751486
NA 2016 Summer Split regular_season CLG-vs-NV CLG|NV|G2|9b095b8c824c4662a6cb d7613718-fa12-4d36-9ca0-36a084db3d88 NV CLG NV CLG 1466387774992
NA 2016 Summer Split regular_season CLG-vs-NV CLG|NV|G3|9b095b8c824c4662a6cb 026a6062-f7a3-4290-8a57-d42003e49114 CLG NV NV CLG 1466395293355
NA 2016 Summer Split regular_season CLG-vs-TSM CLG|TSM|G1|313400098b204f73861 5c8435f8-ce2f-4186-a9af-d51f38bea5a6 CLG TSM TSM CLG 1467581018201
NA 2016 Summer Split regular_season CLG-vs-TSM CLG|TSM|G2|313400098b204f73861 a1f1a5dd-bbc9-4c33-8328-e0af627e88cc TSM CLG TSM CLG 1467584880955
NA 2016 Summer Split regular_season FOX-vs-APX APX|FOX|G1|fc02ffc4d3ef4b3c8fa 2a61ff92-4d2f-40dc-b432-6d3fb7c1a589 FOX APX FOX APX 1469246595244
NA 2016 Summer Split regular_season FOX-vs-APX APX|FOX|G2|fc02ffc4d3ef4b3c8fa ee74d2de-656d-41f5-ac23-1dd3a91c5f94 APX FOX APX FOX 1469244392059
NA 2016 Summer Split regular_season FOX-vs-APX APX|FOX|G3|fc02ffc4d3ef4b3c8fa 3e292246-40eb-4eaf-8a12-d1348c7f2a3d FOX APX APX FOX 1469251641342
NA 2016 Summer Split regular_season NV-vs-P1 NV|P1|G1|d27d2387be314fa39108a d57756ce-7ce7-4a19-8ea4-bcc682140abf NV P1 NV P1 1465769037280
NA 2016 Summer Split regular_season NV-vs-P1 NV|P1|G2|d27d2387be314fa39108a ef7ea0fa-6c91-4eec-86e6-f67315599b9b P1 NV NV P1 1465771583024
NA 2016 Summer Split regular_season CLG-vs-TL CLG|TL|G1|322e1a5defae497a96ad c9ee9a4d-fa37-497d-baed-0e2a92752666 CLG TL TL CLG 1469309405069
NA 2016 Summer Split regular_season CLG-vs-TL CLG|TL|G2|322e1a5defae497a96ad a025f0b9-8119-4c60-95d1-e2b301761c1e TL CLG CLG TL 1469312056568
NA 2016 Summer Split regular_season CLG-vs-TL CLG|TL|G3|322e1a5defae497a96ad d55661a0-b4a8-4f1f-9e40-442a89d78939 CLG TL CLG TL 1469316709179
NA 2016 Summer Split regular_season C9-vs-TSM C9|TSM|G1|ad45d32125ed404699c8 993bdf17-3ea5-4f0f-8748-4ec4700bb652 C9 TSM TSM C9 1466218694660
NA 2016 Summer Split regular_season C9-vs-TSM C9|TSM|G2|ad45d32125ed404699c8 4cf99b6c-b0fc-45d7-8827-b0b8cc44cb65 TSM C9 C9 TSM 1466218707643
NA 2016 Summer Split regular_season C9-vs-TSM C9|TSM|G3|ad45d32125ed404699c8 7507ba9c-a830-42e2-9cac-dd75fc7512a3 C9 TSM TSM C9 1466224810702
NA 2016 Summer Split regular_season IMT-vs-NRG IMT|NRG|G1|00640eba828348a6bc6 ca77cf01-7788-4b01-bb51-139d5ac5264d IMT NRG IMT NRG 1469234246776
NA 2016 Summer Split regular_season IMT-vs-NRG IMT|NRG|G2|00640eba828348a6bc6 94b37a6c-fe4a-46a5-a3a0-82c09ca2019d NRG IMT IMT NRG 1469237704422
NA 2016 Summer Split regular_season TSM-vs-CLG CLG|TSM|G1|98e358ff2153453a92d 0045fb8f-0272-4a84-8500-240d69c33f7b TSM CLG TSM CLG 1465007552035
NA 2016 Summer Split regular_season TSM-vs-CLG CLG|TSM|G2|98e358ff2153453a92d 4d985748-066a-4ea1-9a16-db0612d08b10 CLG TSM TSM CLG 1465011081791
NA 2016 Summer Split regular_season NRG-vs-FOX FOX|NRG|G1|014e85efcaf0452dbe5 fcc202c4-cd90-4b69-9ce5-10a905e5c83a NRG FOX NRG FOX 1465683207308
NA 2016 Summer Split regular_season NRG-vs-FOX FOX|NRG|G2|014e85efcaf0452dbe5 07844bbe-3ca9-4bfe-8fd8-7442f2310597 FOX NRG NRG FOX 1465686435286
NA 2016 Summer Split regular_season P1-vs-APX APX|P1|G1|ffe80e3c186a49b7a193 dc3e5103-189c-44c0-b207-5c99f535622d P1 APX APX P1 1466295414441
NA 2016 Summer Split regular_season P1-vs-APX APX|P1|G2|ffe80e3c186a49b7a193 8a9fefc1-acd6-49a5-a40b-2e118ca6418a APX P1 P1 APX 1466295380282
NA 2016 Summer Split regular_season P1-vs-APX APX|P1|G3|ffe80e3c186a49b7a193 c8729257-dd40-4965-9539-199ba1e3e825 P1 APX APX P1 1466298609869
NA 2016 Summer Split regular_season NV-vs-C9 C9|NV|G1|1d7ea30aa43e41469ff02 6e61fa68-de77-4791-8124-096f3e4717b6 NV C9 C9 NV 1469309804874
NA 2016 Summer Split regular_season NV-vs-C9 C9|NV|G2|1d7ea30aa43e41469ff02 3f3a2c5b-6984-486c-999f-2a16dd6bb4bb C9 NV C9 NV 1469313128972
NA 2016 Summer Split regular_season CLG-vs-NRG CLG|NRG|G1|b045c1e79a874296a88 07f200e8-31b6-4579-baf8-e1bf1e41af1f CLG NRG CLG NRG 1469915700522
NA 2016 Summer Split regular_season CLG-vs-NRG CLG|NRG|G2|b045c1e79a874296a88 e4ce7010-ae01-420e-8512-73305b405d2c NRG CLG NRG CLG 1469917175690
NA 2016 Summer Split regular_season CLG-vs-NRG CLG|NRG|G3|b045c1e79a874296a88 50ce982f-263f-4f15-8dbf-457522c918fc CLG NRG CLG NRG 1469921043044
NA 2016 Summer Split regular_season CLG-vs-APX APX|CLG|G1|6311833405e54e02bd3 084c4b2f-d340-4b1a-a812-f55b6479dcc0 CLG APX CLG APX 1470001470076
NA 2016 Summer Split regular_season CLG-vs-APX APX|CLG|G2|6311833405e54e02bd3 74ba84a6-2b6b-4c20-b6f9-e27fa3358567 APX CLG APX CLG 1470004004450
NA 2016 Summer Split regular_season CLG-vs-APX APX|CLG|G3|6311833405e54e02bd3 b540ab36-a2d0-4127-8cb9-2f600c45f19a CLG APX APX CLG 1470008618995
NA 2016 Summer Split regular_season IMT-vs-P1 IMT|P1|G1|6932eaf5a2eb45838034 3535deb2-b976-416f-a75d-d481eafc63b9 IMT P1 IMT P1 1465167971491
NA 2016 Summer Split regular_season IMT-vs-P1 IMT|P1|G2|6932eaf5a2eb45838034 155fdbc9-b288-4211-89ff-a4e906a2c1ea P1 IMT IMT P1 1465176148600
NA 2016 Summer Split regular_season C9-vs-FOX C9|FOX|G1|f7cc41e87f714db2a130 daafcc63-a9bc-4329-b763-40d6d3ce1c04 C9 FOX C9 FOX 1469924828691
NA 2016 Summer Split regular_season C9-vs-FOX C9|FOX|G2|f7cc41e87f714db2a130 d05d2787-3519-4418-8e25-d0f63c9986fe FOX C9 C9 FOX 1469928596503
NA 2016 Summer Split regular_season P1-vs-NRG NRG|P1|G1|f86a630c8a56427ebe8e 85ac3687-517b-40ce-bb99-ead8ce55a81a P1 NRG P1 NRG 1468644310272
NA 2016 Summer Split regular_season P1-vs-NRG NRG|P1|G2|f86a630c8a56427ebe8e f7731e13-5dae-4fb7-bd44-adc480c2c642 NRG P1 NRG P1 1468644422067
NA 2016 Summer Split regular_season P1-vs-NRG NRG|P1|G3|f86a630c8a56427ebe8e e679fb54-8f62-4bbf-8498-8fe547af046c P1 NRG P1 NRG 1468687196818
NA 2016 Summer Split regular_season P1-vs-CLG CLG|P1|G1|63e106bca76646aca2e2 d7dc01e7-8fb1-4e62-99aa-7c2265982bf2 P1 CLG CLG P1 1466981535791
NA 2016 Summer Split regular_season P1-vs-CLG CLG|P1|G2|63e106bca76646aca2e2 67498508-c3cd-419f-a24c-9ced80672de5 CLG P1 CLG P1 1466988449234
NA 2016 Summer Split regular_season TL-vs-IMT IMT|TL|G1|d577ff707c7346198796 e24f436c-b3c8-48db-8e25-1b0875922b90 TL IMT IMT TL 1468108854009
NA 2016 Summer Split regular_season TL-vs-IMT IMT|TL|G2|d577ff707c7346198796 da8eaa1b-bd72-484f-8e90-5e7e44b3675b IMT TL TL IMT 1468120731471
NA 2016 Summer Split regular_season TL-vs-IMT IMT|TL|G3|d577ff707c7346198796 9f33d9ca-904e-49e2-94ed-2179ea2eb6ef TL IMT IMT TL 1468109402901
NA 2016 Summer Split regular_season TSM-vs-IMT IMT|TSM|G1|81790d648c4647e0bfb 36d6c836-08d6-4817-a0ce-c330dd345e15 TSM IMT TSM IMT 1465765970435
NA 2016 Summer Split regular_season TSM-vs-IMT IMT|TSM|G2|81790d648c4647e0bfb 8da946d5-4f9c-49d7-90c7-dab8633170ab IMT TSM IMT TSM 1465767715128
NA 2016 Summer Split regular_season TSM-vs-IMT IMT|TSM|G3|81790d648c4647e0bfb 49792061-e2f6-4cbe-9604-600b8e44935a TSM IMT TSM IMT 1465773860080
NA 2016 Summer Split regular_season CLG-vs-IMT CLG|IMT|G1|0b4e8ff23afa4c98b49 155e8032-a724-4796-9682-e44a5b81cc61 CLG IMT CLG IMT 1466824123732
NA 2016 Summer Split regular_season CLG-vs-IMT CLG|IMT|G2|0b4e8ff23afa4c98b49 d002fa8c-818a-4fa2-bc96-2f9f136011b8 IMT CLG IMT CLG 1466830444185
NA 2016 Summer Split regular_season CLG-vs-IMT CLG|IMT|G3|0b4e8ff23afa4c98b49 e5883dad-e9af-45b2-b12f-05899cba4ba5 CLG IMT IMT CLG 1466830755853
NA 2016 Summer Split regular_season P1-vs-TSM P1|TSM|G1|0add2d3a349a4c1eb59a 48e75281-8a49-45be-8e32-79ec26be8d18 P1 TSM TSM P1 1467496666936
NA 2016 Summer Split regular_season P1-vs-TSM P1|TSM|G2|0add2d3a349a4c1eb59a f6f767c6-7571-4182-a57d-4d9b76139ef0 TSM P1 TSM P1 1467496774842
NA 2016 Summer Split regular_season TL-vs-NV NV|TL|G1|fc590ff6736b44feb08ea 36f16155-d68f-46a3-b5a5-2b481c81b1c0 TL NV TL NV 1467501684206
NA 2016 Summer Split regular_season TL-vs-NV NV|TL|G2|fc590ff6736b44feb08ea defbc078-4e70-4b79-8f43-a89e2b2d724c NV TL TL NV 1467535432335
NA 2016 Summer Split regular_season CLG-vs-C9 C9|CLG|G1|4506297f8424498ba21a 6f0436f2-5ce1-4215-bfce-150784f52f59 CLG C9 C9 CLG 1465773872019
NA 2016 Summer Split regular_season CLG-vs-C9 C9|CLG|G2|4506297f8424498ba21a 57e37ca3-5a97-47e3-b693-2367532c4254 C9 CLG C9 CLG 1465778770425
NA 2016 Summer Split regular_season CLG-vs-P1 CLG|P1|G1|9dcd0cbffbf74b3e8ca2 715218f9-a4d9-40c6-b440-bccc22615381 CLG P1 P1 CLG 1468192444996
NA 2016 Summer Split regular_season CLG-vs-P1 CLG|P1|G2|9dcd0cbffbf74b3e8ca2 29445fc9-ebc4-47a0-856d-1e9aa78fcfed P1 CLG CLG P1 1468194529643
NA 2016 Summer Split regular_season CLG-vs-P1 CLG|P1|G3|9dcd0cbffbf74b3e8ca2 2c5ea8a7-c1ac-4b16-8090-b64187c57fc7 CLG P1 CLG P1 1468193188439
NA 2016 Summer Split regular_season TL-vs-APX APX|TL|G1|3474b27947e2418fa9fe 415daa39-8e2f-4b84-ab63-0d723ae1a7bb TL APX TL APX 1466833029564
NA 2016 Summer Split regular_season TL-vs-APX APX|TL|G2|3474b27947e2418fa9fe 80ce1904-3ddc-43e1-821c-b86e1b811726 APX TL TL APX 1466836971067
NA 2016 Summer Split regular_season APX-vs-C9 APX|C9|G1|3af8f08f2ce1421898c6 9067b65f-d335-4ccc-a020-c04c1aa52bbd APX C9 C9 APX 1466373692863
NA 2016 Summer Split regular_season APX-vs-C9 APX|C9|G2|3af8f08f2ce1421898c6 5b5e5f8c-d185-45f3-aaaa-fa9b5a5adbec C9 APX APX C9 1466377733520
NA 2016 Summer Split regular_season APX-vs-C9 APX|C9|G3|3af8f08f2ce1421898c6 304ba43a-76ea-46e3-8fd3-3a49e1e15756 APX C9 C9 APX 1466386785815
NA 2016 Summer Split regular_season APX-vs-FOX APX|FOX|G1|9b80f2e9905e4798a32 6ef44612-0c2f-486b-9bf1-26898130e5a0 APX FOX APX FOX 1466983883418
NA 2016 Summer Split regular_season APX-vs-FOX APX|FOX|G2|9b80f2e9905e4798a32 27533f7d-bc06-4327-a481-dbdd7a07441a FOX APX APX FOX 1466989973193
NA 2016 Summer Split regular_season C9-vs-CLG C9|CLG|G1|be07f442bcde436fb802 9a9708e3-011f-4819-b421-1bc29ecac738 C9 CLG CLG C9 1468791036680
NA 2016 Summer Split regular_season C9-vs-CLG C9|CLG|G2|be07f442bcde436fb802 71325fb6-48db-4203-8ae2-025cba9b435d CLG C9 C9 CLG 1468793122122
NA 2016 Summer Split regular_season C9-vs-CLG C9|CLG|G3|be07f442bcde436fb802 37dce064-7ea1-46c5-98fd-297a399af9bd C9 CLG CLG C9 1468796504348
NA 2016 Summer Split regular_season C9-vs-IMT C9|IMT|G1|6a69a9a504664779bdc1 925d8443-8f5a-4b1b-8717-2a882b7e429c C9 IMT IMT C9 1465079687861
NA 2016 Summer Split regular_season C9-vs-IMT C9|IMT|G2|6a69a9a504664779bdc1 d96283e5-604d-4dac-8e9f-ec6e4ed20cd6 IMT C9 C9 IMT 1465082990327
NA 2016 Summer Split regular_season C9-vs-IMT C9|IMT|G3|6a69a9a504664779bdc1 187bd0f9-a197-49f2-ba6f-a7a8700967e0 C9 IMT IMT C9 1465084715941
NA 2016 Summer Split regular_season TSM-vs-NRG NRG|TSM|G1|beb1abd86ace4e18ab5 3c0bb4c0-dd15-4c38-bd8f-22aefe465925 TSM NRG TSM NRG 1470001694003
NA 2016 Summer Split regular_season TSM-vs-NRG NRG|TSM|G2|beb1abd86ace4e18ab5 0fccc219-42a8-4ff9-8797-f5bc59faab4b NRG TSM NRG TSM 1470004225872
NA 2016 Summer Split regular_season TSM-vs-NRG NRG|TSM|G3|beb1abd86ace4e18ab5 485d40d5-5f34-454f-8eba-bd3080e8bbed TSM NRG TSM NRG 1470004950141
NA 2016 Summer Split regular_season TL-vs-FOX FOX|TL|G1|61399e0217b64d069dfd 6b6e68c2-ba50-49be-ba53-5fb8b284c285 TL FOX TL FOX 1468191699588
NA 2016 Summer Split regular_season TL-vs-FOX FOX|TL|G2|61399e0217b64d069dfd 40e25e09-ae09-4377-b824-cb1fc1219424 FOX TL FOX TL 1468195566334
NA 2016 Summer Split regular_season TL-vs-FOX FOX|TL|G3|61399e0217b64d069dfd ef84a159-19cd-44fb-a9af-a93e863a8b00 TL FOX TL FOX 1468200925295
NA 2016 Summer Split regular_season TSM-vs-NV NV|TSM|G1|f295759f6a714c9ea37f 48a6bdca-e803-4cab-8731-8b4413365eb9 TSM NV TSM NV 1469396190296
NA 2016 Summer Split regular_season TSM-vs-NV NV|TSM|G2|f295759f6a714c9ea37f 95fc88c4-b39c-4c89-891c-b4481a9ad0c9 NV TSM TSM NV 1469397960795
NA 2016 Summer Split regular_season IMT-vs-C9 C9|IMT|G1|99e4d5b371ea4e748303 861e19b3-39ff-4bbe-9455-b341f6228382 IMT C9 IMT C9 1467590522254
NA 2016 Summer Split regular_season IMT-vs-C9 C9|IMT|G2|99e4d5b371ea4e748303 edb69ca7-5e2e-45e1-987b-e98cce47ed79 C9 IMT IMT C9 1467592264520
NA 2016 Summer Split regular_season FOX-vs-NV FOX|NV|G1|2f18122970704a3599ce 51e320d9-5053-47cb-bdf0-120ba69b666d FOX NV FOX NV 1467443226093
NA 2016 Summer Split regular_season FOX-vs-NV FOX|NV|G2|2f18122970704a3599ce f605ec9f-aa71-42e2-bf87-e3c7905728b1 NV FOX NV FOX 1467445346407
NA 2016 Summer Split regular_season FOX-vs-NV FOX|NV|G3|2f18122970704a3599ce eb099cd7-70b7-4564-84b7-1adfecd58bf2 FOX NV NV FOX 1467449549765
NA 2016 Summer Split regular_season NV-vs-NRG NRG|NV|G1|70ed07fa5fa74467a84d ae0255a4-ad36-4efd-a2ce-7e8b83560dab NV NRG NV NRG 1465016598690
NA 2016 Summer Split regular_season NV-vs-NRG NRG|NV|G2|70ed07fa5fa74467a84d 9f7b7ad2-7677-4931-b76e-8de149e1d29e NRG NV NRG NV 1465022410874
NA 2016 Summer Split regular_season NV-vs-NRG NRG|NV|G3|70ed07fa5fa74467a84d 5d61cb8b-3c3b-4b5c-a58d-246ab276b8e0 NV NRG NV NRG 1465025103716
NA 2016 Summer Split regular_season IMT-vs-CLG CLG|IMT|G1|72148c2940aa426e8da 9d1624e4-c0b3-4b5b-ba78-7c54cb1ec38c IMT CLG CLG IMT 1468643937115
NA 2016 Summer Split regular_season IMT-vs-CLG CLG|IMT|G2|72148c2940aa426e8da 8f58abbb-7a07-4828-80b1-b1f85f21485f CLG IMT IMT CLG 1468687397178
NA 2016 Summer Split regular_season IMT-vs-CLG CLG|IMT|G3|72148c2940aa426e8da 47fc5326-a210-4878-b652-3a508d6fa289 IMT CLG IMT CLG 1468644142069
NA 2016 Summer Split regular_season APX-vs-P1 APX|P1|G1|81d0713654444cc0b976 be35be80-6233-4b81-82ab-7261363c5869 APX P1 APX P1 1467589796752
NA 2016 Summer Split regular_season APX-vs-P1 APX|P1|G2|81d0713654444cc0b976 6ae2760b-63da-4963-876d-72632dd70c63 P1 APX P1 APX 1467593860853
NA 2016 Summer Split regular_season APX-vs-P1 APX|P1|G3|81d0713654444cc0b976 142cf486-fb68-4d04-b3d8-5629b188623f APX P1 P1 APX 1467596636941
NA 2016 Summer Split regular_season NRG-vs-NV NRG|NV|G1|a57fb3eb07134a0fae23 260a60eb-877d-4a1b-ba55-ffa1091f7df3 NRG NV NRG NV 1468704027519
NA 2016 Summer Split regular_season NRG-vs-NV NRG|NV|G2|a57fb3eb07134a0fae23 8bf750eb-88d7-47b6-b734-3784486c8175 NV NRG NRG NV 1468708594330
NA 2016 Summer Split na_2016_summer_promotion_relegation match-a FOX|TLA|G1|1f0cbc104e294a1e95d 0abcd7be-21b7-4068-8859-01207bca9cf5 FOX TLA TLA FOX 1470351349602
NA 2016 Summer Split na_2016_summer_promotion_relegation match-a FOX|TLA|G2|1f0cbc104e294a1e95d d6b5843b-3b01-4b15-b159-1f51e33f864c TLA FOX FOX TLA 1470353048315
NA 2016 Summer Split na_2016_summer_promotion_relegation match-a FOX|TLA|G3|1f0cbc104e294a1e95d a7fed1c8-41f5-46db-8c47-d04b948563d4 FOX TLA FOX TLA 1470355445709
NA 2016 Summer Split na_2016_summer_promotion_relegation match-a FOX|TLA|G4|1f0cbc104e294a1e95d a741cb47-647c-4c35-addc-7f440e20f3d6 FOX TLA TLA FOX 1470362497505
NA 2016 Summer Split na_2016_summer_promotion_relegation match-a FOX|TLA|G5|1f0cbc104e294a1e95d 68fe8c71-6fca-4394-bd75-5af4c5f71f40 FOX TLA FOX TLA 1470362615161
NA 2016 Summer Split na_2016_summer_promotion_relegation match-c C9C|NRG|G1|d10d52b0dd7e432c962 d2398fa9-b9fd-44b4-b59a-33a1a1ad3d69 NRG C9C C9C NRG 1470518168425
NA 2016 Summer Split na_2016_summer_promotion_relegation match-c C9C|NRG|G2|d10d52b0dd7e432c962 8d03fce6-2eb0-4e09-b770-34e8ab59b4e9 C9C NRG C9C NRG 1470520550461
NA 2016 Summer Split na_2016_summer_promotion_relegation match-c C9C|NRG|G3|d10d52b0dd7e432c962 afd9b7c6-3792-4c79-9703-3bce171d8d20 NRG C9C C9C NRG 1470525980972
NA 2016 Summer Split na_2016_summer_promotion_relegation match-d FOX|NRG|G1|66c397ee96c242d6a64 376858e1-2f0d-415d-a257-918781959f3d FOX NRG FOX NRG 1470605298799
NA 2016 Summer Split na_2016_summer_promotion_relegation match-d FOX|NRG|G2|66c397ee96c242d6a64 7b3f1a2c-04e2-4c50-b012-386e40ecc260 FOX NRG FOX NRG 1470608972805
NA 2016 Summer Split na_2016_summer_promotion_relegation match-d FOX|NRG|G3|66c397ee96c242d6a64 ae1b648b-3dc8-4c2f-97d6-af1cc156f62f NRG FOX FOX NRG 1471286236089
NA 2016 Summer Split na_2016_summer_promotion_relegation match-b FOX|P1|G1|9adf18382d934fa6acc0 6bbb6c2f-307d-4a57-a37a-01a4df7e9b6e FOX P1 P1 FOX 1470520529548
NA 2016 Summer Split na_2016_summer_promotion_relegation match-b FOX|P1|G2|9adf18382d934fa6acc0 5f2af244-15d6-4f16-821d-1b70f88473b7 FOX P1 P1 FOX 1470517824787
NA 2016 Summer Split na_2016_summer_promotion_relegation match-b FOX|P1|G3|9adf18382d934fa6acc0 dbdc8eb2-ab21-4879-ad35-c735425b6db7 FOX P1 P1 FOX 1470525991753
NA 2016 Spring Split na_2016_spring_playoffs grand-final CLG|TSM|G1|849dec4fe3ca476084d fcf8756d-4b1d-47bb-b1d7-395b04e3ee85 CLG TSM CLG TSM 1460925744041
NA 2016 Spring Split na_2016_spring_playoffs grand-final CLG|TSM|G2|849dec4fe3ca476084d 1e80c529-7f17-4cea-9e53-d2e18d533bf7 TSM CLG TSM CLG 1460928841106
NA 2016 Spring Split na_2016_spring_playoffs grand-final CLG|TSM|G3|849dec4fe3ca476084d 4077ffad-98c5-476a-87cc-8df243ccb8b4 CLG TSM CLG TSM 1460932658576
NA 2016 Spring Split na_2016_spring_playoffs grand-final CLG|TSM|G4|849dec4fe3ca476084d 42126708-e077-4fc7-984b-ca9eec36b5dc TSM CLG TSM CLG 1460936303150
NA 2016 Spring Split na_2016_spring_playoffs grand-final CLG|TSM|G5|849dec4fe3ca476084d c8a48826-2fd3-4fc9-87e0-d4074771ce72 CLG TSM CLG TSM 1460940542642
NA 2016 Spring Split na_2016_spring_playoffs semi-final-1 CLG|TL|G1|87224bd7b5154592b410 9bfc9b08-6d5f-421e-8c60-6593c807eeb1 CLG TL TL CLG 1460238526715
NA 2016 Spring Split na_2016_spring_playoffs semi-final-1 CLG|TL|G2|87224bd7b5154592b410 9df02495-be56-4504-a045-585870eb7eea TL CLG CLG TL 1460241881829
NA 2016 Spring Split na_2016_spring_playoffs semi-final-1 CLG|TL|G3|87224bd7b5154592b410 1ce07a38-6ab8-4562-9aa9-a02fd0674e48 CLG TL CLG TL 1460245003339
NA 2016 Spring Split na_2016_spring_playoffs semi-final-1 CLG|TL|G4|87224bd7b5154592b410 c0f0a855-0ede-467c-9928-711d9437f50d TL CLG TL CLG 1460247838135
NA 2016 Spring Split na_2016_spring_playoffs semi-final-1 CLG|TL|G5|87224bd7b5154592b410 9e3fdb9f-a5ca-4d4f-ab12-420347584660 CLG TL CLG TL 1460251740836
NA 2016 Spring Split na_2016_spring_playoffs quarter-final-2 C9|TSM|G1|f37596bc1647448187eb ceb3a744-21eb-4fdf-a6db-4ce0f4a600a0 C9 TSM C9 TSM 1459627328758
NA 2016 Spring Split na_2016_spring_playoffs quarter-final-2 C9|TSM|G2|f37596bc1647448187eb a2f19b67-8bd6-46ba-80a8-e99c03d9e159 TSM C9 TSM C9 1459630694001
NA 2016 Spring Split na_2016_spring_playoffs quarter-final-2 C9|TSM|G3|f37596bc1647448187eb 0f71b76b-e0c2-4213-b565-5ba779489b97 C9 TSM TSM C9 1459633956943
NA 2016 Spring Split na_2016_spring_playoffs quarter-final-2 C9|TSM|G4|f37596bc1647448187eb 8c0c6ad4-41e9-4b87-953e-a6109abd63f5 TSM C9 TSM C9 1459637108431
NA 2016 Spring Split na_2016_spring_playoffs semi-final-2 IMT|TSM|G1|5e9af7b0fff94aa9a3a 21a87386-1012-46b4-bca0-497bce1f4fc9 IMT TSM TSM IMT 1460319581208
NA 2016 Spring Split na_2016_spring_playoffs semi-final-2 IMT|TSM|G2|5e9af7b0fff94aa9a3a 32f5859d-0bbf-4d57-80b6-d6d855043573 TSM IMT TSM IMT 1460322866522
NA 2016 Spring Split na_2016_spring_playoffs semi-final-2 IMT|TSM|G3|5e9af7b0fff94aa9a3a 515e4aa7-0963-47fe-9167-2b522f7aa15a IMT TSM TSM IMT 1460327043466
NA 2016 Spring Split na_2016_spring_playoffs quarter-final-1 NRG|TL|G1|505de0841aba41128239 bb0f5c88-b524-49fd-ab8e-42252c0b624c TL NRG TL NRG 1459713253144
NA 2016 Spring Split na_2016_spring_playoffs quarter-final-1 NRG|TL|G2|505de0841aba41128239 585ab9db-3bfe-4808-9de4-e24d04fc608c NRG TL TL NRG 1459716396354
NA 2016 Spring Split na_2016_spring_playoffs quarter-final-1 NRG|TL|G3|505de0841aba41128239 c5490e06-46fd-451f-a638-3be8d9a3b4ad TL NRG TL NRG 1459719856994
NA 2016 Spring Split na_2016_spring_playoffs third-place IMT|TL|G1|16ef4750d7b6410eb16f 3b5c845b-a95b-48e4-b14d-d126e7d9d0b4 IMT TL IMT TL 1460839902623
NA 2016 Spring Split na_2016_spring_playoffs third-place IMT|TL|G2|16ef4750d7b6410eb16f 427d19b7-8d11-4341-9838-3758db49c5bf TL IMT IMT TL 1460842868781
NA 2016 Spring Split na_2016_spring_playoffs third-place IMT|TL|G3|16ef4750d7b6410eb16f 8d136066-8018-4fe3-87c7-1cfbf8b746bf IMT TL IMT TL 1460846039702
NA 2016 Spring Split na_2016_spring_promotion_relegation match-d APX|TDK|G1|2573ea0ab2774a85b7b f7bcb143-d7c4-4e30-8305-896e815abc39 APX TDK APX TDK 1460145944487
NA 2016 Spring Split na_2016_spring_promotion_relegation match-d APX|TDK|G2|2573ea0ab2774a85b7b 00c63f1d-ca9b-41c3-8eb4-5aa827e130b6 APX TDK APX TDK 1460148903795
NA 2016 Spring Split na_2016_spring_promotion_relegation match-d APX|TDK|G3|2573ea0ab2774a85b7b 76eed561-ed51-47d9-9692-dd4a3b2bab9d APX TDK APX TDK 1460151870430
NA 2016 Spring Split na_2016_spring_promotion_relegation match-a DIG|TDK|G1|361d0f49262148bdadd f504b5a4-3ee2-4140-b951-c35beadcf8ba TDK DIG TDK DIG 1459990775589
NA 2016 Spring Split na_2016_spring_promotion_relegation match-a DIG|TDK|G2|361d0f49262148bdadd badddc5f-a071-4a7e-bf43-f46cfc68f61f DIG TDK TDK DIG 1459994115438
NA 2016 Spring Split na_2016_spring_promotion_relegation match-a DIG|TDK|G3|361d0f49262148bdadd 15828482-5cfa-49a3-a54a-aec9e24c9982 TDK DIG TDK DIG 1459997370279
NA 2016 Spring Split na_2016_spring_promotion_relegation match-b REN|TDK|G1|c86a55b38ea8431f8b6 85fce6dc-9a6e-4a18-a68f-736ccd6a9d60 REN TDK REN TDK 1460058143364
NA 2016 Spring Split na_2016_spring_promotion_relegation match-b REN|TDK|G2|c86a55b38ea8431f8b6 80f61f8d-179b-4ab2-859d-0640ef6d2328 REN TDK REN TDK 1460061477258
NA 2016 Spring Split na_2016_spring_promotion_relegation match-b REN|TDK|G3|c86a55b38ea8431f8b6 49b0358e-5e2d-4cd9-826e-4b5e5b81001f TDK REN REN TDK 1460064655822
NA 2016 Spring Split na_2016_spring_promotion_relegation match-c APX|TIP|G1|cef5eb767dbe4334a86 9e2dda6b-33bf-447d-a733-56c8e2b80db8 APX TIP TIP APX 1460068874812
NA 2016 Spring Split na_2016_spring_promotion_relegation match-c APX|TIP|G2|cef5eb767dbe4334a86 8c1c19c0-7ee4-4e94-84ac-e0edc185b47c TIP APX TIP APX 1460071635505
NA 2016 Spring Split na_2016_spring_promotion_relegation match-c APX|TIP|G3|cef5eb767dbe4334a86 7eec7785-cc1b-4bb6-8029-51f47c8f05ce APX TIP APX TIP 1460075159191
NA 2016 Spring Split na_2016_spring_promotion_relegation match-c APX|TIP|G4|cef5eb767dbe4334a86 5d539a2c-8790-4e1c-a2fc-cfe6f25a13fe TIP APX TIP APX 1460078165829
NA 2016 Spring Split regular_season TIP-vs-TSM TIP|TSM|G1|f268f5f5fec94f318ff 4637be1e-0a4b-4682-8c8a-d39756eba0a6 TIP TSM TSM TIP 1455407456151
NA 2016 Spring Split regular_season FOX-vs-TL FOX|TL|G1|7810f3dbc4de4926ae0b 6847cd6e-aecd-4ed4-918d-92cb1eb913b0 FOX TL TL FOX 1453680327487
NA 2016 Spring Split regular_season CLG-vs-TIP CLG|TIP|G1|fa9b79d82ba04eed998 9a580730-23e5-4008-81f7-0b48def6ef71 CLG TIP CLG TIP 1456012806780
NA 2016 Spring Split regular_season IMT-vs-REN IMT|REN|G1|5ca3c26d2af342c1816 2132a184-542d-4335-a16f-f9a2a01b0177 IMT REN IMT REN 1454201149954
NA 2016 Spring Split regular_season REN-vs-TIP REN|TIP|G1|00f8ae5f408b4229b75 8dc8e823-d258-4e0c-9a04-5a1e2bd4294b REN TIP TIP REN 1453684456931
NA 2016 Spring Split regular_season TSM-vs-DIG DIG|TSM|G1|d6272882d1df4dffb15 58fb72f3-d60b-40f7-b965-6e4870ff3bef TSM DIG TSM DIG 1453668562115
NA 2016 Spring Split regular_season CLG-vs-TSM CLG|TSM|G1|93cbe3ea0b4f42a7b09 6d719700-815c-4a8c-949d-9e610180b6ae CLG TSM TSM CLG 1455486920784
NA 2016 Spring Split regular_season TL-vs-REN REN|TL|G1|f65f5674fd2e4bb8b4d2 56e465ed-b0d2-4b04-9fd8-8576489e1452 TL REN TL REN 1455493977171
NA 2016 Spring Split regular_season DIG-vs-CLG CLG|DIG|G1|9285a10bc63b4b4195f 0126532b-154a-4263-9852-2cc1d52e36ae DIG CLG DIG CLG 1453068033496
NA 2016 Spring Split regular_season IMT-vs-TSM IMT|TSM|G1|3a574ec8efc14133a19 d4ac0a2b-1261-44ac-84b0-5d0ba481b529 IMT TSM IMT TSM 1458424315002
NA 2016 Spring Split regular_season REN-vs-NRG NRG|REN|G1|595576ab268c4654964 c7d41c87-ff11-4f19-a27e-fdf59cafdc26 REN NRG NRG REN 1453064597237
NA 2016 Spring Split regular_season C9-vs-TL C9|TL|G1|2e8856972a0e4be5a091e ebf79ea9-fab3-4ab1-9a8a-deb08d41ec91 C9 TL C9 TL 1455404105636
NA 2016 Spring Split regular_season TIP-vs-IMT IMT|TIP|G1|6ac28a2acb9a4032b56 64f361e2-398a-42c1-9b11-266b06f00b30 TIP IMT IMT TIP 1458510737022
NA 2016 Spring Split regular_season DIG-vs-NRG DIG|NRG|G1|a1ff1570993c4c19ada 247415be-4e7d-4ebb-8095-26088a3fc8c0 DIG NRG NRG DIG 1452986842109
NA 2016 Spring Split regular_season TL-vs-CLG CLG|TL|G1|3cb4eabc931548308162 c8e3ab53-26a2-497c-90ca-2b7aa5ca8e6d TL CLG CLG TL 1453590211998
NA 2016 Spring Split regular_season NRG-vs-DIG DIG|NRG|G1|113795d361194330a64 56635435-70ef-413e-a348-0160f10d363a NRG DIG NRG DIG 1456001599862
NA 2016 Spring Split regular_season C9-vs-TIP C9|TIP|G1|6b79fde2bd2e4025999a efbc72fa-90f4-4195-88d1-36cfdd593ecb C9 TIP C9 TIP 1457898667536
NA 2016 Spring Split regular_season IMT-vs-TL IMT|TL|G1|1f8a9847a82d4ce88b6f 3977a21f-eb53-4c21-b4f7-42a39509681b IMT TL IMT TL 1454878726178
NA 2016 Spring Split regular_season FOX-vs-REN FOX|REN|G1|b422c544241646ec8e3 8a691187-c8b9-47d2-8c3e-2305da8490e7 FOX REN FOX REN 1455396826135
NA 2016 Spring Split regular_season TIP-vs-CLG CLG|TIP|G1|03f2990e13bb419b94c dacce933-d70e-4a7c-9690-39becb682d0f TIP CLG CLG TIP 1454888649037
NA 2016 Spring Split regular_season NRG-vs-CLG CLG|NRG|G1|0d35a37e76c6484a91a 4973675e-eb11-44f0-a736-f48cf793993a NRG CLG CLG NRG 1455400830707
NA 2016 Spring Split regular_season TIP-vs-REN REN|TIP|G1|0d05d127a19c40f3bc4 0294b10e-d0df-4e1a-b62b-f00876ed4be2 TIP REN REN TIP 1458417768310
NA 2016 Spring Split regular_season NRG-vs-IMT IMT|NRG|G1|5d292563481f4e50945 41cd8a14-7ff3-49b4-a7c9-02750c71f55e NRG IMT IMT NRG 1453671895666
NA 2016 Spring Split regular_season TL-vs-DIG DIG|TL|G1|ecd76d6645fc49c6904e b0aca63a-ed06-432c-aba5-f498ddd68a91 TL DIG TL DIG 1454792230097
NA 2016 Spring Split regular_season TIP-vs-REN-tb REN|TIP|G1|9f4651cd85b24f16b94 3e90e2e5-23b7-4692-b1f5-f8c9087c2fc1 TIP REN REN TIP 1458521671662
NA 2016 Spring Split regular_season TIP-vs-FOX FOX|TIP|G1|e283eb8d4ca4406ca44 a68a66ed-dd88-4d2b-95a1-6ead6733d870 TIP FOX FOX TIP 1456099687725
NA 2016 Spring Split regular_season TSM-vs-FOX FOX|TSM|G1|2279e68045fb4edd9e7 58521c7c-d9b3-42f6-83b2-af911eed1c7d TSM FOX TSM FOX 1454802196916
NA 2016 Spring Split regular_season NRG-vs-TIP NRG|TIP|G1|7ab19f98dc0e402ba27 49b838a7-606b-4bf5-b5b4-9faf6af3ed20 NRG TIP NRG TIP 1454806257499
NA 2016 Spring Split regular_season IMT-vs-FOX FOX|IMT|G1|b45fde17e4c0418c9c5 25f79bc8-a3db-4e79-91d9-2339e6e5e518 IMT FOX IMT FOX 1456708339284
NA 2016 Spring Split regular_season CLG-vs-FOX CLG|FOX|G1|7b80962873af4bf0818 3eab6654-8d80-4e11-bf06-3b08e3a087a1 CLG FOX CLG FOX 1454197879845
NA 2016 Spring Split regular_season NRG-vs-C9 C9|NRG|G1|e61c1a31d7034e83ba1c fb93c3f7-3fa2-4cd8-8b3c-f02128448bbe NRG C9 C9 NRG 1456096336514
NA 2016 Spring Split regular_season TSM-vs-C9 C9|TSM|G1|71985e7316b64d838142 5a97f919-e2ff-423d-b292-ed411add0748 TSM C9 C9 TSM 1456009700827
NA 2016 Spring Split regular_season FOX-vs-C9 C9|FOX|G1|fab8ea2b6eb942abb269 200a0866-4613-4a37-b710-8ee358b666ac FOX C9 C9 FOX 1453075934864
NA 2016 Spring Split regular_season FOX-vs-DIG DIG|FOX|G1|bae8716157e54529b0b 4c4bf6cf-1b14-4fd4-a917-29c0d34c22aa FOX DIG FOX DIG 1457834051754
NA 2016 Spring Split regular_season IMT-vs-C9 C9|IMT|G1|43d930fc6dc448cdaf1b 0c35cf88-b407-408a-a46d-b4505a0b1d90 IMT C9 IMT C9 1455490356724
NA 2016 Spring Split regular_season TL-vs-FOX FOX|TL|G1|cbb6777dedea4f929e4f 5734bbcd-5228-4a51-ae7b-aaece4e72ff1 TL FOX FOX TL 1456017788974
NA 2016 Spring Split regular_season FOX-vs-TIP FOX|TIP|G1|cc046f02cde248868d1 bb5718bb-bb19-4cf9-8a67-9d99ab93536a FOX TIP FOX TIP 1452996382618
NA 2016 Spring Split regular_season REN-vs-C9 C9|REN|G1|f0c6153b79a74a45bbb9 256e5345-9f52-452a-88a3-e24c4b48dccf REN C9 C9 REN 1457817663996
NA 2016 Spring Split regular_season TSM-vs-REN REN|TSM|G1|17c42b7e11e74a86853 be618273-6ea1-4b88-8286-1610d2ffec42 TSM REN REN TSM 1457905659104
NA 2016 Spring Split regular_season CLG-vs-REN CLG|REN|G1|ab0dbd05c1504041a25 80aefa86-33d4-43a2-b7f9-db536b061140 CLG REN CLG REN 1454287214975
NA 2016 Spring Split regular_season FOX-vs-IMT FOX|IMT|G1|6b55c595043d467aa9d f9bf6846-4874-4a0b-b1d1-e08be45c2484 FOX IMT IMT FOX 1454283432137
NA 2016 Spring Split regular_season NRG-vs-TSM NRG|TSM|G1|6baeea3a5b80410ca3e 6a76fb12-b658-4871-9a6c-43893ba8adc5 NRG TSM NRG TSM 1454277113082
NA 2016 Spring Split regular_season REN-vs-TL REN|TL|G1|e715a9c609f34080baa3 630768c7-a0b4-48d5-bfdb-2bc2e0b9b473 REN TL REN TL 1452991990370
NA 2016 Spring Split regular_season TIP-vs-TL TIP|TL|G1|b63224a8b89e4728aff0 9c94a5c6-af02-4b62-8dd5-1cf656521dab TIP TL TL TIP 1456606141604
NA 2016 Spring Split regular_season REN-vs-CLG CLG|REN|G1|6ecc17035d944a7a80d c0ef2a1e-a64e-44c7-844a-af32c1359023 REN CLG CLG REN 1456088211904
NA 2016 Spring Split regular_season C9-vs-FOX C9|FOX|G1|5bdbdd612a2b4733a5f6 dae637a9-8072-4533-8f84-1d1773d1773e C9 FOX C9 FOX 1458431515985
NA 2016 Spring Split regular_season TSM-vs-NRG NRG|TSM|G1|fe49249c717d4cc3afb b317901d-53b5-40ea-a3ba-bcf231d03c85 TSM NRG NRG TSM 1458517809005
NA 2016 Spring Split regular_season DIG-vs-TSM DIG|TSM|G1|6b739e9a13994a70a49 3fc0eb20-e5dd-4ed9-844a-2c31a0bca98f DIG TSM DIG TSM 1456092089424
NA 2016 Spring Split regular_season TSM-vs-IMT IMT|TSM|G1|bf6243339c31474a836 4aeb9f9d-ae8a-40c0-ba7b-5f92179de5dd TSM IMT IMT TSM 1453586503767
NA 2016 Spring Split regular_season DIG-vs-TL DIG|TL|G1|f1c6634af25a484e8605 219d60fa-40e6-4601-9bd0-14c83823c345 DIG TL TL DIG 1458427969607
NA 2016 Spring Split regular_season NRG-vs-FOX FOX|NRG|G1|ef217d0d8bd94bb99c5 5b9f1384-5907-479f-bde8-8a63b22b4b95 NRG FOX NRG FOX 1453540930938
NA 2016 Spring Split regular_season DIG-vs-TIP DIG|TIP|G1|cf0346d226144b2a987 2f6ee358-5ff9-4ec2-865e-50dfa4e95618 DIG TIP TIP DIG 1455498115817
NA 2016 Spring Split regular_season REN-vs-IMT IMT|REN|G1|940c98463cb746f9bd1 c219fc77-e03a-4db7-91e6-731c6fc2603f REN IMT IMT REN 1456005138332
NA 2016 Spring Split regular_season IMT-vs-TIP IMT|TIP|G1|da247161dab14689a12 59bb1b1f-a0a5-4b73-8bc7-ec93977f9760 IMT TIP IMT TIP 1453078573278
NA 2016 Spring Split regular_season C9-vs-NRG C9|NRG|G1|1b4aad815b814634a5a8 1e07570f-db1c-47a4-a209-962f44388bcc C9 NRG C9 NRG 1454881844179
NA 2016 Spring Split regular_season C9-vs-IMT C9|IMT|G1|7b2fdc902d554769af77 7bdc7315-88e2-4513-a9c4-4ba026491a12 C9 IMT IMT C9 1452982398798
NA 2016 Spring Split regular_season TL-vs-TSM TL|TSM|G1|ef5400c89ad74251a71c 96b6bd02-c314-4b2d-a5d3-4cc2f1820f05 TL TSM TL TSM 1456700861569
NA 2016 Spring Split regular_season TIP-vs-DIG DIG|TIP|G1|bcd8810c125b4e26a09 faeb71e2-8aa0-4f14-93b8-e4f592d04239 TIP DIG TIP DIG 1454186964708
NA 2016 Spring Split regular_season TIP-vs-C9 C9|TIP|G1|056395fc49874f708fcd 6efa843c-4736-4a66-b8cf-27de20d63ac9 TIP C9 TIP C9 1453582659368
NA 2016 Spring Split regular_season DIG-vs-IMT DIG|IMT|G1|4dab28b6f9ff4f188a5 f73fac84-fdf5-4c67-b973-ef7a9cf5199d DIG IMT IMT DIG 1457910010247
NA 2016 Spring Split regular_season IMT-vs-CLG CLG|IMT|G1|7587680bea084f75ba9 968544a5-871e-4804-9ee0-52ea70fa9a50 IMT CLG CLG IMT 1456614128923
NA 2016 Spring Split regular_season TL-vs-NRG NRG|TL|G1|df049c854f264c08a5e5 fe7c93c9-6a36-4316-b4a6-8c9c1520e44e TL NRG TL NRG 1454194662754
NA 2016 Spring Split regular_season C9-vs-DIG C9|DIG|G1|a44c32cceafe4bd0aa98 12e1ae61-0123-448a-848b-196063fd99e6 C9 DIG C9 DIG 1456619765498
NA 2016 Spring Split regular_season CLG-vs-TL CLG|TL|G1|77933566624e4a8dbb4b c0d25ad4-e680-4189-a02f-4cde7d51bb04 CLG TL TL CLG 1457825363800
NA 2016 Spring Split regular_season TSM-vs-CLG CLG|TSM|G1|f186019739864a098e7 d863d85b-77ae-4868-93bc-0684df87fae1 TSM CLG CLG TSM 1452978745084
NA 2016 Spring Split regular_season TL-vs-TIP TIP|TL|G1|a758d97a8fec49a8a26a 77604048-570a-478b-8f37-a76d67af1db7 TL TIP TL TIP 1454273656017
NA 2016 Spring Split regular_season FOX-vs-CLG CLG|FOX|G1|ebdb2e4c11b94e9fa7a 7f789f64-dc88-4f6e-abd6-3ffb67d90745 FOX CLG CLG FOX 1457913980243
NA 2016 Spring Split regular_season NRG-vs-TL NRG|TL|G1|43c24453685144928916 d7ef21f7-b0d3-48b1-a084-3bd362b0b3dd NRG TL NRG TL 1457902336314
NA 2016 Spring Split regular_season C9-vs-TSM C9|TSM|G1|8405a2a54df94e23ac53 abca3505-f0cd-47fa-9490-3f3056644fbc C9 TSM TSM C9 1454189839317
NA 2016 Spring Split regular_season FOX-vs-TSM FOX|TSM|G1|2eb2690b90a04263807 3166e06a-355f-49a4-8f15-c4dbb13a09f8 FOX TSM TSM FOX 1456609469660
NA 2016 Spring Split regular_season CLG-vs-NRG CLG|NRG|G1|f8631794fc4e4ddcb33 16d591d8-3d9f-4a51-aae7-7e4e0d454a49 CLG NRG CLG NRG 1458420867860
NA 2016 Spring Split regular_season DIG-vs-REN DIG|REN|G1|9945b7df54854c2fa4b 9f97f050-314a-4be0-9cf0-f92a104027e2 DIG REN DIG REN 1453594671646
NA 2016 Spring Split regular_season TSM-vs-TIP TIP|TSM|G1|d2a8ff8d4e744aa8b99 6cee8e87-eff5-42e0-be3c-ec5e3389187d TSM TIP TSM TIP 1457828476225
NA 2016 Spring Split regular_season REN-vs-FOX FOX|REN|G1|7c4342f882e04ab2b72 80bf670a-70a5-43ac-bc0d-af215e3fb39c REN FOX REN FOX 1458504203961
NA 2016 Spring Split regular_season TSM-vs-TL TL|TSM|G1|41e3799a4415479ca641 eaad0706-629b-4538-8b5c-1cefa1047ef0 TSM TL TSM TL 1453072476122
NA 2016 Spring Split regular_season CLG-vs-DIG CLG|DIG|G1|ac027c02a3c74eababf f7191cc5-ed19-47b2-8a22-7d7d6e4fa910 CLG DIG CLG DIG 1458513749687
NA 2016 Spring Split regular_season CLG-vs-C9 C9|CLG|G1|4403d39ef61348a1b3c7 92ac2d2f-9216-4c85-9314-3ce7d2f79baf CLG C9 C9 CLG 1453675601163
NA 2016 Spring Split regular_season FOX-vs-NRG FOX|NRG|G1|639c747f6c824e49907 32377c4c-efca-48f8-8b39-2e4f90700131 FOX NRG FOX NRG 1455483657512
NA 2016 Spring Split regular_season TL-vs-IMT IMT|TL|G1|001e39c943cc41eca05d 78bb195f-3024-40d8-826f-e2d519c8e69a TL IMT IMT TL 1456102995801
NA 2016 Spring Split regular_season CLG-vs-IMT CLG|IMT|G1|02fa5a4f7f67437f9bb dcf926cf-6147-4212-9780-7c26be79f57e CLG IMT IMT CLG 1454798307493
NA 2016 Spring Split regular_season IMT-vs-DIG DIG|IMT|G1|a2b124d32d1e42779eb 6eda6902-440b-421a-8435-476bbb253932 IMT DIG IMT DIG 1455410429577
NA 2016 Spring Split regular_season DIG-vs-C9 C9|DIG|G1|5c4e3f06abd846dfa645 bcbbeda2-1e4e-4fa9-b809-bdc64f09262e DIG C9 C9 DIG 1454280727468
NA 2016 Spring Split regular_season REN-vs-TSM REN|TSM|G1|ad45ebecc2b54d749cb 8a1c7745-c649-4e91-91d1-9da0222798e3 REN TSM TSM REN 1454885799781
NA 2016 Spring Split regular_season REN-vs-DIG DIG|REN|G1|0f8b4f7f359b4e80942 bec9e9ed-2ec2-4ba6-9f94-7a18ea24a6a2 REN DIG REN DIG 1456705443881
NA 2016 Spring Split regular_season DIG-vs-FOX DIG|FOX|G1|35f192bb43db47f4af8 bd070aac-7b23-4ccb-8e2a-715d8dd5a1b4 DIG FOX DIG FOX 1454892988815
NA 2016 Spring Split regular_season IMT-vs-NRG IMT|NRG|G1|5d2b4d72112a48cf8bd 887b5e4a-1bd4-4489-a014-03a178d678ff IMT NRG IMT NRG 1457821395421
NA 2016 Spring Split regular_season C9-vs-CLG C9|CLG|G1|4a7bb6aa5d4044cb8673 0ea22d4c-94cb-47da-ab3f-b36bb80f0dcc C9 CLG CLG C9 1456697366231
NA 2016 Spring Split regular_season C9-vs-REN C9|REN|G1|97cd5049d6f9499aabf6 48a59c00-2c73-4a76-91bd-a186bf6bab48 C9 REN C9 REN 1454794748712
NA 2016 Spring Split regular_season TL-vs-C9 C9|TL|G1|8120797c63054045860e3 b3ee2501-70c9-4e4c-9045-9e6e938ebd99 TL C9 TL C9 1458507543667
NA 2016 Spring Split regular_season TIP-vs-NRG NRG|TIP|G1|c63b59094cd64df0a7f 4bb51652-6ff3-4f24-8dcf-9fc4e56af638 TIP NRG TIP NRG 1456693298608
NA 2016 Spring Split regular_season NRG-vs-REN NRG|REN|G1|f644face7d9f4bfc989 60ef48ca-165b-4633-b41d-ffb8d465908a NRG REN NRG REN 1456616843051
NA 2017 Summer Split na_2017_summer_playoffs semi-final-2 CLG|IMT|G1|2561b6d7b632416092f 06e54b40-cb22-4a55-90e5-0cccc4e35a3a CLG IMT IMT CLG 1503781728975
NA 2017 Summer Split na_2017_summer_playoffs semi-final-2 CLG|IMT|G2|2561b6d7b632416092f d774ad6c-a179-4ffb-a865-b51a0b372de1 IMT CLG IMT CLG 1503787448443
NA 2017 Summer Split na_2017_summer_playoffs semi-final-2 CLG|IMT|G3|2561b6d7b632416092f b4963a32-36d6-472d-b85c-e63d5d896b1f IMT CLG IMT CLG 1503788836186
NA 2017 Summer Split na_2017_summer_playoffs semi-final-1 DIG|TSM|G1|76e28bfb8eaa443aad8 8aafca76-6b0b-4595-8d5b-ce89bb122f36 TSM DIG TSM DIG 1503868738596
NA 2017 Summer Split na_2017_summer_playoffs semi-final-1 DIG|TSM|G2|76e28bfb8eaa443aad8 05b831d6-60b4-4401-a391-809cd9a680cd DIG TSM TSM DIG 1503871500900
NA 2017 Summer Split na_2017_summer_playoffs semi-final-1 DIG|TSM|G3|76e28bfb8eaa443aad8 c88b304c-a8b7-4f60-a132-a2dfd8ae9f08 DIG TSM DIG TSM 1503874871350
NA 2017 Summer Split na_2017_summer_playoffs semi-final-1 DIG|TSM|G4|76e28bfb8eaa443aad8 523eeade-494f-44a2-975a-6ece8feb24bf DIG TSM TSM DIG 1503880987262
NA 2017 Summer Split na_2017_summer_playoffs quarter-final-2 CLG|NV|G1|fc38ade95b4449c4b7cc da6b889c-a5b4-4f39-86a4-49e9a17fdc19 CLG NV CLG NV 1503268417975
NA 2017 Summer Split na_2017_summer_playoffs quarter-final-2 CLG|NV|G2|fc38ade95b4449c4b7cc 3f1621a5-cad3-4d69-9b44-16786d44b8ad CLG NV NV CLG 1503272673204
NA 2017 Summer Split na_2017_summer_playoffs quarter-final-2 CLG|NV|G3|fc38ade95b4449c4b7cc d5fcff9a-0988-4508-a4fb-6a8c5610f562 CLG NV NV CLG 1503275911569
NA 2017 Summer Split na_2017_summer_playoffs quarter-final-2 CLG|NV|G4|fc38ade95b4449c4b7cc 364726e2-e54b-4c92-99cc-0839c7639f17 CLG NV CLG NV 1503278023883
NA 2017 Summer Split na_2017_summer_playoffs quarter-final-2 CLG|NV|G5|fc38ade95b4449c4b7cc 8258ce44-c911-4c5a-9161-2ffaeb761d55 NV CLG CLG NV 1503283726895
NA 2017 Summer Split na_2017_summer_playoffs grand-final IMT|TSM|G1|79dfc77caf5e46c3981 6cbcd518-8387-414f-b9c2-e2c141f367dc TSM IMT TSM IMT 1504478073765
NA 2017 Summer Split na_2017_summer_playoffs grand-final IMT|TSM|G2|79dfc77caf5e46c3981 68801abf-e93d-44a5-82d8-a3762d1f3eb4 IMT TSM IMT TSM 1504478168017
NA 2017 Summer Split na_2017_summer_playoffs grand-final IMT|TSM|G3|79dfc77caf5e46c3981 0a2bcac5-b0cd-4f32-a91e-223f976f5a3a TSM IMT TSM IMT 1504558175407
NA 2017 Summer Split na_2017_summer_playoffs grand-final IMT|TSM|G4|79dfc77caf5e46c3981 9d429f26-d1a1-4a6f-b712-d0c16a01017d IMT TSM TSM IMT 1504558197613
NA 2017 Summer Split na_2017_summer_playoffs quarter-final-1 C9|DIG|G1|3606f1f8a6ac4acc9709 94064247-2318-4c47-936b-0e0f6e400cf5 DIG C9 DIG C9 1503189934157
NA 2017 Summer Split na_2017_summer_playoffs quarter-final-1 C9|DIG|G2|3606f1f8a6ac4acc9709 ee87b964-48b2-403a-9ced-05d48f9b2195 C9 DIG DIG C9 1503189930866
NA 2017 Summer Split na_2017_summer_playoffs quarter-final-1 C9|DIG|G3|3606f1f8a6ac4acc9709 69707e0b-8d89-4eae-9f17-21bf89e31b67 DIG C9 C9 DIG 1503189950365
NA 2017 Summer Split na_2017_summer_playoffs quarter-final-1 C9|DIG|G4|3606f1f8a6ac4acc9709 6adecd5b-71cd-42cd-84b8-88197c253de2 C9 DIG DIG C9 1503189859763
NA 2017 Summer Split na_2017_summer_playoffs third-place CLG|DIG|G1|ca385232f53649f1a9a bc57735b-51df-48a6-ab27-7bf063b73066 DIG CLG CLG DIG 1504415503723
NA 2017 Summer Split na_2017_summer_playoffs third-place CLG|DIG|G2|ca385232f53649f1a9a 05443956-fe8b-476b-a573-bc35912025a3 CLG DIG CLG DIG 1504415548324
NA 2017 Summer Split na_2017_summer_playoffs third-place CLG|DIG|G3|ca385232f53649f1a9a fb6355ba-0292-4142-aac8-8c657535c7c8 DIG CLG CLG DIG 1504415617744
NA 2017 Summer Split regular_season FOX-vs-CLG CLG|FOX|G1|20a6b963f72a4b7bb22 4cdd7de9-4b67-43da-9337-4be868b0ebfd FOX CLG CLG FOX 1497129162655
NA 2017 Summer Split regular_season FOX-vs-CLG CLG|FOX|G2|20a6b963f72a4b7bb22 9b53c6d6-1bf2-44e2-8a64-7b18f0e06637 CLG FOX FOX CLG 1497129217983
NA 2017 Summer Split regular_season FOX-vs-CLG CLG|FOX|G3|20a6b963f72a4b7bb22 02703666-974c-45d5-b7f3-72359fec65e2 FOX CLG CLG FOX 1497136237150
NA 2017 Summer Split regular_season DIG-vs-CLG CLG|DIG|G1|273c410ef05047a6b20 90655a72-191e-4ba0-9fd4-9143d270cf93 DIG CLG CLG DIG 1501895257808
NA 2017 Summer Split regular_season DIG-vs-CLG CLG|DIG|G2|273c410ef05047a6b20 df09cf98-9a0b-4f10-9c71-0c9931e73a36 CLG DIG DIG CLG 1501897954577
NA 2017 Summer Split regular_season DIG-vs-CLG CLG|DIG|G3|273c410ef05047a6b20 b906ccee-de6c-4f78-89e2-604fa7b1f99b DIG CLG CLG DIG 1501901644281
NA 2017 Summer Split regular_season FLY-vs-IMT FLY|IMT|G1|fbb5750ddc574501831 f1109b2d-502b-4b7f-9dbd-219fc9babd71 FLY IMT FLY IMT 1500764073936
NA 2017 Summer Split regular_season FLY-vs-IMT FLY|IMT|G2|fbb5750ddc574501831 65e96180-e7e0-48b5-ad75-8a44348ab712 IMT FLY IMT FLY 1500769114508
NA 2017 Summer Split regular_season FLY-vs-IMT FLY|IMT|G3|fbb5750ddc574501831 2da6d8a4-5416-4228-8e2b-6e6be3c562d2 FLY IMT IMT FLY 1500773427932
NA 2017 Summer Split regular_season IMT-vs-C9 C9|IMT|G1|36b9f8882d2c433a9cad 53d72fde-26e7-47e0-97dc-6a3d33c4f522 IMT C9 C9 IMT 1497732627973
NA 2017 Summer Split regular_season IMT-vs-C9 C9|IMT|G2|36b9f8882d2c433a9cad e80e7dad-8641-4c20-b51c-2c2dfae8c47c C9 IMT IMT C9 1497735963868
NA 2017 Summer Split regular_season IMT-vs-C9 C9|IMT|G3|36b9f8882d2c433a9cad 465b550d-7d50-4e37-a05f-40e3a0ece026 IMT C9 IMT C9 1497741521512
NA 2017 Summer Split regular_season IMT-vs-FLY FLY|IMT|G1|d482e30196cc4b7e859 fa6fc405-8a9f-46a4-ab58-54cc10560f60 IMT FLY IMT FLY 1497139903470
NA 2017 Summer Split regular_season IMT-vs-FLY FLY|IMT|G2|d482e30196cc4b7e859 7233d2db-78d0-42d7-8495-021ba1985cab FLY IMT FLY IMT 1497142830809
NA 2017 Summer Split regular_season IMT-vs-FLY FLY|IMT|G3|d482e30196cc4b7e859 58c817cf-bd79-4343-93d6-023c4c28d643 IMT FLY IMT FLY 1497147174046
NA 2017 Summer Split regular_season NV-vs-P1 NV|P1|G1|ca1f9f80c63a4492ad99e a9b406c6-6143-40e1-8026-b9a22750c00d NV P1 NV P1 1496641927360
NA 2017 Summer Split regular_season NV-vs-P1 NV|P1|G2|ca1f9f80c63a4492ad99e 7e78b5bb-ec0b-4d49-91f5-25fdc1cc3aa4 P1 NV P1 NV 1496641782148
NA 2017 Summer Split regular_season NV-vs-P1 NV|P1|G3|ca1f9f80c63a4492ad99e 104ff27d-63fa-40e9-b7da-d2f668dd5213 NV P1 NV P1 1496641938977
NA 2017 Summer Split regular_season FOX-vs-DIG DIG|FOX|G1|db3b6b50b610476283d 3eea0e2d-66c0-455d-8f1b-35f3d4d26173 FOX DIG DIG FOX 1501455681179
NA 2017 Summer Split regular_season FOX-vs-DIG DIG|FOX|G2|db3b6b50b610476283d b0576e9e-c457-4014-b72a-8bba59a74ba8 DIG FOX FOX DIG 1501460216925
NA 2017 Summer Split regular_season FOX-vs-DIG DIG|FOX|G3|db3b6b50b610476283d 3a9fbf5a-4525-4bf1-bc1b-fb4455628941 FOX DIG DIG FOX 1501465555125
NA 2017 Summer Split regular_season IMT-vs-CLG CLG|IMT|G1|f3db4c6a9ab84311b7b e05f122a-02b6-4f9b-a3e1-63b67f8f94aa IMT CLG IMT CLG 1498263194685
NA 2017 Summer Split regular_season IMT-vs-CLG CLG|IMT|G2|f3db4c6a9ab84311b7b eb3718cd-0d0b-4aa8-b599-3577b676aa59 CLG IMT IMT CLG 1498266280535
NA 2017 Summer Split regular_season TL-vs-DIG DIG|TL|G1|0485baef55d44f9ab193 fbe9789e-6b27-4d3e-866a-22df55cc7b8a TL DIG DIG TL 1502049079701
NA 2017 Summer Split regular_season TL-vs-DIG DIG|TL|G2|0485baef55d44f9ab193 860b9aa1-1127-4a8f-a305-6d94c36fe138 DIG TL TL DIG 1502052117957
NA 2017 Summer Split regular_season TL-vs-DIG DIG|TL|G3|0485baef55d44f9ab193 5485ac05-0b0b-44c0-a49b-9b55be3037a2 TL DIG DIG TL 1502059050120
NA 2017 Summer Split regular_season CLG-vs-NV CLG|NV|G1|5b75498765424b84a0e5 025073e8-1546-47bd-a8f0-dae991a8f6ec CLG NV CLG NV 1498337205690
NA 2017 Summer Split regular_season CLG-vs-NV CLG|NV|G2|5b75498765424b84a0e5 a588920b-d263-4402-9914-ab53d1a31a98 NV CLG NV CLG 1498340402984
NA 2017 Summer Split regular_season CLG-vs-NV CLG|NV|G3|5b75498765424b84a0e5 2ab5e56b-2e26-4d05-bb4f-7bf28b0f7683 CLG NV CLG NV 1498343887933
NA 2017 Summer Split regular_season TSM-vs-P1 P1|TSM|G1|d209aef77d684b53871c a747f02f-c121-4287-b746-d43abf7365fc TSM P1 TSM P1 1500152971350
NA 2017 Summer Split regular_season TSM-vs-P1 P1|TSM|G2|d209aef77d684b53871c 138d510b-660d-4aaa-961a-1355868bc9ff P1 TSM TSM P1 1500155802482
NA 2017 Summer Split regular_season TSM-vs-CLG CLG|TSM|G1|79162bf7d0ee40e892f 61c3977f-ce98-47a5-8c57-444e241b186c TSM CLG TSM CLG 1502059055566
NA 2017 Summer Split regular_season TSM-vs-CLG CLG|TSM|G2|79162bf7d0ee40e892f 30a0da07-773b-41de-a1f0-e075ed2ebe7d CLG TSM TSM CLG 1502063554134
NA 2017 Summer Split regular_season C9-vs-TSM C9|TSM|G1|fe76f8129bd640929f9a e19beab1-9711-45e8-a881-43aed4e2409d C9 TSM TSM C9 1498866779678
NA 2017 Summer Split regular_season C9-vs-TSM C9|TSM|G2|fe76f8129bd640929f9a d4828398-d166-4e0d-998d-53302e3a8f71 TSM C9 C9 TSM 1498869795956
NA 2017 Summer Split regular_season C9-vs-TSM C9|TSM|G3|fe76f8129bd640929f9a 30408357-485d-4f04-9455-87b791265b57 C9 TSM C9 TSM 1498873533153
NA 2017 Summer Split regular_season P1-vs-CLG CLG|P1|G1|383230ffe21c460aad22 7b073e40-7206-4422-9dec-d242f7fd58a2 P1 CLG CLG P1 1497819749123
NA 2017 Summer Split regular_season P1-vs-CLG CLG|P1|G2|383230ffe21c460aad22 f0d54de5-d270-4f9c-b874-15448f240f68 CLG P1 P1 CLG 1497822419751
NA 2017 Summer Split regular_season P1-vs-CLG CLG|P1|G3|383230ffe21c460aad22 bae2ba55-457e-4031-b6d6-3987e901ac45 P1 CLG CLG P1 1497827775568
NA 2017 Summer Split regular_season DIG-vs-TL DIG|TL|G1|f828fbac2a3d4068808d 15dffd7d-a8cd-4a95-b89d-d415b6a8319b DIG TL DIG TL 1497214722606
NA 2017 Summer Split regular_season DIG-vs-TL DIG|TL|G2|f828fbac2a3d4068808d dfd350bc-7f16-4cea-9ea4-4590c127af1c TL DIG TL DIG 1497218346199
NA 2017 Summer Split regular_season DIG-vs-TL DIG|TL|G3|f828fbac2a3d4068808d a950e59f-2220-463a-aefa-7c1d8d6a9c3c DIG TL TL DIG 1497222551338
NA 2017 Summer Split regular_season CLG-vs-C9 C9|CLG|G1|df312a9e98e7438d8dfd 82ea9465-f937-40db-9d0b-7ad06567844c CLG C9 CLG C9 1498943610588
NA 2017 Summer Split regular_season CLG-vs-C9 C9|CLG|G2|df312a9e98e7438d8dfd b0d8f3f9-4cf7-44ef-aa0a-7e448443becc C9 CLG C9 CLG 1498947746504
NA 2017 Summer Split regular_season CLG-vs-C9 C9|CLG|G3|df312a9e98e7438d8dfd 7aeaf068-e3be-454d-8759-b78ad97f20fd CLG C9 CLG C9 1498949614001
NA 2017 Summer Split regular_season FOX-vs-FLY FLY|FOX|G1|608045f6fde5464ebad ed181e9a-e0fb-429c-8008-6b75668766bf FOX FLY FOX FLY 1496641872001
NA 2017 Summer Split regular_season FOX-vs-FLY FLY|FOX|G2|608045f6fde5464ebad 80a0834a-6452-4926-bfbd-abc33b728482 FLY FOX FOX FLY 1496641675154
NA 2017 Summer Split regular_season TSM-vs-DIG DIG|TSM|G1|39e43500a5194a60b1b 521a1731-3087-458a-a1ce-04407a8fe2f8 TSM DIG DIG TSM 1500757612709
NA 2017 Summer Split regular_season TSM-vs-DIG DIG|TSM|G2|39e43500a5194a60b1b 07903819-179e-43fb-b66e-aadcca72927f DIG TSM DIG TSM 1500756652941
NA 2017 Summer Split regular_season TSM-vs-NV NV|TSM|G1|e6efcd03b7f54dc19709 d6367fc6-6d47-4fd0-9b19-ef9bd1da38f9 TSM NV TSM NV 1501454730524
NA 2017 Summer Split regular_season TSM-vs-NV NV|TSM|G2|e6efcd03b7f54dc19709 eeb6a48c-8cf0-4c75-b1bc-8e472e948389 NV TSM NV TSM 1501459381446
NA 2017 Summer Split regular_season TSM-vs-NV NV|TSM|G3|e6efcd03b7f54dc19709 b6c8e724-59f4-47f9-bc83-ae30745b9e1c TSM NV TSM NV 1501465547627
NA 2017 Summer Split regular_season TL-vs-P1 P1|TL|G1|80cacd2f4db942639eb4a c056b181-d18b-468d-915c-8ea0eb04fb6c TL P1 TL P1 1498424208467
NA 2017 Summer Split regular_season TL-vs-P1 P1|TL|G2|80cacd2f4db942639eb4a 3bc77be4-c221-4cf3-9bc8-d321d073fa92 P1 TL P1 TL 1498429783255
NA 2017 Summer Split regular_season TL-vs-P1 P1|TL|G3|80cacd2f4db942639eb4a 349e369a-7960-4f9c-b248-c292cd0caa79 TL P1 TL P1 1498432107854
NA 2017 Summer Split regular_season TL-vs-TSM TL|TSM|G1|ce7a38b9961549da9fb7 f7fbadae-f768-43a5-9141-7836f9cfc2bd TL TSM TSM TL 1497729710311
NA 2017 Summer Split regular_season TL-vs-TSM TL|TSM|G2|ce7a38b9961549da9fb7 d4428060-a5eb-403e-bdc7-110eeb6fe3f0 TSM TL TSM TL 1497735797924
NA 2017 Summer Split regular_season C9-vs-NV C9|NV|G1|aa1e34e2c58e455182478 65489d4a-b6aa-4ce1-bd2f-3a40033c1659 C9 NV NV C9 1500159499952
NA 2017 Summer Split regular_season C9-vs-NV C9|NV|G2|aa1e34e2c58e455182478 aa17ca3c-d9f7-41ed-8839-e86d069a6619 NV C9 NV C9 1500163999420
NA 2017 Summer Split regular_season FOX-vs-P1 FOX|P1|G1|4811c7181c4e437d88da bec6482f-c31a-42be-b31b-3dd6fcf5ecc0 FOX P1 P1 FOX 1498266237147
NA 2017 Summer Split regular_season FOX-vs-P1 FOX|P1|G2|4811c7181c4e437d88da 5b917613-4f27-47df-b52a-8b0827527b02 P1 FOX P1 FOX 1498328247965
NA 2017 Summer Split regular_season C9-vs-DIG C9|DIG|G1|d72b2c2e45b1480884f9 9df49ece-18e6-4e64-ac52-b0f597af93bd C9 DIG DIG C9 1498431216234
NA 2017 Summer Split regular_season C9-vs-DIG C9|DIG|G2|d72b2c2e45b1480884f9 b1e45678-0853-49ac-9ced-c85b0a66ab8c DIG C9 C9 DIG 1498433930787
NA 2017 Summer Split regular_season C9-vs-DIG C9|DIG|G3|d72b2c2e45b1480884f9 400e0dae-1ce1-4799-a948-5b10b0ef2cbd C9 DIG C9 DIG 1498438122113
NA 2017 Summer Split regular_season FOX-vs-TL FOX|TL|G1|ea60ae626e624893aa25 fb875f4f-e4b2-4094-91a9-294c108bf688 FOX TL FOX TL 1498953428329
NA 2017 Summer Split regular_season FOX-vs-TL FOX|TL|G2|ea60ae626e624893aa25 2447e837-5205-4b4a-ac24-ee14cc412642 TL FOX TL FOX 1498955932078
NA 2017 Summer Split regular_season FOX-vs-TL FOX|TL|G3|ea60ae626e624893aa25 129f721d-da7c-487f-976b-93562b14fe6c FOX TL FOX TL 1498956178248
NA 2017 Summer Split regular_season TSM-vs-TL TL|TSM|G1|94904c7effb949dda430 4a45e6c7-932d-43a0-afc9-02c939bc9b1a TSM TL TSM TL 1500249307362
NA 2017 Summer Split regular_season TSM-vs-TL TL|TSM|G2|94904c7effb949dda430 86ab17b2-e675-4d3f-a5f6-f4e8c5db06cb TL TSM TSM TL 1500253561947
NA 2017 Summer Split regular_season P1-vs-TSM P1|TSM|G1|ede57988769f40b980a2 ed8bc316-266d-4aec-ba46-a3647aed74da P1 TSM TSM P1 1501966208954
NA 2017 Summer Split regular_season P1-vs-TSM P1|TSM|G2|ede57988769f40b980a2 dd7b0f99-0a15-4d73-a9ca-b7bec88d90b0 TSM P1 TSM P1 1501966001579
NA 2017 Summer Split regular_season FOX-vs-C9 C9|FOX|G1|bca6c7969563473eb839 3f346e4d-99d9-4d36-9e19-6ac32700c285 FOX C9 C9 FOX 1497218078739
NA 2017 Summer Split regular_season FOX-vs-C9 C9|FOX|G2|bca6c7969563473eb839 1a2fdf83-e077-458e-94da-4e72e4896087 C9 FOX C9 FOX 1497218567507
NA 2017 Summer Split regular_season TL-vs-FOX FOX|TL|G1|83ef03e510374388bfaa f04b8705-cc6d-4e52-bdc0-3f6b4a33921b TL FOX FOX TL 1496641808179
NA 2017 Summer Split regular_season TL-vs-FOX FOX|TL|G2|83ef03e510374388bfaa a74c7a01-054f-43de-8e16-42ec437465b8 FOX TL FOX TL 1496641813734
NA 2017 Summer Split regular_season TL-vs-NV NV|TL|G1|324d3e3b5d6b49e5a67bd 8cfdcaf6-c905-4dd5-b3b3-a29b26e706cc TL NV TL NV 1500690663207
NA 2017 Summer Split regular_season TL-vs-NV NV|TL|G2|324d3e3b5d6b49e5a67bd 2edcdd1c-dce3-4d4e-9fb6-5852302c978b NV TL NV TL 1500694355470
NA 2017 Summer Split regular_season TL-vs-NV NV|TL|G3|324d3e3b5d6b49e5a67bd 84924cbc-ce24-4c2b-97e5-07dbe241f731 TL NV TL NV 1500700395899
NA 2017 Summer Split regular_season CLG-vs-FOX CLG|FOX|G1|cd08227b62f44943aa1 e6e71064-0ff7-43c0-9492-3720d5e8e514 CLG FOX CLG FOX 1500756348684
NA 2017 Summer Split regular_season CLG-vs-FOX CLG|FOX|G2|cd08227b62f44943aa1 e067cbf2-621b-4a62-8880-678aeb1ad22d FOX CLG CLG FOX 1500759531278
NA 2017 Summer Split regular_season DIG-vs-IMT DIG|IMT|G1|489b945f64174b7bb88 b6067834-b0aa-4260-bb62-94665ff1ac47 DIG IMT DIG IMT 1501368420803
NA 2017 Summer Split regular_season DIG-vs-IMT DIG|IMT|G2|489b945f64174b7bb88 820c7c8d-6a2c-4475-88c3-6815400384fa IMT DIG IMT DIG 1501368298886
NA 2017 Summer Split regular_season DIG-vs-IMT DIG|IMT|G3|489b945f64174b7bb88 29a20cd4-7a81-4b92-b8fb-b06b328b65d6 DIG IMT DIG IMT 1501381223377
NA 2017 Summer Split regular_season P1-vs-NV NV|P1|G1|82bf97f4df31445aba344 3933cdab-2864-4e13-92c0-f1627ce2d5e6 P1 NV P1 NV 1498876915289
NA 2017 Summer Split regular_season P1-vs-NV NV|P1|G2|82bf97f4df31445aba344 4d0a95c4-5228-428e-b8b3-0a54dc7876f7 NV P1 NV P1 1498882283964
NA 2017 Summer Split regular_season P1-vs-NV NV|P1|G3|82bf97f4df31445aba344 951072b7-9d1a-4795-a482-f18aa90ff164 P1 NV P1 NV 1498887082839
NA 2017 Summer Split regular_season DIG-vs-NV DIG|NV|G1|24b03d42ec2541f690e2 2dd37117-05c9-4944-bf05-62a5baa6ad32 DIG NV DIG NV 1496641695241
NA 2017 Summer Split regular_season DIG-vs-NV DIG|NV|G2|24b03d42ec2541f690e2 ebeca86f-710a-471e-a058-a5d337b6c8fc NV DIG NV DIG 1496641795560
NA 2017 Summer Split regular_season DIG-vs-NV DIG|NV|G3|24b03d42ec2541f690e2 47913846-5e7f-45fd-b186-9c25c8054b9f DIG NV DIG NV 1496641706841
NA 2017 Summer Split regular_season NV-vs-DIG DIG|NV|G1|ac3eae58b8d447bf8598 b8f4883b-5e33-4538-bee4-fada46d00793 NV DIG NV DIG 1499039389259
NA 2017 Summer Split regular_season NV-vs-DIG DIG|NV|G2|ac3eae58b8d447bf8598 2d634d23-7e1d-4302-ba12-b67cd71dabf7 DIG NV DIG NV 1499041918822
NA 2017 Summer Split regular_season NV-vs-DIG DIG|NV|G3|ac3eae58b8d447bf8598 a71ad554-fcea-42a2-81fa-ced30f4e08d3 NV DIG NV DIG 1499046479914
NA 2017 Summer Split regular_season TSM-vs-IMT IMT|TSM|G1|72742d57b7a64452ba0 5dfc5d4f-2d8a-4fdb-b08e-d18e8e70a906 TSM IMT TSM IMT 1498943623451
NA 2017 Summer Split regular_season TSM-vs-IMT IMT|TSM|G2|72742d57b7a64452ba0 7cbc89af-aada-4747-8e4f-02f45467a978 IMT TSM TSM IMT 1498947718968
NA 2017 Summer Split regular_season DIG-vs-P1 DIG|P1|G1|817890a4bbd6457384ac 9ecc0e5a-a12d-489c-8dbc-6699e1f7776d DIG P1 DIG P1 1500238268860
NA 2017 Summer Split regular_season DIG-vs-P1 DIG|P1|G2|817890a4bbd6457384ac 5ce064f3-a01d-4575-ba65-f8941a05d8e3 P1 DIG P1 DIG 1500240203120
NA 2017 Summer Split regular_season DIG-vs-P1 DIG|P1|G3|817890a4bbd6457384ac a558826f-0f22-4216-b963-b52534845fca DIG P1 DIG P1 1500244908292
NA 2017 Summer Split regular_season FOX-vs-NV FOX|NV|G1|df62e428d466492dbc07 f7146566-d38d-47ae-bed4-41819753a301 FOX NV FOX NV 1500250098937
NA 2017 Summer Split regular_season FOX-vs-NV FOX|NV|G2|df62e428d466492dbc07 eaea551d-bcf4-4562-b2ef-ebf97b6d549b NV FOX NV FOX 1500250120644
NA 2017 Summer Split regular_season FOX-vs-NV FOX|NV|G3|df62e428d466492dbc07 04c6790e-a168-4d72-af68-b63ef5e08890 FOX NV NV FOX 1500256270708
NA 2017 Summer Split regular_season P1-vs-FOX FOX|P1|G1|1e5184ea41b4427e8f83 77011210-37be-4bae-9d29-771d1f5e9a23 P1 FOX FOX P1 1501287648423
NA 2017 Summer Split regular_season P1-vs-FOX FOX|P1|G2|1e5184ea41b4427e8f83 a2204a79-0808-43eb-94b8-bf338edcaa03 FOX P1 FOX P1 1501290244075
NA 2017 Summer Split regular_season C9-vs-CLG C9|CLG|G1|dd86c0aa411d4d5d8004 5f0dab20-fe93-41bd-b8ee-5e58f3e71423 C9 CLG C9 CLG 1496641663123
NA 2017 Summer Split regular_season C9-vs-CLG C9|CLG|G2|dd86c0aa411d4d5d8004 8f31d624-ef55-444e-8e97-5b1062c768be CLG C9 CLG C9 1496641819117
NA 2017 Summer Split regular_season C9-vs-CLG C9|CLG|G3|dd86c0aa411d4d5d8004 6c544a5e-b255-477e-ac60-d419b7b0435a C9 CLG CLG C9 1496641614011
NA 2017 Summer Split regular_season FLY-vs-P1 FLY|P1|G1|a5ebf6296ca5480f97e9 db31743e-d840-4868-8f05-a4822828f90e FLY P1 FLY P1 1502060988776
NA 2017 Summer Split regular_season FLY-vs-P1 FLY|P1|G2|a5ebf6296ca5480f97e9 6132fb6b-7076-419e-b09e-061c504b0790 P1 FLY FLY P1 1502067130104
NA 2017 Summer Split regular_season TSM-vs-FOX FOX|TSM|G1|b0445f69aa6048dfba0 3cd745a8-6488-438d-a14c-ddb2bb36b4ce TSM FOX TSM FOX 1498424189663
NA 2017 Summer Split regular_season TSM-vs-FOX FOX|TSM|G2|b0445f69aa6048dfba0 aac7e2b2-60c8-4c0b-b60b-078ad7142708 FOX TSM TSM FOX 1498428857624
NA 2017 Summer Split regular_season FOX-vs-IMT FOX|IMT|G1|04f73c1508844ab4899 b4565fb0-b7d8-4f69-a01e-9133bfc67ccf FOX IMT IMT FOX 1501972169637
NA 2017 Summer Split regular_season FOX-vs-IMT FOX|IMT|G2|04f73c1508844ab4899 bb5c72b4-caec-442d-9065-c19d97bf83a7 IMT FOX IMT FOX 1501976654772
NA 2017 Summer Split regular_season FLY-vs-TSM FLY|TSM|G1|d23e8fcca17a4c7ab5c ba749209-2100-46bf-aaae-37eaf9c4b9d1 FLY TSM TSM FLY 1501360827132
NA 2017 Summer Split regular_season FLY-vs-TSM FLY|TSM|G2|d23e8fcca17a4c7ab5c d6e5e663-36b3-435f-8888-3e3699726862 TSM FLY TSM FLY 1501364810529
NA 2017 Summer Split regular_season TSM-vs-C9 C9|TSM|G1|16ec7718386c46bc9797 31181183-ac56-4caf-9b50-9d4f07f4a071 TSM C9 TSM C9 1496641855666
NA 2017 Summer Split regular_season TSM-vs-C9 C9|TSM|G2|16ec7718386c46bc9797 e5af7ade-5dbc-4dc6-b7c2-774d90f7387e C9 TSM TSM C9 1496641688533
NA 2017 Summer Split regular_season P1-vs-DIG DIG|P1|G1|22246a25349440d5b616 a809f366-9ed7-4f6d-b4a1-097bf997fea4 P1 DIG DIG P1 1497743923468
NA 2017 Summer Split regular_season P1-vs-DIG DIG|P1|G2|22246a25349440d5b616 e10a07e6-f0e7-445a-beee-be23b1fa5d2a DIG P1 P1 DIG 1497746067685
NA 2017 Summer Split regular_season P1-vs-DIG DIG|P1|G3|22246a25349440d5b616 5096c5e1-23fa-4576-aafd-0eaa413c0886 P1 DIG DIG P1 1497753892305
NA 2017 Summer Split regular_season CLG-vs-TL CLG|TL|G1|b99857b854bc4f1499a9 7cc339f3-737f-4a6a-952c-d7e9b4c3d669 CLG TL CLG TL 1496641706980
NA 2017 Summer Split regular_season CLG-vs-TL CLG|TL|G2|b99857b854bc4f1499a9 6ea5695f-5e0d-446c-bf08-173e2403970f TL CLG CLG TL 1496641863542
NA 2017 Summer Split regular_season IMT-vs-TL IMT|TL|G1|869b6661e62c4b148d6f f9a42b25-0958-44fa-862e-e9d51265c3ae IMT TL IMT TL 1497656343349
NA 2017 Summer Split regular_season IMT-vs-TL IMT|TL|G2|869b6661e62c4b148d6f 29390d1a-58c1-42d1-a65f-40222b825936 TL IMT IMT TL 1497659235215
NA 2017 Summer Split regular_season IMT-vs-NV IMT|NV|G1|1e7bcb6d368e4581a3e3 b4368d23-d1db-4eb6-9ba3-51185705b868 IMT NV NV IMT 1497058625743
NA 2017 Summer Split regular_season IMT-vs-NV IMT|NV|G2|1e7bcb6d368e4581a3e3 22766f53-c387-4f2b-9e57-95953c5d4e0f NV IMT NV IMT 1497062291345
NA 2017 Summer Split regular_season C9-vs-TL C9|TL|G1|dd963c4473f54876be4db 9cc572f9-60b3-4acb-af9d-80e9dea23e91 C9 TL C9 TL 1498343912192
NA 2017 Summer Split regular_season C9-vs-TL C9|TL|G2|dd963c4473f54876be4db 833265ab-141f-4aa1-b640-4ca012b76791 TL C9 C9 TL 1498348411992
NA 2017 Summer Split regular_season IMT-vs-DIG DIG|IMT|G1|f059df01d92c44bab98 a63ade95-877a-4217-b92e-0c7890cec76e IMT DIG DIG IMT 1498346888094
NA 2017 Summer Split regular_season IMT-vs-DIG DIG|IMT|G2|f059df01d92c44bab98 72170b77-77d9-4ec9-95e7-f833efaf27f2 DIG IMT IMT DIG 1498349722975
NA 2017 Summer Split regular_season IMT-vs-DIG DIG|IMT|G3|f059df01d92c44bab98 9419227b-3298-41ce-9226-d50b61e745b9 IMT DIG IMT DIG 1498358862030
NA 2017 Summer Split regular_season DIG-vs-FOX DIG|FOX|G1|8681ba7c7c9f447eb5d 39eb9e19-7467-49c2-a3d3-4a8939a820cc DIG FOX DIG FOX 1497827624096
NA 2017 Summer Split regular_season DIG-vs-FOX DIG|FOX|G2|8681ba7c7c9f447eb5d 17aa0315-4f7f-4ec1-a016-b583c6419b71 FOX DIG FOX DIG 1497834704554
NA 2017 Summer Split regular_season DIG-vs-FOX DIG|FOX|G3|8681ba7c7c9f447eb5d 4af7bee2-ebbc-40fb-9faf-f416986ab7f7 DIG FOX DIG FOX 1497838956667
NA 2017 Summer Split regular_season DIG-vs-C9 C9|DIG|G1|2324a85294354cd3b367 85d5f159-3453-4008-b473-23d612e9e36a DIG C9 DIG C9 1500842696745
NA 2017 Summer Split regular_season DIG-vs-C9 C9|DIG|G2|2324a85294354cd3b367 e5f99caf-b343-4168-ad9e-ed07d5e321c7 C9 DIG C9 DIG 1500846769764
NA 2017 Summer Split regular_season DIG-vs-C9 C9|DIG|G3|2324a85294354cd3b367 df4ad004-7842-4dec-9915-3afaad400c68 DIG C9 C9 DIG 1500849952701
NA 2017 Summer Split regular_season DIG-vs-TSM DIG|TSM|G1|93386199725149fea0d 080c4cca-928f-4a25-94bf-6f091df2a3bd DIG TSM DIG TSM 1497129059257
NA 2017 Summer Split regular_season DIG-vs-TSM DIG|TSM|G2|93386199725149fea0d d9f54286-72aa-4d3b-b37a-bc37da2ad38f TSM DIG TSM DIG 1497132086984
NA 2017 Summer Split regular_season DIG-vs-TSM DIG|TSM|G3|93386199725149fea0d 3e43002e-9caf-426d-8405-9edbb59aacdc DIG TSM DIG TSM 1497136124671
NA 2017 Summer Split regular_season IMT-vs-FOX FOX|IMT|G1|a1656c9a809d4c25873 b7415bce-2c1a-455e-b744-ba9ec49cbb13 IMT FOX IMT FOX 1500083963041
NA 2017 Summer Split regular_season IMT-vs-FOX FOX|IMT|G2|a1656c9a809d4c25873 4b8f81c1-80d0-4182-8fe9-c78311955ddb FOX IMT IMT FOX 1500088425166
NA 2017 Summer Split regular_season NV-vs-TL NV|TL|G1|d4d50c134daf4a418dd19 f3aca9d2-740b-4570-a0e5-720ac941ad2f NV TL NV TL 1497139750296
NA 2017 Summer Split regular_season NV-vs-TL NV|TL|G2|d4d50c134daf4a418dd19 69bd2c00-0d02-46fe-9072-b936342c2e1a TL NV TL NV 1497142090045
NA 2017 Summer Split regular_season NV-vs-TL NV|TL|G3|d4d50c134daf4a418dd19 808babfc-5d7e-495c-ac45-172df7084ea6 NV TL NV TL 1497147084025
NA 2017 Summer Split regular_season C9-vs-IMT C9|IMT|G1|f52129b9b45a40ff9721 49a191a3-958f-4a52-839f-7986c1c51c60 C9 IMT C9 IMT 1500238256956
NA 2017 Summer Split regular_season C9-vs-IMT C9|IMT|G2|f52129b9b45a40ff9721 bbc22d5c-b829-4a14-956c-2cf3477ccc25 IMT C9 IMT C9 1500242646295
NA 2017 Summer Split regular_season C9-vs-IMT C9|IMT|G3|f52129b9b45a40ff9721 b24c5ff8-fbf4-41f9-a4fc-cffd0f0a19ac C9 IMT IMT C9 1500245382232
NA 2017 Summer Split regular_season P1-vs-IMT IMT|P1|G1|503eeb09bcb24bc3817c 77e5dbf0-9feb-4761-a487-741ef0e7daf0 P1 IMT IMT P1 1499028556275
NA 2017 Summer Split regular_season P1-vs-IMT IMT|P1|G2|503eeb09bcb24bc3817c a19dacdf-76b1-4388-a3b7-5c0b6ab55d7b IMT P1 P1 IMT 1499031512777
NA 2017 Summer Split regular_season P1-vs-IMT IMT|P1|G3|503eeb09bcb24bc3817c d2eb219f-029a-49ac-a56b-85c55d3a079b P1 IMT P1 IMT 1499035219116
NA 2017 Summer Split regular_season FLY-vs-C9 C9|FLY|G1|73484b50fead4588bcf6 5c69f9be-fce7-4ef3-ab49-14a109eb0b2d FLY C9 C9 FLY 1497824909050
NA 2017 Summer Split regular_season FLY-vs-C9 C9|FLY|G2|73484b50fead4588bcf6 69d6fe14-9d4d-472f-950a-6a50615cb891 C9 FLY C9 FLY 1497997990209
NA 2017 Summer Split regular_season FOX-vs-TSM FOX|TSM|G1|7bf6a5521e6b4337bb2 555828df-39ec-4ac0-9116-3ce09b28695f FOX TSM TSM FOX 1500843495960
NA 2017 Summer Split regular_season FOX-vs-TSM FOX|TSM|G2|7bf6a5521e6b4337bb2 3039a14f-593d-497e-bdab-1430c04008fd TSM FOX FOX TSM 1500845976107
NA 2017 Summer Split regular_season FOX-vs-TSM FOX|TSM|G3|7bf6a5521e6b4337bb2 b5570429-978a-4363-aeb1-0cff491f0dbd FOX TSM TSM FOX 1500849229345
NA 2017 Summer Split regular_season NV-vs-FLY FLY|NV|G1|a5cb773bfc3e42fd9d36 42f7a5ef-921d-4e33-9408-4eb8ee6004b9 NV FLY FLY NV 1500853237180
NA 2017 Summer Split regular_season NV-vs-FLY FLY|NV|G2|a5cb773bfc3e42fd9d36 eaa8973e-e28d-4d57-8d7c-65395d3c46b4 FLY NV NV FLY 1500857608140
NA 2017 Summer Split regular_season NV-vs-FLY FLY|NV|G3|a5cb773bfc3e42fd9d36 eaafd5bc-b30a-45c8-be5f-9e4a5e178b82 NV FLY NV FLY 1500862900340
NA 2017 Summer Split regular_season FLY-vs-NV FLY|NV|G1|bdb73175d0824101868b cf15f084-a9f9-48bd-a584-bf3ca82bed42 FLY NV FLY NV 1498436692187
NA 2017 Summer Split regular_season FLY-vs-NV FLY|NV|G2|bdb73175d0824101868b 9261b896-5190-4bc7-839a-59998c780de9 NV FLY NV FLY 1498438708758
NA 2017 Summer Split regular_season FLY-vs-NV FLY|NV|G3|bdb73175d0824101868b 64281b56-8ffa-4fd8-bd8c-6c56e39e5243 FLY NV NV FLY 1498443025455
NA 2017 Summer Split regular_season NV-vs-C9 C9|NV|G1|59e02c5151f84c91badfb e4fc0723-e21a-4783-a1df-57f7935642f4 NV C9 C9 NV 1501965587328
NA 2017 Summer Split regular_season NV-vs-C9 C9|NV|G2|59e02c5151f84c91badfb 67a4b363-f955-47bf-9f97-33e264066b5c C9 NV C9 NV 1501969624219
NA 2017 Summer Split regular_season IMT-vs-P1 IMT|P1|G1|41271df368d0431584d6 04d93e59-5a42-4857-bc7b-4dd0a9e908bc IMT P1 P1 IMT 1496641834088
NA 2017 Summer Split regular_season IMT-vs-P1 IMT|P1|G2|41271df368d0431584d6 7efcfe66-742d-4061-94c5-f26a57d96f67 P1 IMT IMT P1 1496641732869
NA 2017 Summer Split regular_season IMT-vs-P1 IMT|P1|G3|41271df368d0431584d6 797b2e57-f81d-4cdd-95d1-5b74c7395324 IMT P1 IMT P1 1496641740110
NA 2017 Summer Split regular_season NV-vs-IMT IMT|NV|G1|09aa43dd1f844aa893bb 07ec4527-3df2-4d85-a588-6ff65c46d444 NV IMT IMT NV 1501889374654
NA 2017 Summer Split regular_season NV-vs-IMT IMT|NV|G2|09aa43dd1f844aa893bb d6f26ea8-74da-4d77-9a9b-a06e6379d3f3 IMT NV IMT NV 1501892434418
NA 2017 Summer Split regular_season FLY-vs-FOX FLY|FOX|G1|23fd309154f94dbf92e a88075a7-c54b-4824-bcbd-7140907f154b FLY FOX FOX FLY 1499030325416
NA 2017 Summer Split regular_season FLY-vs-FOX FLY|FOX|G2|23fd309154f94dbf92e d05b8dde-5c47-4e6f-a537-7c9f3a6bcaa0 FOX FLY FLY FOX 1499300508439
NA 2017 Summer Split regular_season FLY-vs-FOX FLY|FOX|G3|23fd309154f94dbf92e 7f1407d3-2cef-4151-9b0a-1ceb4eaba4e7 FLY FOX FLY FOX 1499036287193
NA 2017 Summer Split regular_season TL-vs-C9 C9|TL|G1|b7b1b27bd288456d83847 de956596-6fc2-4455-b5f5-70f70091ceba TL C9 TL C9 1501367625425
NA 2017 Summer Split regular_season TL-vs-C9 C9|TL|G2|b7b1b27bd288456d83847 06072e7d-41ed-4c27-90e0-80629f14039d C9 TL C9 TL 1501383308403
NA 2017 Summer Split regular_season TL-vs-C9 C9|TL|G3|b7b1b27bd288456d83847 9e60ed16-c116-45e2-a95a-a87235bbbab1 TL C9 C9 TL 1501381236356
NA 2017 Summer Split regular_season C9-vs-P1 C9|P1|G1|bef9065d522749be9be29 61e9036d-f0c0-4f46-88d4-75200dc9ca27 C9 P1 C9 P1 1500681800148
NA 2017 Summer Split regular_season C9-vs-P1 C9|P1|G2|bef9065d522749be9be29 c14f2798-15b3-4598-bc02-10f9df8604f5 P1 C9 P1 C9 1500680921411
NA 2017 Summer Split regular_season C9-vs-P1 C9|P1|G3|bef9065d522749be9be29 dea93233-6cb6-4622-835e-33c96142a4fa C9 P1 C9 P1 1500687732443
NA 2017 Summer Split regular_season CLG-vs-DIG CLG|DIG|G1|d22c85f62bd44f418a9 cd46460b-9a24-44fa-8aaf-e9bbe13fa303 CLG DIG DIG CLG 1500148927722
NA 2017 Summer Split regular_season CLG-vs-DIG CLG|DIG|G2|d22c85f62bd44f418a9 36bbdfd7-cf27-4279-923e-6ef65a271c3f DIG CLG DIG CLG 1500155789037
NA 2017 Summer Split regular_season NV-vs-TSM NV|TSM|G1|be91c95c08f74fca92e3 7a8ee041-4d4a-4414-9112-94736e82ffdf NV TSM TSM NV 1497819604106
NA 2017 Summer Split regular_season NV-vs-TSM NV|TSM|G2|be91c95c08f74fca92e3 5813d6b8-588c-4c87-b335-33fa5d7c550a TSM NV TSM NV 1497823294880
NA 2017 Summer Split regular_season TL-vs-FLY FLY|TL|G1|01546f7e5db24bc987fd 3e8ff15e-972d-4317-b1b7-4a312335d94e TL FLY FLY TL 1500161340298
NA 2017 Summer Split regular_season TL-vs-FLY FLY|TL|G2|01546f7e5db24bc987fd ce6fac10-dd43-49a2-a924-02ba182f0653 FLY TL FLY TL 1500163432577
NA 2017 Summer Split regular_season P1-vs-TL P1|TL|G1|819d5d6de48e4bdcbe4e8 03093907-a098-4a5a-a475-86ef7e2cfa9b P1 TL TL P1 1500763092599
NA 2017 Summer Split regular_season P1-vs-TL P1|TL|G2|819d5d6de48e4bdcbe4e8 e993c4a4-3132-4e19-a039-9ac9f6a66614 TL P1 TL P1 1500766590715
NA 2017 Summer Split regular_season TSM-vs-FLY FLY|TSM|G1|f0ff18bbcfdb48008c4 4859dbef-0c9d-4a34-b1d4-3d16c7a3de52 TSM FLY TSM FLY 1498337532837
NA 2017 Summer Split regular_season TSM-vs-FLY FLY|TSM|G2|f0ff18bbcfdb48008c4 4b0b9906-5589-40fc-b9b9-0b07c959e1fa FLY TSM TSM FLY 1498340388757
NA 2017 Summer Split regular_season FLY-vs-DIG DIG|FLY|G1|d84e35b5eb69413aa91 85953d67-1f71-4631-84ff-daf26836d8a6 FLY DIG DIG FLY 1496641744732
NA 2017 Summer Split regular_season FLY-vs-DIG DIG|FLY|G2|d84e35b5eb69413aa91 8e96cf81-6334-4989-8787-478f30c74310 DIG FLY DIG FLY 1496641845129
NA 2017 Summer Split regular_season C9-vs-FOX C9|FOX|G1|6fce323d9a524a62a810 1310d8e4-bb12-43d8-bcb8-9b918c770e9f C9 FOX C9 FOX 1502051480182
NA 2017 Summer Split regular_season C9-vs-FOX C9|FOX|G2|6fce323d9a524a62a810 d0e5b647-6007-45ce-8070-adc3e39336e7 FOX C9 C9 FOX 1502054671965
NA 2017 Summer Split regular_season CLG-vs-FLY CLG|FLY|G1|23d85b22fcd64383968 96e0a98f-fe69-47dc-8cd5-7e144ec3597b CLG FLY CLG FLY 1500076561414
NA 2017 Summer Split regular_season CLG-vs-FLY CLG|FLY|G2|23d85b22fcd64383968 2f3aa61d-ce04-4cfb-9174-be5685452199 FLY CLG CLG FLY 1500076543940
NA 2017 Summer Split regular_season TL-vs-IMT IMT|TL|G1|d5df534f2afa4ee5b404 bd8391fa-e8f0-45d1-ac14-8c89873ed5c3 TL IMT IMT TL 1501294128283
NA 2017 Summer Split regular_season TL-vs-IMT IMT|TL|G2|d5df534f2afa4ee5b404 ca490539-8660-47b5-937b-1de616e1507b IMT TL IMT TL 1501297243517
NA 2017 Summer Split regular_season CLG-vs-IMT CLG|IMT|G1|611507e4a11b43f1893 6cde69eb-0748-492d-bc05-0eda6ad16dea CLG IMT IMT CLG 1500853686317
NA 2017 Summer Split regular_season CLG-vs-IMT CLG|IMT|G2|611507e4a11b43f1893 d0dbbbcb-3e55-4616-9c96-cc171443da35 IMT CLG CLG IMT 1500857607572
NA 2017 Summer Split regular_season CLG-vs-IMT CLG|IMT|G3|611507e4a11b43f1893 6791f926-7dff-4ad0-b600-69382c4206d9 CLG IMT IMT CLG 1500873636365
NA 2017 Summer Split regular_season IMT-vs-TSM IMT|TSM|G1|734cf9739fe44bc5b0a 58c40d13-9eb9-4adf-b430-50a7edaf451c IMT TSM IMT TSM 1496641887136
NA 2017 Summer Split regular_season IMT-vs-TSM IMT|TSM|G2|734cf9739fe44bc5b0a aa21204f-425d-41c4-a2b1-b4187a69eb76 TSM IMT IMT TSM 1496641892917
NA 2017 Summer Split regular_season P1-vs-FLY FLY|P1|G1|658899dc8cd845e983a7 c14e6a4f-949c-4ac5-bcd3-32d29e7aaacc P1 FLY FLY P1 1497225250091
NA 2017 Summer Split regular_season P1-vs-FLY FLY|P1|G2|658899dc8cd845e983a7 32f964cd-e362-4d92-a7e5-b14edd8eb45d FLY P1 FLY P1 1497228208423
NA 2017 Summer Split regular_season P1-vs-C9 C9|P1|G1|3fb93e8be95e4ecf9621f c568caa6-68a1-4771-a18b-e8a1ea76bea7 P1 C9 C9 P1 1497052155598
NA 2017 Summer Split regular_season P1-vs-C9 C9|P1|G2|3fb93e8be95e4ecf9621f 249e142a-676e-4c69-a6d9-99d55dbc00c5 C9 P1 C9 P1 1497051971237
NA 2017 Summer Split regular_season NV-vs-CLG CLG|NV|G1|ce181b84445c4d25859a 53a585c2-33a8-4d3a-a678-3961baae38e9 NV CLG CLG NV 1501364926919
NA 2017 Summer Split regular_season NV-vs-CLG CLG|NV|G2|ce181b84445c4d25859a 40f0e06b-1d1d-40b5-8944-3787574987b3 CLG NV CLG NV 1501366472004
NA 2017 Summer Split regular_season FLY-vs-CLG CLG|FLY|G1|5a70aa95e69f48e7ad7 2f5599f8-cfb2-45e9-b33b-9dda246335df FLY CLG CLG FLY 1497739485131
NA 2017 Summer Split regular_season FLY-vs-CLG CLG|FLY|G2|5a70aa95e69f48e7ad7 3503b0c9-7eff-4c36-adb2-5be9dac4608b CLG FLY FLY CLG 1497740780261
NA 2017 Summer Split regular_season FLY-vs-CLG CLG|FLY|G3|5a70aa95e69f48e7ad7 01b150a8-bdf8-4e18-acf7-7e468437137a FLY CLG CLG FLY 1497748211770
NA 2017 Summer Split regular_season DIG-vs-FLY DIG|FLY|G1|4b91b54563084989a57 913f4d06-0c53-4b3f-b906-8dcb63ca4f19 DIG FLY FLY DIG 1498949592478
NA 2017 Summer Split regular_season DIG-vs-FLY DIG|FLY|G2|4b91b54563084989a57 fb7ad57d-c45e-41e9-931d-d11017214790 FLY DIG DIG FLY 1498953468719
NA 2017 Summer Split regular_season DIG-vs-FLY DIG|FLY|G3|4b91b54563084989a57 b35a7e59-0b02-435a-b5d5-19de04bfe5c9 DIG FLY FLY DIG 1498953444096
NA 2017 Summer Split regular_season C9-vs-FLY C9|FLY|G1|8382263b216b4e1b999f 847e20e5-8605-4a0c-a04f-4c2c6fc5069c C9 FLY C9 FLY 1501447868669
NA 2017 Summer Split regular_season C9-vs-FLY C9|FLY|G2|8382263b216b4e1b999f 140ff7b5-4911-466e-9925-3073fe69eb46 FLY C9 C9 FLY 1501450062900
NA 2017 Summer Split regular_season CLG-vs-P1 CLG|P1|G1|e978e015b29f49789ea9 275ba92d-bb6c-43a0-9fc7-9691277d69d2 CLG P1 CLG P1 1501447895689
NA 2017 Summer Split regular_season CLG-vs-P1 CLG|P1|G2|e978e015b29f49789ea9 43142012-4310-4f64-b7c2-4b8c7bb56554 P1 CLG P1 CLG 1501617392243
NA 2017 Summer Split regular_season CLG-vs-P1 CLG|P1|G3|e978e015b29f49789ea9 f155b4d5-0055-4194-b236-3252a2a38c37 CLG P1 P1 CLG 1501453321755
NA 2017 Summer Split regular_season FLY-vs-TL FLY|TL|G1|17d9a1aadc0b44ba9335 3ec17c2a-4135-4ec4-835d-f64a1d1e6492 FLY TL FLY TL 1501972735706
NA 2017 Summer Split regular_season FLY-vs-TL FLY|TL|G2|17d9a1aadc0b44ba9335 4c68232f-0022-4098-982c-606241af5048 TL FLY TL FLY 1501975968777
NA 2017 Summer Split regular_season FLY-vs-TL FLY|TL|G3|17d9a1aadc0b44ba9335 d2654698-7d63-42cc-a8b3-1411fa2ea6b3 FLY TL FLY TL 1501981532560
NA 2017 Summer Split regular_season NV-vs-FOX FOX|NV|G1|0c6004ac6d0b45698fc0 ec69bb4a-66c6-4145-be81-fdb14b1b82c1 NV FOX FOX NV 1497664185166
NA 2017 Summer Split regular_season NV-vs-FOX FOX|NV|G2|0c6004ac6d0b45698fc0 cc9f5090-c0fc-4347-b28f-d9fe30c03db4 FOX NV FOX NV 1497997942572
NA 2017 Summer Split regular_season CLG-vs-TSM CLG|TSM|G1|c217f94ef2a647c198c adcba79e-966d-48ad-bf87-fdad889f1330 CLG TSM CLG TSM 1497222694650
NA 2017 Summer Split regular_season CLG-vs-TSM CLG|TSM|G2|c217f94ef2a647c198c ad357285-c8c1-49e5-8bfd-2d6369bcfc97 TSM CLG TSM CLG 1497231362569
NA 2017 Summer Split regular_season CLG-vs-TSM CLG|TSM|G3|c217f94ef2a647c198c 29ed6da7-74d9-48ad-a10a-bf4b06c35e00 CLG TSM TSM CLG 1497231512265
NA 2017 Summer Split regular_season TL-vs-CLG CLG|TL|G1|96c75bfc6ebb4cf5af18 8540326e-1461-46c9-badb-699ab33e1e13 TL CLG CLG TL 1499040130927
NA 2017 Summer Split regular_season TL-vs-CLG CLG|TL|G2|96c75bfc6ebb4cf5af18 a010676c-285a-4e5c-a736-3b2721e49e01 CLG TL CLG TL 1499046311145
NA 2017 Summer Split na_2017_summer_promotion_relegation match-b GCU|P1|G1|96fd353f222f4a99abe5 6e0cefe6-9139-40ca-b7d5-a28c492b0664 P1 GCU P1 GCU 1502486663673
NA 2017 Summer Split na_2017_summer_promotion_relegation match-b GCU|P1|G2|96fd353f222f4a99abe5 16e75f1e-0e0b-4813-afcc-8539838a8a32 GCU P1 P1 GCU 1502488810977
NA 2017 Summer Split na_2017_summer_promotion_relegation match-b GCU|P1|G3|96fd353f222f4a99abe5 76ac81b4-1cf5-48ec-9e01-df7a12cd20ae P1 GCU GCU P1 1502491326924
NA 2017 Summer Split na_2017_summer_promotion_relegation match-b GCU|P1|G4|96fd353f222f4a99abe5 31003a61-fe0f-452d-9309-5f760ec813e9 GCU P1 GCU P1 1502495121211
NA 2017 Summer Split na_2017_summer_promotion_relegation match-b GCU|P1|G5|96fd353f222f4a99abe5 90a4b8bf-7a70-491c-8078-7c6184eef321 P1 GCU P1 GCU 1502500075642
NA 2017 Summer Split na_2017_summer_promotion_relegation match-d P1|TL|G1|cfc8712a62324cea8cd5d ddab57d3-0a5e-4363-a890-780ed5bed4ee TL P1 P1 TL 1502572525393
NA 2017 Summer Split na_2017_summer_promotion_relegation match-d P1|TL|G2|cfc8712a62324cea8cd5d 486bb8ac-8296-48a8-b175-cb6e8f4c57f0 P1 TL P1 TL 1502574038876
NA 2017 Summer Split na_2017_summer_promotion_relegation match-d P1|TL|G3|cfc8712a62324cea8cd5d 965dfc11-ab1b-4f5c-ab21-a116ef45a358 TL P1 TL P1 1502577399252
NA 2017 Summer Split na_2017_summer_promotion_relegation match-d P1|TL|G4|cfc8712a62324cea8cd5d f254e26f-b0ba-4c91-b000-57c2ff75ab08 P1 TL TL P1 1502580410463
NA 2017 Summer Split na_2017_summer_promotion_relegation match-d P1|TL|G5|cfc8712a62324cea8cd5d 8d7adfa4-55a5-467e-bd10-fec75b393396 TL P1 TL P1 1502586024112
NA 2017 Summer Split na_2017_summer_promotion_relegation match-a EUN|TL|G1|c4db21bf3a5b4081af99 97f2cc89-826b-43d7-b738-719c98822c96 TL EUN TL EUN 1502484294236
NA 2017 Summer Split na_2017_summer_promotion_relegation match-a EUN|TL|G2|c4db21bf3a5b4081af99 28a5aaed-b191-4993-aa48-e41a89cb7c16 EUN TL TL EUN 1502485286423
NA 2017 Summer Split na_2017_summer_promotion_relegation match-a EUN|TL|G3|c4db21bf3a5b4081af99 6a67a8ff-038e-467f-879a-2ad1563ff85a EUN TL TL EUN 1502488921982
NA 2017 Summer Split na_2017_summer_promotion_relegation match-c EUN|GCU|G1|cebff61943dd463eab1 eb39b216-a92a-4def-8a87-287275715b98 EUN GCU EUN GCU 1502571766210
NA 2017 Summer Split na_2017_summer_promotion_relegation match-c EUN|GCU|G2|cebff61943dd463eab1 ee17a2be-8348-4f2a-8555-4413eb65614f EUN GCU EUN GCU 1502575602077
NA 2017 Summer Split na_2017_summer_promotion_relegation match-c EUN|GCU|G3|cebff61943dd463eab1 b5c81741-2fdf-40d6-9fd8-8512d8e11a3a GCU EUN EUN GCU 1502579574344
NA 2017 Summer Split na_2017_summer_promotion_relegation match-e EUN|P1|G1|b2b3b95583d544b8a987 2fb4ce25-e7b4-42e6-86c7-631e6f04103b P1 EUN P1 EUN 1502659436524
NA 2017 Summer Split na_2017_summer_promotion_relegation match-e EUN|P1|G2|b2b3b95583d544b8a987 efccebd8-9a09-4768-99cb-58e67f1f928a EUN P1 P1 EUN 1502663955530
NA 2017 Summer Split na_2017_summer_promotion_relegation match-e EUN|P1|G3|b2b3b95583d544b8a987 07d7d7b9-e3cb-410c-99ad-6704285a10c3 P1 EUN P1 EUN 1502669125855
NA 2017 Summer Split na_2017_regionals match-b CLG|FLY|G1|9a38d426500f483e8b0 7c1b9ae0-e1f4-47f2-b941-265a9ad04a4b FLY CLG FLY CLG 1504989547775
NA 2017 Summer Split na_2017_regionals match-b CLG|FLY|G2|9a38d426500f483e8b0 444d8588-77e9-4a26-bf8a-a5a62c7fc02a FLY CLG CLG FLY 1504997238085
NA 2017 Summer Split na_2017_regionals match-b CLG|FLY|G3|9a38d426500f483e8b0 ed71bf4e-8a0c-4686-840a-85e708c2cd1e CLG FLY CLG FLY 1504997502807
NA 2017 Summer Split na_2017_regionals match-b CLG|FLY|G4|9a38d426500f483e8b0 3b3214e2-51b7-41f9-80d9-77c7b4a4d70e FLY CLG CLG FLY 1505001853394
NA 2017 Summer Split na_2017_regionals match-a DIG|FLY|G1|ed0a001720fe46a0b39 1b0569cd-6e49-4d5c-a5ff-fd2a8ba5d01b FLY DIG FLY DIG 1504904984465
NA 2017 Summer Split na_2017_regionals match-a DIG|FLY|G2|ed0a001720fe46a0b39 adeb86c2-ac46-4251-97af-4597148e2e4d FLY DIG FLY DIG 1504907756968
NA 2017 Summer Split na_2017_regionals match-a DIG|FLY|G3|ed0a001720fe46a0b39 51bbc138-bf39-4e4e-890d-b18da4ceb5d3 DIG FLY FLY DIG 1504910477110
NA 2017 Summer Split na_2017_regionals match-c C9|CLG|G1|04b74482ce7a4e9fb234 f24eb970-62d5-4411-8dc9-eee7dc8cd6ba C9 CLG C9 CLG 1505077837382
NA 2017 Summer Split na_2017_regionals match-c C9|CLG|G2|04b74482ce7a4e9fb234 d294b44d-ff8c-4fca-b207-fa37e553a81d CLG C9 C9 CLG 1505080400469
NA 2017 Summer Split na_2017_regionals match-c C9|CLG|G3|04b74482ce7a4e9fb234 53ff01c4-7722-45d7-b24c-8c903f41cbaa C9 CLG CLG C9 1505083396252
NA 2017 Summer Split na_2017_regionals match-c C9|CLG|G4|04b74482ce7a4e9fb234 f5b066a3-c484-4963-b448-9e6e6e708788 CLG C9 C9 CLG 1505089248961
NA LCS Summer regional playoffs na_2015_regionals R1M1 C9|GV|G1|3294f2ca0b244752b6b31 68be844b-dd09-4687-ab26-fe6a215a3635 C9 GV GV C9 1440877478046
NA LCS Summer regional playoffs na_2015_regionals R1M1 C9|GV|G2|3294f2ca0b244752b6b31 0a4caee8-eee0-4c45-a936-da078f1fd2cb C9 GV GV C9 1440881336556
NA LCS Summer regional playoffs na_2015_regionals R1M1 C9|GV|G3|3294f2ca0b244752b6b31 a7c7aeae-307d-425a-a4cb-cf516fb3df4d C9 GV C9 GV 1440884729228
NA LCS Summer regional playoffs na_2015_regionals R1M1 C9|GV|G4|3294f2ca0b244752b6b31 0b391bb1-fb6c-4f46-b5ac-98d02d233411 C9 GV C9 GV 1440888220618
NA LCS Summer regional playoffs na_2015_regionals R1M1 C9|GV|G5|3294f2ca0b244752b6b31 7445b376-a33a-4841-9eab-9819d2964232 C9 GV C9 GV 1440891640329
NA LCS Summer regional playoffs na_2015_regionals R2M2 C9|TIP|G1|e9a5b193697c44dbb614 439a193f-5a52-4331-aadf-544a28c26947 TIP C9 TIP C9 1440969657540
NA LCS Summer regional playoffs na_2015_regionals R2M2 C9|TIP|G2|e9a5b193697c44dbb614 e6d42381-c1ef-4ed5-948e-9ed045e088a3 C9 TIP TIP C9 1440973128862
NA LCS Summer regional playoffs na_2015_regionals R2M2 C9|TIP|G3|e9a5b193697c44dbb614 7ceec250-6074-478f-b1cf-80ae47e4fe2c TIP C9 C9 TIP 1440975920034
NA LCS Summer regional playoffs na_2015_regionals R2M2 C9|TIP|G4|e9a5b193697c44dbb614 d3143b64-8b03-4622-aa6c-da9d32a1ebac C9 TIP C9 TIP 1440979585737
NA LCS Summer regional playoffs na_2015_regionals R2M2 C9|TIP|G5|e9a5b193697c44dbb614 587e4dff-b2a1-4e42-bf69-93b15b4033ca TIP C9 C9 TIP 1440982995476
NA LCS Summer regional playoffs na_2015_regionals R3M3 C9|TL|G1|cbca127725fa435799908 1ba9a039-1575-4c87-934d-e47af3681c61 TL C9 C9 TL 1441051250221
NA LCS Summer regional playoffs na_2015_regionals R3M3 C9|TL|G2|cbca127725fa435799908 242e47e4-d6b6-43aa-a876-c16c4b3075c2 C9 TL TL C9 1441053084448
NA LCS Summer regional playoffs na_2015_regionals R3M3 C9|TL|G3|cbca127725fa435799908 ded5f112-d9c6-4f44-af4f-2abdd2e4b41d TL C9 C9 TL 1441057718527
NA LCS Summer regional playoffs na_2015_regionals R3M3 C9|TL|G4|cbca127725fa435799908 40f25a15-1677-4d62-b87f-d75ae10f9b07 C9 TL C9 TL 1441062260038
NA 2017 Spring Split na_2017_spring_playoffs quarter-final-2 CLG|FLY|G1|b9b6c1d1fe444eba86d 55d5d674-c65f-4059-a4cf-ede5205ba1dc FLY CLG CLG FLY 1491770251986
NA 2017 Spring Split na_2017_spring_playoffs quarter-final-2 CLG|FLY|G2|b9b6c1d1fe444eba86d 43fe10e4-6c2d-485e-85ec-19918dbbfb91 CLG FLY CLG FLY 1491774745570
NA 2017 Spring Split na_2017_spring_playoffs quarter-final-2 CLG|FLY|G3|b9b6c1d1fe444eba86d 984af58b-ef21-460c-88fc-c9f32a4d6b99 FLY CLG FLY CLG 1491778034694
NA 2017 Spring Split na_2017_spring_playoffs quarter-final-2 CLG|FLY|G4|b9b6c1d1fe444eba86d 2ba81c36-df9a-4f31-88de-1c8042763a22 FLY CLG FLY CLG 1491780746422
NA 2017 Spring Split na_2017_spring_playoffs quarter-final-2 CLG|FLY|G5|b9b6c1d1fe444eba86d ce3d644d-327c-4aab-93c7-3643ed6da16d CLG FLY FLY CLG 1491786920290
NA 2017 Spring Split na_2017_spring_playoffs semi-final-2 FLY|TSM|G1|5c19b127ebd74b1d92d f1b21edc-7604-4418-8b2d-fae26e5dc5c1 TSM FLY TSM FLY 1492377319128
NA 2017 Spring Split na_2017_spring_playoffs semi-final-2 FLY|TSM|G2|5c19b127ebd74b1d92d dabf9ea8-7746-433c-b8bd-f2b694ea6946 FLY TSM TSM FLY 1492380045656
NA 2017 Spring Split na_2017_spring_playoffs semi-final-2 FLY|TSM|G3|5c19b127ebd74b1d92d df33d828-a007-45c5-8ee7-bd14ae66ed5a FLY TSM TSM FLY 1492385546931
NA 2017 Spring Split na_2017_spring_playoffs third-place FLY|P1|G1|1f6dde12e36f4fc892c5 db9f792a-67d1-4291-a07a-68ab31f9e2e1 P1 FLY P1 FLY 1492896419069
NA 2017 Spring Split na_2017_spring_playoffs third-place FLY|P1|G2|1f6dde12e36f4fc892c5 a781819a-7e92-4798-a9bf-28acabf6f1bd FLY P1 FLY P1 1492896401210
NA 2017 Spring Split na_2017_spring_playoffs third-place FLY|P1|G3|1f6dde12e36f4fc892c5 505f9eb8-f117-4991-9f9d-f2a166f4251a FLY P1 FLY P1 1492900091754
NA 2017 Spring Split na_2017_spring_playoffs third-place FLY|P1|G4|1f6dde12e36f4fc892c5 b4eed852-8b62-4bf6-b939-b6c08ca40c76 FLY P1 P1 FLY 1492904474682
NA 2017 Spring Split na_2017_spring_playoffs third-place FLY|P1|G5|1f6dde12e36f4fc892c5 6d385a89-c944-41f8-911e-a04764f4d0a2 P1 FLY P1 FLY 1492908605103
NA 2017 Spring Split na_2017_spring_playoffs semi-final-1 C9|P1|G1|572abd437a1b44d58f08d b4dfa948-7384-4bbb-addc-b32b87d37f6d C9 P1 C9 P1 1492286500415
NA 2017 Spring Split na_2017_spring_playoffs semi-final-1 C9|P1|G2|572abd437a1b44d58f08d f12c5587-9f19-4d9f-988d-42624e2b0096 C9 P1 C9 P1 1492292976027
NA 2017 Spring Split na_2017_spring_playoffs semi-final-1 C9|P1|G3|572abd437a1b44d58f08d 803a479b-9e83-4062-a26a-9cab35d8e3a7 P1 C9 C9 P1 1492298315769
NA 2017 Spring Split na_2017_spring_playoffs grand-final C9|TSM|G1|ec687c28a2db44259af0 c0c503fa-48e1-42d8-9c6c-2f0fcd7b17b1 C9 TSM TSM C9 1492980301092
NA 2017 Spring Split na_2017_spring_playoffs grand-final C9|TSM|G2|ec687c28a2db44259af0 1a54717e-d39c-4fce-8de1-8d3bda1cc293 TSM C9 TSM C9 1492984171553
NA 2017 Spring Split na_2017_spring_playoffs grand-final C9|TSM|G3|ec687c28a2db44259af0 aedfc6fa-a01d-4851-9829-5802be340d10 C9 TSM C9 TSM 1492989198519
NA 2017 Spring Split na_2017_spring_playoffs grand-final C9|TSM|G4|ec687c28a2db44259af0 70c8e466-a161-4121-8c6e-13d29cb728e2 TSM C9 C9 TSM 1492991234556
NA 2017 Spring Split na_2017_spring_playoffs grand-final C9|TSM|G5|ec687c28a2db44259af0 f012f948-d064-4557-b466-1064db348b24 C9 TSM TSM C9 1492996136072
NA 2017 Spring Split na_2017_spring_playoffs quarter-final-1 DIG|P1|G1|4ace0de3e5874240affc 3c54e9bf-da32-4be6-a19d-abd0c9a151d0 DIG P1 P1 DIG 1491693156297
NA 2017 Spring Split na_2017_spring_playoffs quarter-final-1 DIG|P1|G2|4ace0de3e5874240affc 2e213479-cd17-465c-a4b1-845e0ff89460 P1 DIG P1 DIG 1491695777869
NA 2017 Spring Split na_2017_spring_playoffs quarter-final-1 DIG|P1|G3|4ace0de3e5874240affc 0a6737d5-b92c-4f0f-b099-6c7085ba8829 DIG P1 P1 DIG 1491699501318
NA 2017 Spring Split regular_season TL-vs-DIG DIG|TL|G1|09a7d6ae860e4f33a61d 7d8bf41d-0a60-4c2c-9898-863cf1eb2093 TL DIG TL DIG 1487458456464
NA 2017 Spring Split regular_season TL-vs-DIG DIG|TL|G2|09a7d6ae860e4f33a61d f750dff3-0fc8-437d-bdd5-37afd9d04e04 DIG TL DIG TL 1487461635327
NA 2017 Spring Split regular_season TL-vs-DIG DIG|TL|G3|09a7d6ae860e4f33a61d 106ba94f-1be5-42e1-8f0b-c7c52fba0930 TL DIG DIG TL 1487465568512
NA 2017 Spring Split regular_season FLY-vs-IMT FLY|IMT|G1|342754eb2dee43079f9 09cc084f-1c2a-4467-8c46-4464819be258 FLY IMT IMT FLY 1489280388739
NA 2017 Spring Split regular_season FLY-vs-IMT FLY|IMT|G2|342754eb2dee43079f9 41cc88f4-66c7-436f-8056-ded1beb5165e IMT FLY IMT FLY 1489279402260
NA 2017 Spring Split regular_season IMT-vs-TSM IMT|TSM|G1|7386a945fa7141669c7 c4d95853-516d-4968-b645-198a30a3995a IMT TSM IMT TSM 1489363365121
NA 2017 Spring Split regular_season IMT-vs-TSM IMT|TSM|G2|7386a945fa7141669c7 84c80583-8199-445e-b538-69dd5665d32a TSM IMT TSM IMT 1489369426420
NA 2017 Spring Split regular_season IMT-vs-TSM IMT|TSM|G3|7386a945fa7141669c7 3d0c02b5-86fc-4ca7-a710-16822b3d350b IMT TSM TSM IMT 1489376073440
NA 2017 Spring Split regular_season DIG-vs-C9 C9|DIG|G1|74430344e4fd43e3b618 403eb82c-16a9-40c3-9faa-9cea4b287f2c DIG C9 C9 DIG 1485132582587
NA 2017 Spring Split regular_season DIG-vs-C9 C9|DIG|G2|74430344e4fd43e3b618 01ff339f-8953-4d58-bf6a-96538a898d04 C9 DIG DIG C9 1485143545154
NA 2017 Spring Split regular_season DIG-vs-C9 C9|DIG|G3|74430344e4fd43e3b618 29065c53-7a3a-4543-9624-d021bb762df5 DIG C9 C9 DIG 1485148469603
NA 2017 Spring Split regular_season FOX-vs-TSM FOX|TSM|G1|299c941d3c644c66bfd 16b5635a-57b0-4645-bd4c-a4d51307baeb FOX TSM FOX TSM 1486938267223
NA 2017 Spring Split regular_season FOX-vs-TSM FOX|TSM|G2|299c941d3c644c66bfd da0481b0-a151-490f-b77c-625e24ebc6d0 TSM FOX FOX TSM 1486942680275
NA 2017 Spring Split regular_season TL-vs-NV NV|TL|G1|190e410c891a44b7a0cf9 dc90e703-4fe1-4d60-b98d-4291443fd156 TL NV TL NV 1489365023706
NA 2017 Spring Split regular_season TL-vs-NV NV|TL|G2|190e410c891a44b7a0cf9 e7555d68-61ec-4650-83c9-926b8ad63985 NV TL NV TL 1489367083544
NA 2017 Spring Split regular_season TL-vs-NV NV|TL|G3|190e410c891a44b7a0cf9 71e69a7d-9bb7-4a83-b2ae-292f093f52ed TL NV TL NV 1489373982147
NA 2017 Spring Split regular_season TSM-vs-FLY FLY|TSM|G1|20c8e6d688814852999 fcfe7e96-3861-4ab3-9510-7445e7b49a41 TSM FLY FLY TSM 1489878562292
NA 2017 Spring Split regular_season TSM-vs-FLY FLY|TSM|G2|20c8e6d688814852999 85161db8-aa5b-401c-8114-3f99a47df268 FLY TSM TSM FLY 1489882194543
NA 2017 Spring Split regular_season TSM-vs-FLY FLY|TSM|G3|20c8e6d688814852999 89eeceb9-924f-4920-94dc-51aafedb0c39 TSM FLY TSM FLY 1489885591422
NA 2017 Spring Split regular_season TSM-vs-FOX FOX|TSM|G1|97ba60548d454f0c856 723d54c1-31aa-4e03-9276-0e72d2543987 TSM FOX TSM FOX 1489955845513
NA 2017 Spring Split regular_season TSM-vs-FOX FOX|TSM|G2|97ba60548d454f0c856 b2be46c1-e141-4e5f-8028-be9671f928ea FOX TSM TSM FOX 1489959177427
NA 2017 Spring Split regular_season IMT-vs-C9 C9|IMT|G1|b80127e8aa414f8dab44 bd9bb0d4-d9aa-45a7-bd1e-a0e579e7d142 IMT C9 C9 IMT 1485642080361
NA 2017 Spring Split regular_season IMT-vs-C9 C9|IMT|G2|b80127e8aa414f8dab44 0e6ac0ec-21ed-4205-a616-9cfae5d9eb63 C9 IMT C9 IMT 1485644019423
NA 2017 Spring Split regular_season FLY-vs-C9 C9|FLY|G1|73f1ac9e5b114062ab97 d050820a-bffe-47e8-a70f-5452b3e7a9b1 FLY C9 C9 FLY 1486950845674
NA 2017 Spring Split regular_season FLY-vs-C9 C9|FLY|G2|73f1ac9e5b114062ab97 a547a5b6-cf0e-40fd-a0a5-4d0e73e4d155 C9 FLY FLY C9 1486954307523
NA 2017 Spring Split regular_season FLY-vs-C9 C9|FLY|G3|73f1ac9e5b114062ab97 5e8b9a63-052f-4960-b9fa-a60c74c17054 FLY C9 C9 FLY 1487272210569
NA 2017 Spring Split regular_season DIG-vs-NV DIG|NV|G1|0249798db255482fb67e 74cd8c46-e63c-4db1-9868-9b2d5e7d5382 DIG NV DIG NV 1486944784126
NA 2017 Spring Split regular_season DIG-vs-NV DIG|NV|G2|0249798db255482fb67e b3da2d46-ba0a-49b0-b333-af1a60219afb NV DIG DIG NV 1486948933511
NA 2017 Spring Split regular_season FLY-vs-TL FLY|TL|G1|6fbebf64667d4a7dbbca 581cb316-6868-4599-9660-7b599e607a87 FLY TL TL FLY 1490569975187
NA 2017 Spring Split regular_season FLY-vs-TL FLY|TL|G2|6fbebf64667d4a7dbbca aa3c6a8a-c901-4084-a601-e1f5f38e6de1 TL FLY FLY TL 1490571506177
NA 2017 Spring Split regular_season FLY-vs-TL FLY|TL|G3|6fbebf64667d4a7dbbca 17a51013-081c-4f00-bcda-09b07315c9f0 FLY TL FLY TL 1490575129060
NA 2017 Spring Split regular_season FLY-vs-CLG CLG|FLY|G1|3d6148c2139446ffa0d 33d653e4-b691-4fbe-9685-6a5f40a057f1 FLY CLG FLY CLG 1485561956089
NA 2017 Spring Split regular_season FLY-vs-CLG CLG|FLY|G2|3d6148c2139446ffa0d f0eaa5b5-3057-4361-9287-2f60ddf18236 CLG FLY FLY CLG 1485570488887
NA 2017 Spring Split regular_season P1-vs-NV NV|P1|G1|d5ad4bd15e234b1db6504 743f8560-9ae0-4639-89ff-31ace1906311 P1 NV P1 NV 1485637263303
NA 2017 Spring Split regular_season P1-vs-NV NV|P1|G2|d5ad4bd15e234b1db6504 61492c1d-6f0c-4185-a937-b4d2f67a3635 NV P1 P1 NV 1485644031701
NA 2017 Spring Split regular_season CLG-vs-TL CLG|TL|G1|5a73c99162574d789514 89c9d0ce-4d0c-49b7-8df5-7dcf3ba5b245 CLG TL TL CLG 1485056435380
NA 2017 Spring Split regular_season CLG-vs-TL CLG|TL|G2|5a73c99162574d789514 5f95d014-a5ea-47c4-b79c-78250371d888 TL CLG TL CLG 1485056362690
NA 2017 Spring Split regular_season CLG-vs-DIG CLG|DIG|G1|66a83f1bdd3b4a40aec f5721d47-9936-486e-842a-cb70fef16bf3 CLG DIG DIG CLG 1489268384337
NA 2017 Spring Split regular_season CLG-vs-DIG CLG|DIG|G2|66a83f1bdd3b4a40aec 68dff45b-6149-4c6e-8949-a35db57efc7d DIG CLG DIG CLG 1489273545535
NA 2017 Spring Split regular_season TSM-vs-P1 P1|TSM|G1|54880e91256e456f99d9 f5866cfb-dd57-46f5-80f6-60118cac1f5f TSM P1 TSM P1 1490560972748
NA 2017 Spring Split regular_season TSM-vs-P1 P1|TSM|G2|54880e91256e456f99d9 0da0fc03-a5a1-44b9-8627-c8b12874daaa P1 TSM TSM P1 1490561423259
NA 2017 Spring Split regular_season DIG-vs-FOX DIG|FOX|G1|573b039963884594955 81f613e9-b21c-4580-bc15-ef226ccb91b5 DIG FOX DIG FOX 1485643513330
NA 2017 Spring Split regular_season DIG-vs-FOX DIG|FOX|G2|573b039963884594955 095aa7cc-12ee-4b18-be92-996b41f8d2fc FOX DIG FOX DIG 1485653073248
NA 2017 Spring Split regular_season DIG-vs-FOX DIG|FOX|G3|573b039963884594955 502ac678-a580-44fe-89a4-c94dd7d909d9 DIG FOX FOX DIG 1485726311079
NA 2017 Spring Split regular_season DIG-vs-TL DIG|TL|G1|2c1919bd665247acaa6a 6325ca6d-62c5-4a4f-9e0a-9f396cfff97c DIG TL DIG TL 1489794453761
NA 2017 Spring Split regular_season DIG-vs-TL DIG|TL|G2|2c1919bd665247acaa6a 583d1a49-ed8d-414a-b809-cf4b37e1d229 TL DIG DIG TL 1489802951763
NA 2017 Spring Split regular_season FLY-vs-P1 FLY|P1|G1|9e0b60749cf9418c9c8b e25e35bf-1f30-4be5-93bb-627fbea93efa FLY P1 P1 FLY 1489197331628
NA 2017 Spring Split regular_season FLY-vs-P1 FLY|P1|G2r2|9e0b60749cf9418c9c 564c4425-0d77-4dbb-8ded-1a34d6402811 P1 FLY P1 FLY 1489202386590
NA 2017 Spring Split regular_season TSM-vs-NV NV|TSM|G1|173f1155b78d4fe8a4b0 39fbdc8b-be88-4219-972b-47cab9f66a29 TSM NV TSM NV 1486856557647
NA 2017 Spring Split regular_season TSM-vs-NV NV|TSM|G2|173f1155b78d4fe8a4b0 8c03a1f3-90e4-4333-8410-1fe3f18f7303 NV TSM TSM NV 1486861793439
NA 2017 Spring Split regular_season P1-vs-C9 C9|P1|G1|0aa8bf45a8c24a3ab04e4 b957bfb2-802a-444a-b130-c4fb83cc0b42 P1 C9 P1 C9 1487554907233
NA 2017 Spring Split regular_season P1-vs-C9 C9|P1|G2|0aa8bf45a8c24a3ab04e4 15dab9f2-9fb9-4754-8370-defa38371701 C9 P1 P1 C9 1487559148487
NA 2017 Spring Split regular_season NV-vs-IMT IMT|NV|G1|2634671c562749df9947 ad2d7a57-3320-4ff1-a9f4-b19427015e46 NV IMT NV IMT 1485733560305
NA 2017 Spring Split regular_season NV-vs-IMT IMT|NV|G2|2634671c562749df9947 efe6bb37-33f9-4450-9958-36adcaec5943 IMT NV IMT NV 1485740020517
NA 2017 Spring Split regular_season NV-vs-IMT IMT|NV|G3|2634671c562749df9947 69a399ad-f1bd-4d0c-ba1f-e7d737f9251b NV IMT IMT NV 1485740032851
NA 2017 Spring Split regular_season FOX-vs-DIG DIG|FOX|G1|5017acc5b8d1443cb1d 46329b54-3eca-444d-abbe-976f3a361099 FOX DIG FOX DIG 1489355424378
NA 2017 Spring Split regular_season FOX-vs-DIG DIG|FOX|G2|5017acc5b8d1443cb1d 9dca18d4-0bd1-4cf9-ae45-99543ea1dc7b DIG FOX DIG FOX 1489358414564
NA 2017 Spring Split regular_season FOX-vs-DIG DIG|FOX|G3|5017acc5b8d1443cb1d e7fef099-a085-48c3-9782-76ea6a9593ab FOX DIG DIG FOX 1489361234862
NA 2017 Spring Split regular_season CLG-vs-NV CLG|NV|G1|a61fe05391a24ef3b2ef 8187747e-103e-4455-9bfb-08bf2d0a39eb CLG NV NV CLG 1490846302178
NA 2017 Spring Split regular_season CLG-vs-NV CLG|NV|G2|a61fe05391a24ef3b2ef 2352a1bc-2be3-497f-9107-c335055ba1cc NV CLG CLG NV 1490846305358
NA 2017 Spring Split regular_season CLG-vs-NV CLG|NV|G3|a61fe05391a24ef3b2ef a4b7526b-0730-4ca2-8cd0-cbffc58cfa36 CLG NV CLG NV 1490846309088
NA 2017 Spring Split regular_season C9-vs-TSM C9|TSM|G1|3a777c77c3d847688b6c 4578c2a2-0549-4b16-bc43-ab64ddbd98bb C9 TSM TSM C9 1487467875199
NA 2017 Spring Split regular_season C9-vs-TSM C9|TSM|G2|3a777c77c3d847688b6c 75544c4d-6e9a-4c37-9b5e-2020ab042d8b TSM C9 C9 TSM 1487471853940
NA 2017 Spring Split regular_season C9-vs-TSM C9|TSM|G3|3a777c77c3d847688b6c 277897c7-cf07-4703-83f7-49fe18586361 C9 TSM TSM C9 1487475953878
NA 2017 Spring Split regular_season CLG-vs-TSM CLG|TSM|G1|bf6cf98e7eaa4155b0a 2c75ddad-d5fc-450c-93f8-072fe03591c3 CLG TSM CLG TSM 1486247187507
NA 2017 Spring Split regular_season CLG-vs-TSM CLG|TSM|G2|bf6cf98e7eaa4155b0a c7f86ea2-cb56-4038-b7c3-96af4244fe62 TSM CLG TSM CLG 1486248551879
NA 2017 Spring Split regular_season CLG-vs-TSM CLG|TSM|G3|bf6cf98e7eaa4155b0a 857682f3-a25c-4b26-a05f-c3cdd58662d0 CLG TSM TSM CLG 1486253072538
NA 2017 Spring Split regular_season IMT-vs-DIG DIG|IMT|G1|ce44105d106b4f4da5a 04adcc17-465a-4a13-81c4-fae6e24972f4 IMT DIG IMT DIG 1486789050473
NA 2017 Spring Split regular_season IMT-vs-DIG DIG|IMT|G2|ce44105d106b4f4da5a 6e7efdb5-a4da-450b-bfd2-3a7a584979f9 DIG IMT IMT DIG 1486792525461
NA 2017 Spring Split regular_season C9-vs-TL C9|TL|G1|430d7a755e5c4151ba020 bc0c5a5d-36c6-46a2-a35a-55404ff45e2d C9 TL C9 TL 1486778211965
NA 2017 Spring Split regular_season C9-vs-TL C9|TL|G2|430d7a755e5c4151ba020 502ae7d5-d159-4a12-bf85-6b511170494a TL C9 TL C9 1486779060971
NA 2017 Spring Split regular_season C9-vs-TL C9|TL|G3|430d7a755e5c4151ba020 daf684c6-7fcf-4070-b711-af4e7af9c9e4 C9 TL C9 TL 1486783870810
NA 2017 Spring Split regular_season C9-vs-P1 C9|P1|G1|84f80468449146f88b7f3 cb49490b-7d3c-4e37-b3f8-e417c0c61bf5 C9 P1 C9 P1 1490481893734
NA 2017 Spring Split regular_season C9-vs-P1 C9|P1|G2|84f80468449146f88b7f3 b156d341-7c6d-4043-8b90-1033f0e1d56d P1 C9 C9 P1 1490486475824
NA 2017 Spring Split regular_season TL-vs-IMT IMT|TL|G1|7158ff6b3d6046ec913f a04c0c5a-2f6b-4979-9429-a53bf128d9e9 TL IMT IMT TL 1486866020839
NA 2017 Spring Split regular_season TL-vs-IMT IMT|TL|G2|7158ff6b3d6046ec913f dd0d74d8-5110-48b8-97bb-d55f23defb13 IMT TL IMT TL 1486866028017
NA 2017 Spring Split regular_season TL-vs-TSM TL|TSM|G1|f6618782921748f5b086 f7a41f68-1a93-488d-9b49-d9d67918951a TL TSM TL TSM 1490475914606
NA 2017 Spring Split regular_season TL-vs-TSM TL|TSM|G2|f6618782921748f5b086 bb9f492c-c0fe-4bf5-9b2f-0b89afa15842 TSM TL TSM TL 1490478806811
NA 2017 Spring Split regular_season TL-vs-TSM TL|TSM|G3|f6618782921748f5b086 53aacdea-4566-4a18-b5bf-0f4f6ac4234e TL TSM TL TSM 1490481650913
NA 2017 Spring Split regular_season C9-vs-FOX C9|FOX|G1|787044525a144bef9a64 cc032c70-a30b-4229-bd11-a5908e3f4041 C9 FOX C9 FOX 1486342431485
NA 2017 Spring Split regular_season C9-vs-FOX C9|FOX|G2|787044525a144bef9a64 a37326d7-a72b-4e2b-b7ce-fe5f1ef88e44 FOX C9 C9 FOX 1486346568711
NA 2017 Spring Split regular_season P1-vs-FOX FOX|P1|G1|7ea15e933b6e4b72913e 5a3649f1-0bba-4f6d-9d4d-068ff4f2e21c P1 FOX P1 FOX 1489284026149
NA 2017 Spring Split regular_season P1-vs-FOX FOX|P1|G2|7ea15e933b6e4b72913e 8390fd4d-854b-439c-a6a9-6b64b69460f7 FOX P1 P1 FOX 1489279461529
NA 2017 Spring Split regular_season NV-vs-DIG DIG|NV|G1|d27e738bd1e04c95b8c3 fffc6a2b-2364-41b9-9359-69a76f551054 NV DIG DIG NV 1489867171990
NA 2017 Spring Split regular_season NV-vs-DIG DIG|NV|G2|d27e738bd1e04c95b8c3 3d1f55b6-4770-4330-8e07-f0cde9d742cd DIG NV NV DIG 1489871090131
NA 2017 Spring Split regular_season NV-vs-DIG DIG|NV|G3|d27e738bd1e04c95b8c3 f828adc0-46f6-4c1c-97ae-36c7220c1ff8 NV DIG DIG NV 1489878437150
NA 2017 Spring Split regular_season DIG-vs-TSM DIG|TSM|G1|25cd26dab3f34814a03 54d2d26e-7bcb-49e5-a223-5f43f3a1dd2b DIG TSM TSM DIG 1488752602032
NA 2017 Spring Split regular_season DIG-vs-TSM DIG|TSM|G2|25cd26dab3f34814a03 9e0878ab-2db5-4263-98ef-23c8f8ea05ba TSM DIG TSM DIG 1488759344326
NA 2017 Spring Split regular_season FOX-vs-FLY FLY|FOX|G1|1dd359739bf74f33aae db9024c9-d524-4abe-bab1-c94417d74b09 FOX FLY FOX FLY 1485729421062
NA 2017 Spring Split regular_season FOX-vs-FLY FLY|FOX|G2|1dd359739bf74f33aae 453d75cc-a158-4c58-8f3f-fa7ca645a184 FLY FOX FLY FOX 1485730822506
NA 2017 Spring Split regular_season FOX-vs-FLY FLY|FOX|G3|1dd359739bf74f33aae d6fe58a3-121a-41c7-863b-1f80c93aba44 FOX FLY FOX FLY 1485729374919
NA 2017 Spring Split regular_season FOX-vs-P1 FOX|P1|G1|e9efd19afc8b43be9eeb 9d777218-d4f6-47b3-844b-6a8cc8fb9c6b FOX P1 P1 FOX 1484971190146
NA 2017 Spring Split regular_season FOX-vs-P1 FOX|P1|G2|e9efd19afc8b43be9eeb 4afec057-7527-42e1-bf56-68a79040ed9f P1 FOX P1 FOX 1484974578337
NA 2017 Spring Split regular_season CLG-vs-IMT CLG|IMT|G1|207a25b57811427cbb9 a0c9830c-5be7-460a-944b-01bdec2c808d CLG IMT CLG IMT 1487450707951
NA 2017 Spring Split regular_season CLG-vs-IMT CLG|IMT|G2|207a25b57811427cbb9 9aea9e0c-bbf1-4d3e-8346-d42fa82ea57a IMT CLG IMT CLG 1487460725017
NA 2017 Spring Split regular_season CLG-vs-IMT CLG|IMT|G3|207a25b57811427cbb9 56855c3e-b017-48d8-9679-0c10ec2d4268 CLG IMT CLG IMT 1487464375533
NA 2017 Spring Split regular_season CLG-vs-FLY CLG|FLY|G1|8f87deaf9cd64787b11 2735513a-ddac-4298-977d-45c2405517ca CLG FLY CLG FLY 1489962855342
NA 2017 Spring Split regular_season CLG-vs-FLY CLG|FLY|G2|8f87deaf9cd64787b11 9be574cc-c0de-49ac-be61-30ca59315b38 FLY CLG CLG FLY 1489966421298
NA 2017 Spring Split regular_season TL-vs-P1 P1|TL|G1|64c639ee2ef24164a17e2 27174b5d-97fd-4a19-b9b9-8965e521aef8 TL P1 P1 TL 1489883649914
NA 2017 Spring Split regular_season TL-vs-P1 P1|TL|G2|64c639ee2ef24164a17e2 96ba4783-63c8-49e2-9ca9-a3c13a1c35d9 P1 TL P1 TL 1489885307457
NA 2017 Spring Split regular_season P1-vs-TL P1|TL|G1|348fd81f26a24bdcaa74e 36477602-8002-4231-b29a-f03ff1e7cf95 P1 TL P1 TL 1485729411250
NA 2017 Spring Split regular_season P1-vs-TL P1|TL|G2|348fd81f26a24bdcaa74e f686ea5a-523e-4b74-96a5-e91812e4e91e TL P1 P1 TL 1485730837582
NA 2017 Spring Split regular_season DIG-vs-CLG CLG|DIG|G1|74f90cc985f94736807 e4665715-2d64-4f6e-bfa0-1f20279b4c9b DIG CLG CLG DIG 1486336054319
NA 2017 Spring Split regular_season DIG-vs-CLG CLG|DIG|G2|74f90cc985f94736807 22b23915-4ab2-47ea-b40f-98b0f6a40522 CLG DIG CLG DIG 1486333090794
NA 2017 Spring Split regular_season CLG-vs-FOX CLG|FOX|G1|d95a2760bb894c088c4 6bb1e727-beea-4386-9496-874b32f60b6e CLG FOX FOX CLG 1486855624655
NA 2017 Spring Split regular_season CLG-vs-FOX CLG|FOX|G2|d95a2760bb894c088c4 7319f6a7-7d7e-4488-b5ca-66b20d87bc04 FOX CLG FOX CLG 1486855637456
NA 2017 Spring Split regular_season TSM-vs-IMT IMT|TSM|G1|94a25891bc6340ad8ad 490819ed-b3ba-41a5-bfdf-cae8be47816b TSM IMT TSM IMT 1485129104433
NA 2017 Spring Split regular_season TSM-vs-IMT IMT|TSM|G2|94a25891bc6340ad8ad 153b2f8e-29ef-4c32-a37b-47d920352bc4 IMT TSM IMT TSM 1485124258059
NA 2017 Spring Split regular_season TSM-vs-IMT IMT|TSM|G3|94a25891bc6340ad8ad 2dec5c09-f2ee-4d9e-a26f-861a8a9afb96 TSM IMT TSM IMT 1485127450627
NA 2017 Spring Split regular_season FOX-vs-CLG CLG|FOX|G1|ad39feebcf5c4872b33 ca8a3dcc-bb29-4a5f-83e2-1c83e01ea6b4 FOX CLG CLG FOX 1489801915205
NA 2017 Spring Split regular_season FOX-vs-CLG CLG|FOX|G2|ad39feebcf5c4872b33 b6c88759-80f6-4862-bdd8-a9338dfde28d CLG FOX CLG FOX 1489805897627
NA 2017 Spring Split regular_season TL-vs-CLG CLG|TL|G1|9d66e888013e4c5a9b33 206d3bfd-4215-4c07-b62a-49d4160e1142 TL CLG TL CLG 1487547000956
NA 2017 Spring Split regular_season TL-vs-CLG CLG|TL|G2|9d66e888013e4c5a9b33 685e3f82-2530-41ee-8f47-1ded7e631e6c CLG TL CLG TL 1487550451807
NA 2017 Spring Split regular_season TL-vs-CLG CLG|TL|G3|9d66e888013e4c5a9b33 0d7f4c1e-3d0b-4242-928d-9562147c30c3 TL CLG CLG TL 1487550456688
NA 2017 Spring Split regular_season IMT-vs-TL IMT|TL|G1|abc2e86cc89d476bafa3 8227aad3-d7a6-48f9-b2a5-92f12a37fd8e IMT TL IMT TL 1488593473405
NA 2017 Spring Split regular_season IMT-vs-TL IMT|TL|G2|abc2e86cc89d476bafa3 52e1971f-c865-4359-b79d-2eaef8e3d46f TL IMT TL IMT 1488593485761
NA 2017 Spring Split regular_season IMT-vs-TL IMT|TL|G3|abc2e86cc89d476bafa3 8e0933ff-e996-453c-b59d-14c9e864e07b IMT TL TL IMT 1488596657976
NA 2017 Spring Split regular_season P1-vs-FLY FLY|P1|G1|d087063dec3e4339ad5c 4d841de0-91c6-4792-b0c1-42ae64bc017d P1 FLY FLY P1 1486855659084
NA 2017 Spring Split regular_season P1-vs-FLY FLY|P1|G2|d087063dec3e4339ad5c 802bc61a-8a2e-46e8-aa85-517a80a694af FLY P1 FLY P1 1486855669094
NA 2017 Spring Split regular_season IMT-vs-CLG CLG|IMT|G1|2a4792f1cd464bff84f 2097bf22-2039-4bf5-93bf-e8933070f2b7 IMT CLG IMT CLG 1490475918520
NA 2017 Spring Split regular_season IMT-vs-CLG CLG|IMT|G2|2a4792f1cd464bff84f 8599de3a-fa84-4557-8563-5436e727a88f CLG IMT IMT CLG 1490478805022
NA 2017 Spring Split regular_season DIG-vs-FLY DIG|FLY|G1|9179903ba6e5477c830 c7b58061-4d13-45c2-aaef-07b45c30f405 DIG FLY DIG FLY 1487381919043
NA 2017 Spring Split regular_season DIG-vs-FLY DIG|FLY|G2|9179903ba6e5477c830 a6cbd67e-97a0-44c6-a87e-d5151812fbc9 FLY DIG DIG FLY 1487383685181
NA 2017 Spring Split regular_season IMT-vs-NV IMT|NV|G1|2f82eff44b2d439388ac f9344ccf-2671-4c27-a20e-93b050344156 IMT NV IMT NV 1488761393646
NA 2017 Spring Split regular_season IMT-vs-NV IMT|NV|G2|2f82eff44b2d439388ac 8ab57616-76db-4234-bdcf-15fa48736863 NV IMT NV IMT 1488766835288
NA 2017 Spring Split regular_season IMT-vs-NV IMT|NV|G3|2f82eff44b2d439388ac f416f70c-fc35-4d38-8272-ff58e1e5176f IMT NV NV IMT 1488769188824
NA 2017 Spring Split regular_season FOX-vs-IMT FOX|IMT|G1|e35a9ecec8754d44990 46da01a9-b1dc-4880-b7e5-8acc79d37c29 FOX IMT FOX IMT 1485056394039
NA 2017 Spring Split regular_season FOX-vs-IMT FOX|IMT|G2|e35a9ecec8754d44990 cba4661c-29a0-4567-9f7b-81636b16b18d IMT FOX IMT FOX 1485062433177
NA 2017 Spring Split regular_season FOX-vs-IMT FOX|IMT|G3|e35a9ecec8754d44990 b8c7043f-947e-4ef5-9e13-7a384cae07b0 FOX IMT IMT FOX 1485059589034
NA 2017 Spring Split regular_season FLY-vs-TSM FLY|TSM|G1|bbbad7032f404b4db9a 387b0cee-f26c-4722-8809-70ce33ccd163 FLY TSM TSM FLY 1487543895105
NA 2017 Spring Split regular_season FLY-vs-TSM FLY|TSM|G2|bbbad7032f404b4db9a d7938115-bb44-4bb7-8e08-cebb01d76c87 TSM FLY FLY TSM 1487545198924
NA 2017 Spring Split regular_season FLY-vs-TSM FLY|TSM|G3|bbbad7032f404b4db9a f9b1026a-da44-437e-9f44-9b94a2be0ff3 FLY TSM TSM FLY 1487550424147
NA 2017 Spring Split regular_season CLG-vs-P1 CLG|P1|G1|0c25ff11f7214a0da84d 56aa6c27-a8ce-4a45-a59c-eff6f598b2e2 CLG P1 CLG P1 1486939391494
NA 2017 Spring Split regular_season CLG-vs-P1 CLG|P1|G2|0c25ff11f7214a0da84d 8859a289-f97a-485f-a0f9-4129096c9c8d P1 CLG P1 CLG 1486942669548
NA 2017 Spring Split regular_season CLG-vs-P1 CLG|P1|G3|0c25ff11f7214a0da84d f2420931-b66f-4336-9de3-6c5d65e6f76c CLG P1 CLG P1 1486947467338
NA 2017 Spring Split regular_season IMT-vs-P1 IMT|P1|G1|02a5b7b265cd418ebd27 e85f8d78-e426-452a-b7d7-d4bcc178516d IMT P1 P1 IMT 1486177287360
NA 2017 Spring Split regular_season IMT-vs-P1 IMT|P1|G2|02a5b7b265cd418ebd27 9524419d-df54-4704-a156-3682bebe9e2d P1 IMT P1 IMT 1486178683633
NA 2017 Spring Split regular_season FOX-vs-TL FOX|TL|G1|b11e8051a2ab4f61a7f8 76963e0a-33e8-4168-b1ad-f98d05c9bc99 FOX TL FOX TL 1488752622852
NA 2017 Spring Split regular_season FOX-vs-TL FOX|TL|G2|b11e8051a2ab4f61a7f8 852aa8b5-7a8f-448f-844c-0900779d90b8 TL FOX TL FOX 1488759361063
NA 2017 Spring Split regular_season FOX-vs-TL FOX|TL|G3|b11e8051a2ab4f61a7f8 f2202f89-370c-4c64-8972-d7a8ff4b0514 FOX TL FOX TL 1488754266459
NA 2017 Spring Split regular_season TL-vs-FLY FLY|TL|G1|f1ce0d20380a454e8348 f6fe121c-a0d3-480f-bfc2-2619857f656f TL FLY TL FLY 1485135580059
NA 2017 Spring Split regular_season TL-vs-FLY FLY|TL|G2|f1ce0d20380a454e8348 34534066-6dfa-4943-ae7c-0e848ede5de9 FLY TL FLY TL 1485138627635
NA 2017 Spring Split regular_season TL-vs-FLY FLY|TL|G3|f1ce0d20380a454e8348 5b195e31-81cb-4749-a46e-0348aeb25fe6 TL FLY FLY TL 1485138646434
NA 2017 Spring Split regular_season C9-vs-NV C9|NV|G1|bc12053c0c70484886bb9 48075274-99f7-44d7-867e-e659a8304ede C9 NV C9 NV 1486254078989
NA 2017 Spring Split regular_season C9-vs-NV C9|NV|G2|bc12053c0c70484886bb9 1631fc5a-385f-47f0-a105-77bdfb0796cc NV C9 C9 NV 1486258714859
NA 2017 Spring Split regular_season TSM-vs-TL TL|TSM|G1|34e9f621d40d43898a5a fc449420-cd4d-4659-98cd-8b6a3e567086 TSM TL TSM TL 1485650531590
NA 2017 Spring Split regular_season TSM-vs-TL TL|TSM|G2|34e9f621d40d43898a5a b8a8a29c-c1d1-47bb-a8c1-5b8e2b524d0c TL TSM TL TSM 1485651761814
NA 2017 Spring Split regular_season TSM-vs-TL TL|TSM|G3|34e9f621d40d43898a5a 98d8cd79-6d97-4251-a540-d3f9414d71ae TSM TL TSM TL 1485656813345
NA 2017 Spring Split regular_season FOX-vs-C9 C9|FOX|G1|4d930e0efb93494e8fa5 cc09a51c-7779-4c4d-8949-57655e081f13 FOX C9 C9 FOX 1488666862893
NA 2017 Spring Split regular_season FOX-vs-C9 C9|FOX|G2|4d930e0efb93494e8fa5 edd2495a-e296-4528-8c1d-d7e29fd10f04 C9 FOX C9 FOX 1488667924012
NA 2017 Spring Split regular_season NV-vs-C9 C9|NV|G1|e8912bb34d3843479555f a29bb516-42de-4e53-8712-f9f8f7bd1d47 NV C9 NV C9 1489963302765
NA 2017 Spring Split regular_season NV-vs-C9 C9|NV|G2|e8912bb34d3843479555f bae333e1-98af-4f9b-994a-3eaca40eb4e7 C9 NV C9 NV 1489964074717
NA 2017 Spring Split regular_season NV-vs-C9 C9|NV|G3|e8912bb34d3843479555f a4e5e9fa-88c6-45f8-89f2-50cd1c9a5ad9 NV C9 C9 NV 1489974675593
NA 2017 Spring Split regular_season NV-vs-TSM NV|TSM|G1|a4472986bb584ccfb582 6bdc228f-79fa-4bf8-89af-68386d6dfcfe NV TSM NV TSM 1489268987535
NA 2017 Spring Split regular_season NV-vs-TSM NV|TSM|G2|a4472986bb584ccfb582 470c0c77-7327-4528-9cf9-8bc2ee0c2a00 TSM NV TSM NV 1489280168918
NA 2017 Spring Split regular_season NV-vs-TSM NV|TSM|G3|a4472986bb584ccfb582 60f7ffb9-ab4e-4417-bb0f-95e3e7b78aa3 NV TSM TSM NV 1489280272428
NA 2017 Spring Split regular_season DIG-vs-IMT DIG|IMT|G1|05011086bc5d470a930 4a9ba14f-1f2f-4903-aa23-0bf0ec5ce762 DIG IMT DIG IMT 1490564980970
NA 2017 Spring Split regular_season DIG-vs-IMT DIG|IMT|G2|05011086bc5d470a930 020c132b-ab33-490c-819b-f440a0e9b891 IMT DIG DIG IMT 1490568759185
NA 2017 Spring Split regular_season P1-vs-DIG DIG|P1|G1|99c3a045a51a4deb8357 1e8865b0-06eb-4e96-a54d-686c7c00c9e5 P1 DIG P1 DIG 1488680021911
NA 2017 Spring Split regular_season P1-vs-DIG DIG|P1|G2|99c3a045a51a4deb8357 325911ac-28bb-45de-9758-fd7e5feab39d DIG P1 DIG P1 1488680029558
NA 2017 Spring Split regular_season P1-vs-DIG DIG|P1|G3|99c3a045a51a4deb8357 61652fa7-5094-4368-b7a2-f63a96d0de51 P1 DIG P1 DIG 1488681344034
NA 2017 Spring Split regular_season C9-vs-DIG C9|DIG|G1|1717b1ea98474720bfe5 73697ae9-ec30-4593-958c-1fc6278931c2 C9 DIG C9 DIG 1490401261097
NA 2017 Spring Split regular_season C9-vs-DIG C9|DIG|G2|1717b1ea98474720bfe5 ca18466f-58a2-4ce1-b2e0-c8df16337c54 DIG C9 C9 DIG 1490404813901
NA 2017 Spring Split regular_season P1-vs-CLG CLG|P1|G1|9d72868ce210409ea635 a4f13f19-4d1d-4482-8665-3b54b3f2b355 P1 CLG P1 CLG 1488595244437
NA 2017 Spring Split regular_season P1-vs-CLG CLG|P1|G2|9d72868ce210409ea635 b65916d5-87c6-40de-8e6e-4c3458291150 CLG P1 CLG P1 1488605837667
NA 2017 Spring Split regular_season P1-vs-CLG CLG|P1|G3|9d72868ce210409ea635 dd6a91f1-5a2e-470e-a5e6-b182acc37d9e P1 CLG CLG P1 1488601822026
NA 2017 Spring Split regular_season TL-vs-FOX FOX|TL|G1|68ea6beeea794fcfb83c 1dc4ec7d-38fc-4074-8829-09851a9ecf91 TL FOX FOX TL 1486256634932
NA 2017 Spring Split regular_season TL-vs-FOX FOX|TL|G2|68ea6beeea794fcfb83c 7180ac4d-0e94-4067-91fb-3e54a27c52e5 FOX TL TL FOX 1486262775276
NA 2017 Spring Split regular_season TL-vs-FOX FOX|TL|G3|68ea6beeea794fcfb83c de32066d-0217-48a0-8284-4f506504ada8 TL FOX TL FOX 1486269057602
NA 2017 Spring Split regular_season C9-vs-IMT C9|IMT|G1|34b4dd96a7bc4eaa8cef 5879f327-4060-436b-8ff3-636f3c0b01ea C9 IMT IMT C9 1489870242721
NA 2017 Spring Split regular_season C9-vs-IMT C9|IMT|G2|34b4dd96a7bc4eaa8cef 8fe7c27f-269a-4a45-8b01-c1d4fa596870 IMT C9 C9 IMT 1489873129534
NA 2017 Spring Split regular_season C9-vs-IMT C9|IMT|G3|34b4dd96a7bc4eaa8cef 06a587d2-e6b4-471c-a038-e77f064d04d9 C9 IMT IMT C9 1489875918538
NA 2017 Spring Split regular_season TSM-vs-C9 C9|TSM|G1|2a7e1449c49f4868a9e3 56d8b32a-23d1-4de5-a0eb-217b7fc85857 TSM C9 C9 TSM 1484964780996
NA 2017 Spring Split regular_season TSM-vs-C9 C9|TSM|G2|2a7e1449c49f4868a9e3 aca2981d-1d6e-4f8d-b366-fe69d98a56b6 C9 TSM C9 TSM 1484967591740
NA 2017 Spring Split regular_season FLY-vs-NV FLY|NV|G1|c0e7006ab88b45ceba07 6705158c-5452-494e-b439-0af3f62988ee FLY NV FLY NV 1488666875014
NA 2017 Spring Split regular_season FLY-vs-NV FLY|NV|G2|c0e7006ab88b45ceba07 a81133b9-0ab1-4e8c-83c8-5b6c77b4517f NV FLY NV FLY 1488667930559
NA 2017 Spring Split regular_season FLY-vs-NV FLY|NV|G3|c0e7006ab88b45ceba07 ef62d07c-fa3b-4553-aa3d-c94a26930577 FLY NV FLY NV 1488670631918
NA 2017 Spring Split regular_season NV-vs-FOX FOX|NV|G1|12e06bdc309a4c45ac73 16946ed4-497d-4a2d-b530-5d02a72b208f NV FOX NV FOX 1487467172625
NA 2017 Spring Split regular_season NV-vs-FOX FOX|NV|G2|12e06bdc309a4c45ac73 b3a503da-e372-4224-a6b8-ab29ae450f95 FOX NV NV FOX 1487472746711
NA 2017 Spring Split regular_season P1-vs-TSM P1|TSM|G1|947e1068272848f2b977 cf26d3e1-eb87-45cc-abfe-afa1428e1acb P1 TSM P1 TSM 1486333249054
NA 2017 Spring Split regular_season P1-vs-TSM P1|TSM|G2|947e1068272848f2b977 21a1e5b4-00e3-4ba0-ac7f-dd22b8e041c5 TSM P1 TSM P1 1486338675081
NA 2017 Spring Split regular_season P1-vs-TSM P1|TSM|G3|947e1068272848f2b977 6cb562b9-b249-484b-88c2-cc1b30acc80e P1 TSM TSM P1 1486343238578
NA 2017 Spring Split regular_season TL-vs-C9 C9|TL|G1|78f7981e947d43629ab94 cb639507-b2e9-4b27-80e2-aee4709becb8 TL C9 C9 TL 1489194013644
NA 2017 Spring Split regular_season TL-vs-C9 C9|TL|G2|78f7981e947d43629ab94 27f3ad5f-e138-49c9-bee9-060bbdc118ca C9 TL C9 TL 1489197631163
NA 2017 Spring Split regular_season FLY-vs-FOX FLY|FOX|G1|57e77a33faac45f59a8 5a556b34-99fa-49f6-997c-5af7ca5a9c11 FLY FOX FLY FOX 1490408060649
NA 2017 Spring Split regular_season FLY-vs-FOX FLY|FOX|G2|57e77a33faac45f59a8 ddab5831-a20c-4234-80d5-f179c37ac20e FOX FLY FLY FOX 1490411564657
NA 2017 Spring Split regular_season NV-vs-FLY FLY|NV|G1|332d42876c2d4534afe6 8337c5b3-53eb-497c-87c7-6805ef3ac0ed NV FLY FLY NV 1485046533232
NA 2017 Spring Split regular_season NV-vs-FLY FLY|NV|G2|332d42876c2d4534afe6 3887cd82-c47a-4110-93df-5b673408248b FLY NV FLY NV 1485047468967
NA 2017 Spring Split regular_season IMT-vs-FOX FOX|IMT|G1|6cbda9cbd8c2472f8de f5e7fc17-843f-48f2-a487-047350cb1aec IMT FOX IMT FOX 1487541922491
NA 2017 Spring Split regular_season IMT-vs-FOX FOX|IMT|G2|6cbda9cbd8c2472f8de fb1be6f9-c0f6-45c1-b97c-eab574abd26e FOX IMT IMT FOX 1487545182607
NA 2017 Spring Split regular_season CLG-vs-C9 C9|CLG|G1|e410b69b55b44b278970 bc66fdea-8016-49c1-8f99-5e068af74aef CLG C9 CLG C9 1489354011615
NA 2017 Spring Split regular_season CLG-vs-C9 C9|CLG|G2|e410b69b55b44b278970 ec0fc888-6770-4800-8172-072b098fb650 C9 CLG C9 CLG 1489356343018
NA 2017 Spring Split regular_season CLG-vs-C9 C9|CLG|G3|e410b69b55b44b278970 962abfb0-2927-4bfc-b056-aafb31dc55f6 CLG C9 CLG C9 1489361222046
NA 2017 Spring Split regular_season P1-vs-IMT IMT|P1|G1|ab7f33f347ea493190b8 4e670622-4c01-4130-b7ba-77f7831dd73d P1 IMT P1 IMT 1489955992985
NA 2017 Spring Split regular_season P1-vs-IMT IMT|P1|G2|ab7f33f347ea493190b8 69cb78a1-0ff2-4dc2-8afe-03f102dd4d80 IMT P1 P1 IMT 1489959716297
NA 2017 Spring Split regular_season NV-vs-P1 NV|P1|G1|110ab763e1f1492290f0a c31aaee2-6d24-4a17-8a0b-d613df1e7ed7 NV P1 P1 NV 1487391115674
NA 2017 Spring Split regular_season NV-vs-P1 NV|P1|G2|110ab763e1f1492290f0a 5b2acee2-5fac-4444-9280-97020b68a0d6 P1 NV P1 NV 1487393212750
NA 2017 Spring Split regular_season DIG-vs-P1 DIG|P1|G1|2d2d468ecb0d45b6b4b1 28b5b75e-f20b-4b4e-91ba-b7122fb9a8d0 DIG P1 DIG P1 1485050515215
NA 2017 Spring Split regular_season DIG-vs-P1 DIG|P1|G2|2d2d468ecb0d45b6b4b1 39248b5e-12fd-4a4e-92d1-7b5885092d29 P1 DIG P1 DIG 1485056489276
NA 2017 Spring Split regular_season DIG-vs-P1 DIG|P1|G3|2d2d468ecb0d45b6b4b1 954448c9-f17a-4289-9238-b0315e169f97 DIG P1 DIG P1 1485059601975
NA 2017 Spring Split regular_season NV-vs-CLG CLG|NV|G1|904379b0d26447148198 2a55e10f-79ec-417d-a39b-4e1fc03d5549 NV CLG CLG NV 1485129142624
NA 2017 Spring Split regular_season NV-vs-CLG CLG|NV|G2|904379b0d26447148198 da048682-41a1-4dda-88ef-d7fa023cfc02 CLG NV CLG NV 1485131580644
NA 2017 Spring Split regular_season FOX-vs-NV FOX|NV|G1|22f05cfcdd1c4d9d9c64 4be72cf3-7e51-4a48-b73f-466cb7c58819 FOX NV FOX NV 1490486154406
NA 2017 Spring Split regular_season FOX-vs-NV FOX|NV|G2|22f05cfcdd1c4d9d9c64 0c9af6b2-77c1-46a4-962e-aa537e864476 NV FOX NV FOX 1490488755851
NA 2017 Spring Split regular_season FOX-vs-NV FOX|NV|G3|22f05cfcdd1c4d9d9c64 e47a4ddd-650e-4dd1-aa2a-1087d993e4fa FOX NV FOX NV 1490492277605
NA 2017 Spring Split regular_season TSM-vs-CLG CLG|TSM|G1|e3ae2e55819e4b1fbca fe925c3f-2fbc-4732-8e0f-2781d2387e46 TSM CLG TSM CLG 1488672992169
NA 2017 Spring Split regular_season TSM-vs-CLG CLG|TSM|G2|e3ae2e55819e4b1fbca d7223d32-027a-4617-a712-76dfaf69408d CLG TSM TSM CLG 1488680010538
NA 2017 Spring Split regular_season C9-vs-FLY C9|FLY|G1|b62bdbe4806845b4b7b5 9251b9d8-d8ae-4bde-a359-63767e21bfd0 C9 FLY C9 FLY 1488759408499
NA 2017 Spring Split regular_season C9-vs-FLY C9|FLY|G2|b62bdbe4806845b4b7b5 d2e5b624-0aa2-4c09-ac54-c3d80d7db930 FLY C9 C9 FLY 1488764230623
NA 2017 Spring Split regular_season IMT-vs-FLY FLY|IMT|G1|95cd994955294a7b88d ddbfedc0-d84d-427c-8701-7c7996819622 IMT FLY FLY IMT 1486344831099
NA 2017 Spring Split regular_season IMT-vs-FLY FLY|IMT|G2|95cd994955294a7b88d 40133a39-cc13-4a08-97e6-31af8d4d3a76 FLY IMT FLY IMT 1486347680292
NA 2017 Spring Split regular_season FLY-vs-DIG DIG|FLY|G1|18a24d13a28a44b79da 03f1c1b1-8a73-43cb-9fa8-69c3518667f0 FLY DIG FLY DIG 1486248061684
NA 2017 Spring Split regular_season FLY-vs-DIG DIG|FLY|G2|18a24d13a28a44b79da 9bae126a-006d-4d14-a15d-9e1b169681ea DIG FLY FLY DIG 1486250615457
NA 2017 Spring Split regular_season NV-vs-TL NV|TL|G1|9336cfac85574661800c8 08e0713b-fccb-4659-9d02-a9f701174101 NV TL NV TL 1486182242558
NA 2017 Spring Split regular_season NV-vs-TL NV|TL|G2|9336cfac85574661800c8 5621b87a-cca4-4313-a428-1cc364e619b1 TL NV NV TL 1486184017931
NA 2017 Spring Split regular_season C9-vs-CLG C9|CLG|G1|76c0444d1bfa47bfbbda c5d7a499-3637-4b2e-b95f-3d47a784204f C9 CLG C9 CLG 1485740002146
NA 2017 Spring Split regular_season C9-vs-CLG C9|CLG|G2|76c0444d1bfa47bfbbda da83e23c-423e-4193-a51d-1d8aa26b414a CLG C9 CLG C9 1485741071293
NA 2017 Spring Split regular_season C9-vs-CLG C9|CLG|G3|76c0444d1bfa47bfbbda 3285a6fb-1400-4024-b8ae-6bd1afaa5827 C9 CLG C9 CLG 1485745319431
NA 2017 Spring Split regular_season TSM-vs-DIG DIG|TSM|G1|5f974270a3ce4cd796f 34bdd3c9-edde-4428-88b5-9643bae4b0ab TSM DIG DIG TSM 1485575881330
NA 2017 Spring Split regular_season TSM-vs-DIG DIG|TSM|G2|5f974270a3ce4cd796f cde4aab8-15f1-4d92-b626-8614dc802ae5 DIG TSM TSM DIG 1485576889363
NA 2017 Spring Split regular_season TSM-vs-DIG DIG|TSM|G3|5f974270a3ce4cd796f f74a5ab4-ee97-4b0e-b026-c2c659e31360 TSM DIG TSM DIG 1485580452524
NA 2017 Spring Split na_2017_summer_promotion_relegation match-a GCU|NV|G1|e8d1bbbd45e04c4a9a33 978efa72-badc-4c61-b46c-d951caaf2e83 NV GCU GCU NV 1491004356124
NA 2017 Spring Split na_2017_summer_promotion_relegation match-a GCU|NV|G2|e8d1bbbd45e04c4a9a33 d65c14c9-f7b0-4ee2-a975-31194c1ad778 NV GCU NV GCU 1491010194436
NA 2017 Spring Split na_2017_summer_promotion_relegation match-a GCU|NV|G3|e8d1bbbd45e04c4a9a33 f2591a2a-1ff7-48b9-ae2b-1110a63d2140 NV GCU GCU NV 1491012054588
NA 2017 Spring Split na_2017_summer_promotion_relegation match-a GCU|NV|G4|e8d1bbbd45e04c4a9a33 48237b55-8bc9-422d-8c16-3f6eb5206b8f GCU NV GCU NV 1491016645767
NA 2017 Spring Split na_2017_summer_promotion_relegation match-c EUN|NV|G1|de80a32c97d74640a02d 4df27922-af86-4edf-ac35-54aed5c7369e NV EUN NV EUN 1491084193898
NA 2017 Spring Split na_2017_summer_promotion_relegation match-c EUN|NV|G2|de80a32c97d74640a02d f1ce223a-d4f9-4b20-9769-761dbe7969bd NV EUN EUN NV 1491084268032
NA 2017 Spring Split na_2017_summer_promotion_relegation match-c EUN|NV|G3|de80a32c97d74640a02d 299479ab-db4c-4a2a-8d05-db9e88f47de1 NV EUN NV EUN 1491089347837
NA 2017 Spring Split na_2017_summer_promotion_relegation match-c EUN|NV|G4|de80a32c97d74640a02d 74afdbe6-7052-42aa-ae56-94b7e2e9169a EUN NV NV EUN 1491091662853
NA 2017 Spring Split na_2017_summer_promotion_relegation match-e GCU|NV|G1|315f7afd076e4ef58392 30319428-89da-436a-bb97-2b69b83e03a5 GCU NV GCU NV 1491165446817
NA 2017 Spring Split na_2017_summer_promotion_relegation match-e GCU|NV|G2|315f7afd076e4ef58392 16dba721-bafe-4f6a-add0-75f8558d7d53 NV GCU NV GCU 1491168901341
NA 2017 Spring Split na_2017_summer_promotion_relegation match-e GCU|NV|G3|315f7afd076e4ef58392 fdad1f0b-e928-4655-bb2d-85d5a25b412b GCU NV NV GCU 1491173200959
NA 2017 Spring Split na_2017_summer_promotion_relegation match-e GCU|NV|G4|315f7afd076e4ef58392 b9f87d3e-31e6-4b2b-ba9f-4f420a5497d6 NV GCU GCU NV 1491177072605
NA 2017 Spring Split na_2017_summer_promotion_relegation match-e GCU|NV|G5|315f7afd076e4ef58392 740beb00-4b41-415e-9f8d-c577d1956775 GCU NV NV GCU 1491176707436
NA 2017 Spring Split na_2017_summer_promotion_relegation match-d GCU|TL|G1|d5b0872e56484cc58610 befbb4fa-52d5-49d1-8af4-94246df9497c TL GCU TL GCU 1491083708877
NA 2017 Spring Split na_2017_summer_promotion_relegation match-d GCU|TL|G2|d5b0872e56484cc58610 c278837c-46bf-4f93-aa30-874729bde47a TL GCU TL GCU 1491084317155
NA 2017 Spring Split na_2017_summer_promotion_relegation match-d GCU|TL|G3|d5b0872e56484cc58610 50578f26-eeac-4501-bb31-744a37256d68 TL GCU GCU TL 1491089353954
NA 2017 Spring Split na_2017_summer_promotion_relegation match-d GCU|TL|G4|d5b0872e56484cc58610 5c005cfb-f672-4609-b4b0-006f18cfbdcf GCU TL GCU TL 1491093782152
NA 2017 Spring Split na_2017_summer_promotion_relegation match-d GCU|TL|G5|d5b0872e56484cc58610 dd2dd82c-ffe5-450c-9ee7-52f781bb6694 TL GCU TL GCU 1491095094064
NA 2017 Spring Split na_2017_summer_promotion_relegation match-b EUN|TL|G1|e5b36bacbf86488888f0 1ae78ad9-b5ad-49b5-b41b-06c958025e10 TL EUN EUN TL 1491006146342
NA 2017 Spring Split na_2017_summer_promotion_relegation match-b EUN|TL|G2|e5b36bacbf86488888f0 27c157d7-6118-44cf-b450-2cf07fe93aa0 TL EUN TL EUN 1491008134166
NA 2017 Spring Split na_2017_summer_promotion_relegation match-b EUN|TL|G3|e5b36bacbf86488888f0 8ed4c1de-1381-4706-ac40-7762ce7abd35 TL EUN TL EUN 1491012094681
NA 2017 Spring Split na_2017_summer_promotion_relegation match-b EUN|TL|G4|e5b36bacbf86488888f0 0fb182bf-7dc2-4ef6-b276-aa59740dc055 TL EUN TL EUN 1491013577617
Generated tournament for the 2015 summer playoffs na_2015_summer_playoffs R1M1 GV|TSM|G1|9ac829ecd23145baba24 e4e64922-2172-4099-b5b7-80dca6b47159 GV TSM TSM GV 1439157858587
Generated tournament for the 2015 summer playoffs na_2015_summer_playoffs R1M1 GV|TSM|G2|9ac829ecd23145baba24 cf4e65a3-f381-41c9-aea2-dd8572320645 GV TSM GV TSM 1439162148795
Generated tournament for the 2015 summer playoffs na_2015_summer_playoffs R1M1 GV|TSM|G3|9ac829ecd23145baba24 4b87b848-8826-48dd-b4c6-2bdd908df3e8 TSM GV TSM GV 1439165335835
Generated tournament for the 2015 summer playoffs na_2015_summer_playoffs R1M1 GV|TSM|G4|9ac829ecd23145baba24 6ccf1f6b-1d72-4e54-88bd-64140321ddcf GV TSM TSM GV 1439168844970
Generated tournament for the 2015 summer playoffs na_2015_summer_playoffs R1M2 DIG|TIP|G1|9e7db3a2f25e4b87ad0 28e249eb-6839-4617-9fd8-6d00c587ee33 TIP DIG TIP DIG 1439063462751
Generated tournament for the 2015 summer playoffs na_2015_summer_playoffs R1M2 DIG|TIP|G2|9e7db3a2f25e4b87ad0 ab91df49-b989-4a76-b84e-ff76b08e317b DIG TIP TIP DIG 1439067059030
Generated tournament for the 2015 summer playoffs na_2015_summer_playoffs R1M2 DIG|TIP|G3|9e7db3a2f25e4b87ad0 b41668c1-1b47-4d08-9dac-2b056fddbf97 TIP DIG TIP DIG 1439070612667
Generated tournament for the 2015 summer playoffs na_2015_summer_playoffs R3M2 TIP|TL|G1|8c8ab8a212c24a52af6e e50efac6-8ec8-46ec-86aa-190108f2d5ba TL TIP TL TIP 1440284884489
Generated tournament for the 2015 summer playoffs na_2015_summer_playoffs R3M2 TIP|TL|G2|8c8ab8a212c24a52af6e 888ce470-f7dd-48e9-89c9-26303d151362 TIP TL TIP TL 1440288473142
Generated tournament for the 2015 summer playoffs na_2015_summer_playoffs R3M2 TIP|TL|G3|8c8ab8a212c24a52af6e 8dc629f5-851c-48b5-9628-9b61d3efdac1 TL TIP TL TIP 1440291647294
Generated tournament for the 2015 summer playoffs na_2015_summer_playoffs R3M2 TIP|TL|G4|8c8ab8a212c24a52af6e 659ae17e-5a87-4d18-9dae-7c33af502f9b TIP TL TL TIP 1440295061892
Generated tournament for the 2015 summer playoffs na_2015_summer_playoffs R2M2 CLG|TIP|G1|4e5a2b2d19a94ae6bde 1bf5d8d6-f5f1-42b5-9b69-1aea8a1bcc22 CLG TIP CLG TIP 1439669531618
Generated tournament for the 2015 summer playoffs na_2015_summer_playoffs R2M2 CLG|TIP|G2|4e5a2b2d19a94ae6bde 9216e252-c141-4403-aed3-f1feeb244b09 TIP CLG CLG TIP 1439673213690
Generated tournament for the 2015 summer playoffs na_2015_summer_playoffs R2M2 CLG|TIP|G3|4e5a2b2d19a94ae6bde 98e47288-0b13-4b93-8b4e-a5ecf02c2413 CLG TIP CLG TIP 1439676003866
Generated tournament for the 2015 summer playoffs na_2015_summer_playoffs R2M1 TL|TSM|G1|a9968710452c4b8bbed2 ff61c06a-34c8-4692-bbd1-a3de887dcc11 TL TSM TSM TL 1439755649658
Generated tournament for the 2015 summer playoffs na_2015_summer_playoffs R2M1 TL|TSM|G2|a9968710452c4b8bbed2 5fee6db2-1dc7-4a8c-b497-0379b6f2a5cd TSM TL TSM TL 1439760198625
Generated tournament for the 2015 summer playoffs na_2015_summer_playoffs R2M1 TL|TSM|G3|a9968710452c4b8bbed2 e2833384-f0e7-4da9-aa67-d01c9f5678db TL TSM TL TSM 1439764582018
Generated tournament for the 2015 summer playoffs na_2015_summer_playoffs R2M1 TL|TSM|G4|a9968710452c4b8bbed2 fe8cb4c1-de9d-475b-8801-55d0a4ab5744 TSM TL TSM TL 1439767605317
Generated tournament for the 2015 summer playoffs na_2015_summer_playoffs R3M1 CLG|TSM|G1|0aad477bbb7b455cb66 7bd0f0be-2a18-4154-9a8d-7f4b42f072ed CLG TSM CLG TSM 1440367565086
Generated tournament for the 2015 summer playoffs na_2015_summer_playoffs R3M1 CLG|TSM|G2|0aad477bbb7b455cb66 d3811e41-dd64-45cd-9373-9a70bcc0f3e8 TSM CLG CLG TSM 1440370876657
Generated tournament for the 2015 summer playoffs na_2015_summer_playoffs R3M1 CLG|TSM|G3|0aad477bbb7b455cb66 3cab91b7-50a0-447e-a4f1-a421f45f287c CLG TSM CLG TSM 1440374640492
<!DOCTYPE html>
<meta charset='utf-8'>
<link rel="stylesheet" type="text/css" href="style.css">
<body>
<div class='graph'></div>
</body>
<script src='d3+_.js'></script>
<script src='_script.js'></script>
body{
font-family: monaco, Consolas, 'Lucida Console', monospace;
/*margin: 0px;*/
}
canvas{
position: absolute;
top: 0px;
left: 0px;
}
.tooltip {
top: -1000px;
position: fixed;
padding: 10px;
background: rgba(255, 255, 255, .90);
border: 1px solid lightgray;
pointer-events: none;
}
.tooltip-hidden{
opacity: 0;
transition: all .3s;
transition-delay: .1s;
}
@media (max-width: 590px){
div.tooltip{
bottom: -1px;
width: calc(100%);
left: -1px !important;
right: -1px !important;
top: auto !important;
width: auto !important;
}
}
svg{
overflow: visible;
}
.domain{
display: none;
}
text{
pointer-events: none;
text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, 0 -1px 0 #fff, -1px 0 0 #fff;
}
path{
/*shape-rendering: crispEdges;*/
stroke-width: 1px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment