diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /third_party/webkit/PerformanceTests/MotionMark/resources | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/webkit/PerformanceTests/MotionMark/resources')
15 files changed, 5109 insertions, 0 deletions
diff --git a/third_party/webkit/PerformanceTests/MotionMark/resources/debug-runner/animometer.css b/third_party/webkit/PerformanceTests/MotionMark/resources/debug-runner/animometer.css new file mode 100644 index 0000000000..7fbf31ee7d --- /dev/null +++ b/third_party/webkit/PerformanceTests/MotionMark/resources/debug-runner/animometer.css @@ -0,0 +1,774 @@ +body { + font-size: initial; +} + +body.showing-intro, +body.showing-results, +body.showing-test-graph { + background-color: rgb(96, 96, 96); + background-image: initial; + background-repeat: initial; + background-size: initial; + animation: initial; + will-change: initial; + + color: rgb(235, 235, 235); +} + +section .body { + margin-left: 0; + max-width: initial; + transform: none; +} + +h1 { + font-size: 3em; + margin: 1.5em 0 .5em; + text-align: center; +} + +button { + transform: none !important; + min-width: initial; + transition: none; + animation: none; + will-change: initial; + + display: block; + font-size: 1.5em; + border: 2px solid rgb(235, 235, 235); + color: rgb(235, 235, 235); + background: transparent; + border-radius: 10px; + padding: .5em 2em; +} + +button:hover { + background-color: rgba(255, 255, 255, .1); + cursor: pointer; +} + +button:active { + color: inherit; + background-color: rgba(255, 255, 255, .2); +} + +button:disabled { + border-color: rgba(235, 235, 235, .5); + color: rgba(235, 235, 235, .5); +} + +@media screen and (max-device-width: 414px), + screen and (max-device-height: 414px) and (orientation: landscape) { + h1 { + font-size: 2.5em; + } + + section { + box-sizing: border-box; + width: 100%; + height: 100%; + padding: 0 5px; + } +} + +/* -------------------------------------------------------------------------- */ +/* Tree */ +/* -------------------------------------------------------------------------- */ + +.tree { + padding: 0; + list-style-type: none; +} + +.tree .expand-button { + position: absolute; + clip: rect(0, 0, 0, 0); +} + +.tree .expand-button ~ ul { + display: none; +} + +.tree .expand-button:checked ~ ul { + display: block; +} + +.tree ul { + list-style-type:none; +} + +.tree li { + position: relative; + padding: 0 0 1em 1em; +} + +.tree ul li { + list-style:none; + padding: 1em 0 0 0em; +} + +.tree > li:last-child { + padding-bottom: 0; +} + +.tree-label { + position: relative; + display: inline-block; +} + +label.tree-label { + cursor: pointer; +} + +.tree > li > label.tree-label:before { + position: relative; + z-index: 1; + float: left; + margin: 0 0 0 -2em; + width: 1em; + height: 1em; + content: '\25BA'; + text-align: center; + line-height: 2.5em; + font-size: .5em; +} + +.tree > li > :checked ~ label.tree-label:before { + content: '\25BC'; +} + +.tree .link { + cursor: pointer; + color: #999; + font-style: italic; + margin-left: 2em; +} + +@media screen and (max-device-width: 414px), + screen and (max-device-height: 414px) and (orientation: landscape) { + .tree { + padding-left: 1em; + } + .tree > li > label.tree-label:before { + font-size: 1em; + margin-left: -1.75em; + line-height: 1em; + } +} + +/* -------------------------------------------------------------------------- */ +/* Intro Section */ +/* -------------------------------------------------------------------------- */ + +#intro { + padding: 0; + opacity: initial; + transition: none; +} + +#intro .body > p { + padding: 1em 0; + margin: 0 auto; + text-align: center; +} + +#intro .start-benchmark { + padding: 10vh 0; + text-align: center; +} + +#intro .start-benchmark p { + color: hsl(11, 72%, 50%); + margin-bottom: 1em; + -apple-trailing-word: -apple-partially-balanced; +} + +#intro .start-benchmark button { + margin: 0 auto; +} + + +@media screen and (max-device-width: 414px), + screen and (max-device-height: 414px) and (orientation: landscape) { + #intro.selected { + display: flex; + align-items: center; + justify-content: flex-start; + flex-flow: column; + } + + #intro p { + padding-left: 20px; + padding-right: 20px; + font-size: 1.5em; + } +} + +#intro h2 { + font-size: 1.2em; +} + +#intro .body > div:first-of-type { + width: 100%; + margin: 2em 0 0; + flex-direction: row; + display: flex; + align-content: flex-start; +} + +#suites { + padding-left: 15vw; + padding-right: 3em; + flex: 1 1 30%; +} + +#options { + flex: 10 1 auto; +} + +#intro input[type="number"] { + width: 50px; +} + +#suites input[type="number"] { + display: none; + float: right; +} + +#suites input[type="number"].selected { + display: inline; + margin: 0; +} + +#suites ul ul { + font-size: .8em; + margin: 0; + padding: 0 0 0 1em; +} + +#suites > div { + margin: 3em 0; +} + +#drop-target { + font-size: 1em; + border-radius: 10px; + padding: .5em 2em; + border: 2px solid rgb(235, 235, 235); + color: rgb(235, 235, 235); +} + +#drop-target:hover { + background-color: rgba(255, 255, 255, .1); + cursor: pointer; +} + +#options ul { + margin: 0; + padding: 0; + list-style: none; +} + +#options h3 { + font-size: 1em; + font-weight: inherit; + margin: 0 0 .3em 0; + padding: 0; +} + +#options > form > ul > li { + padding: 0 0 1em 0; +} + +#options ul ul { + padding: 0; +} + +#options li { + padding: .1em 0; +} + +#intro > p { + padding: 0 5px 1em; + font-size: 1em; +} + +#intro .start-benchmark { + padding: 0 0 10vh; + margin-top: 0; +} + +#intro .start-benchmark p { + color: hsl(11, 100%, 66%); +} + +@media screen and (max-device-width: 414px), + screen and (max-device-height: 414px) and (orientation: landscape) { + #intro .body > div:first-of-type { + flex-direction: column; + } + + #suites, + #options { + padding: 0 5px; + margin: 0; + flex: 0 0 auto; + } +} + +/* -------------------------------------------------------------------------- */ +/* Running Section */ +/* -------------------------------------------------------------------------- */ + +#running-test { + display: flex; + align-items: center; + justify-content: center; +} + +#progress { + display: none; +} + +.display-progress-bar #progress { + display: block; + position: fixed; + top: 0; + left: 0; + height: 6px; + width: 100%; + background-color: rgb(128, 128, 128); +} + +.display-progress-bar #progress-completed { + position: absolute; + top: 0; + left: 0; + height: 6px; + width: 0; + background-color: rgb(235, 96, 32); +} + +body.showing-test-container.tiles-big { + overflow: hidden; +} + +body.showing-test-container.tiles-classic { + width: 3000px; + height: 3000px; + overflow: scroll; +} + +/* -------------------------------------------------------------------------- */ +/* Results Section */ +/* -------------------------------------------------------------------------- */ + +#results { + text-align: center; +} + +#results h1, #test-graph h1 { + font-size: 2em; +} + +#results button.small-button { + border: 1px solid rgba(235, 235, 235, .9); + color: rgba(235, 235, 235, .9); + border-radius: 2px; + padding: 1px 4px; + margin: 0 0 0 1em; + font-size: 9px; +} + +#results button.small-button:active { + background-color: rgba(235, 235, 235, .2); + color: inherit; +} + +#results .score, +#test-graph .score { + font-size: 3em; + font-weight: bold; + margin: 0; +} + +#results .confidence, +#test-graph .confidence { + margin-top: 0; + margin-bottom: 1em; + font-size: 1.5em; + font-weight: 400; + text-indent: inherit; + color: inherit; +} + +#results-tables { + direction: rtl; + + display: flex; + + align-items: center; + justify-content: center; + + margin: 3em 0; +} + +#results .table-container > div { + margin-left: 0; +} + +#results #results-score { + float: initial; +} + +#results #results-header { + width: initial; + position: initial; +} + +#results table { + direction: ltr; + min-width: initial; +} + +#results table td.suites-separator { + padding: .5em 0; +} + +#results table tr:nth-child(even) { + background-color: transparent; +} + +#results th { + padding: .5em 0; +} + +#results tr td { + padding: .25em 0; +} + +#results-header td, #results-header th { + text-align: left; +} +#results-header tr td { + padding-right: 1em; +} +#results-score td, #results-score th { + text-align: right; +} +#results .body > button { + margin: 1.5em auto .5em; +} +#results footer { + padding-bottom: 10vh; +} + +@media screen and (max-device-width: 414px), + screen and (max-device-height: 414px) and (orientation: landscape) { + #results.selected { + padding: 0 20px; + } +} + +#overlay { + background: rgba(0, 0, 10, .8); +} + +@supports (-webkit-backdrop-filter: blur(10px)) { + #overlay { + background: rgba(0, 0, 10, .4); + } +} + +#overlay > div div { + border: 1px solid rgb(241, 241, 241); +} + +#overlay button { + margin: 2em auto; + border-color: rgb(241, 241, 241); + color: rgb(241, 241, 241); +} + +#overlay button:hover { + background-color: rgba(255, 255, 255, .1); +} + +#overlay button:active { + background-color: rgba(255, 255, 255, .2); +} + +#results-data .average { + padding-left: 1em; + text-align: right; +} + +#results-data .stdev { + text-align: left; + padding-left: .25em; +} + +#results-data .left { + text-align: left; +} + +#results-data .right { + text-align: right; +} + +#results-data .pad-left { + padding-left: 1em; +} + +#results-data .pad-right { + padding-right: .25em; +} + +#results-data .small { + font-size: .8em; +} + +#results-tables td.noisy-results { + color: rgb(255, 104, 104); +} + +#results-tables div { + direction: ltr; + display: flex; + flex-direction: row; +} + +#test-graph { + flex: 1 0 calc(100% - 40px); +} + +#test-graph h1 { + margin-bottom: 0; +} + +#test-graph header { + position: relative; + text-align:center; +} + +#test-graph header button { + position: absolute; + top: 0; + left: 0; + border-width: 1px; + font-size: 1em; + padding: .5em 1em; +} + +#test-graph .score, #test-graph .confidence { + margin: 0; +} + +#test-graph nav { + position: absolute; + top: 1.5em; + right: 0; + font-size: .7em; + width: 28em; +} + +#test-graph nav ul { + margin: 0 30px 1em 0; + padding: 0; + list-style: none; +} + +#test-graph nav li { + padding: .1em 0; +} + +#test-graph nav li > span { + float: right; +} + +#test-graph nav.hide-data span { + display: none; +} + +/* -------------------------------------------------------------------------- */ +/* Graph Section */ +/* -------------------------------------------------------------------------- */ + +#test-graph-data { + z-index: 1; + font: 10px sans-serif; + color: rgb(235, 235, 235); +} + +#test-graph-data > svg { + fill: none; + overflow: visible; +} + +.axis path, +.axis line { + fill: none; + stroke: #999999; + shape-rendering: crispEdges; +} + +.axis text { + fill: #999; +} + +.yLeft.axis text { + fill: #7add49; +} +.yLeft.axis path, +.yLeft.axis line { + stroke: #7add49; +} +.yRight.axis text { + fill: #fa4925; +} +.yRight.axis path, +.yRight.axis line { + stroke: #fa4925; +} + +.axis.complexity .tick line { + stroke: rgba(200, 200, 200, .6); + stroke-width: 2px; +} + +.axis.complexity .domain, +.axis.complexity text { + stroke: transparent; + fill: transparent; +} + +.marker line { + stroke: #5493D6; +} + +.marker text { + fill: #999; +} + +.mean.complexity line { + stroke: hsla(100, 69%, 58%, .8); + stroke-width: 2px; +} + +.mean.complexity polygon { + fill: hsla(100, 69%, 58%, .05); +} + +.target-fps { + stroke: rgba(250, 73, 37, .4); + stroke-width: 1px; + stroke-dasharray: 10, 10; +} + +.mean.fps line { + stroke: hsla(10, 96%, 56%, .8); + stroke-width: 2px; +} + +.mean.fps polygon { + fill: hsla(10, 96%, 56%, .1); +} + +#regressions line { + stroke: rgba(200, 200, 200, .8); + stroke-width: 2px; +} + +#regressions circle { + fill: rgba(200, 200, 200, .8); +} + +.cursor line { + stroke: rgb(250, 250, 250); + stroke-width: 1px; +} + +.cursor circle, +.cursor text { + fill: rgb(250, 250, 250); +} + +#complexity path { + stroke: rgba(122, 221, 73, .7); + stroke-width: 2px; +} + +#complexity circle { + fill: rgb(122, 221, 73); +} + +#filteredFPS path { + stroke: hsla(30, 96%, 56%, .7); + stroke-width: 1px; +} + +#filteredFPS circle { + fill: hsl(30, 96%, 56%); +} + +#rawFPS path { + stroke: rgba(250, 73, 37, .7); + stroke-width: 1px; +} + +#rawFPS circle { + fill: rgb(250, 73, 37); +} + +#complexity-graph .regression line { + stroke: rgba(253, 253, 253, .8); + stroke-width: 2px; +} + +#complexity-graph .regression circle { + fill: rgba(253, 253, 253, .8); +} + +#complexity-graph .regression polygon { + fill: rgba(253, 253, 253, .05); +} + +#complexity-graph .raw.series line { + stroke: hsla(30, 96%, 56%, .3); + stroke-width: 1px; +} + +#complexity-graph .raw.regression line { + stroke: rgba(30, 96%, 86%, .6); +} + +#complexity-graph .raw.regression polygon { + stroke: rgba(30, 96%, 86%, .05); +} + +#complexity-graph .average.series circle { + fill: hsl(170, 96%, 56%); +} + +#complexity-graph .average.series line { + stroke: hsla(170, 96%, 56%, .2); + stroke-width: 2px; +} + +#complexity-graph .bootstrap .bar { + fill: hsla(260, 56%, 66%, .4); +} + +#complexity-graph .bootstrap .median line { + stroke: hsla(300, 56%, 66%, .8); + stroke-width: 2px; +} + +#complexity-graph .bootstrap .median circle { + fill: hsla(300, 56%, 66%, .8); +} + +#complexity-graph .bootstrap .median polygon { + fill: hsla(300, 56%, 66%, .05); +} diff --git a/third_party/webkit/PerformanceTests/MotionMark/resources/debug-runner/animometer.js b/third_party/webkit/PerformanceTests/MotionMark/resources/debug-runner/animometer.js new file mode 100644 index 0000000000..a6702eeadb --- /dev/null +++ b/third_party/webkit/PerformanceTests/MotionMark/resources/debug-runner/animometer.js @@ -0,0 +1,702 @@ +ProgressBar = Utilities.createClass( + function(element, ranges) + { + this._element = element; + this._ranges = ranges; + this._currentRange = 0; + this._updateElement(); + }, { + + _updateElement: function() + { + this._element.style.width = (this._currentRange * (100 / this._ranges)) + "%"; + }, + + incrementRange: function() + { + ++this._currentRange; + this._updateElement(); + } +}); + +DeveloperResultsTable = Utilities.createSubclass(ResultsTable, + function(element, headers) + { + ResultsTable.call(this, element, headers); + }, { + + _addGraphButton: function(td, testName, testResult, testData) + { + var button = Utilities.createElement("button", { class: "small-button" }, td); + button.textContent = Strings.text.graph + "…"; + button.testName = testName; + button.testResult = testResult; + button.testData = testData; + + button.addEventListener("click", function(e) { + benchmarkController.showTestGraph(e.target.testName, e.target.testResult, e.target.testData); + }); + }, + + _isNoisyMeasurement: function(jsonExperiment, data, measurement, options) + { + const percentThreshold = 10; + const averageThreshold = 2; + + if (measurement == Strings.json.measurements.percent) + return data[Strings.json.measurements.percent] >= percentThreshold; + + if (jsonExperiment == Strings.json.frameLength && measurement == Strings.json.measurements.average) + return Math.abs(data[Strings.json.measurements.average] - options["frame-rate"]) >= averageThreshold; + + return false; + }, + + _addTest: function(testName, testResult, options, testData) + { + var row = Utilities.createElement("tr", {}, this.element); + + var isNoisy = false; + [Strings.json.complexity, Strings.json.frameLength].forEach(function (experiment) { + var data = testResult[experiment]; + for (var measurement in data) { + if (this._isNoisyMeasurement(experiment, data, measurement, options)) + isNoisy = true; + } + }, this); + + this._flattenedHeaders.forEach(function (header) { + var className = ""; + if (header.className) { + if (typeof header.className == "function") + className = header.className(testResult, options); + else + className = header.className; + } + + if (header.text == Strings.text.testName) { + if (isNoisy) + className += " noisy-results"; + var td = Utilities.createElement("td", { class: className }, row); + td.textContent = testName; + return; + } + + var td = Utilities.createElement("td", { class: className }, row); + if (header.title == Strings.text.graph) { + this._addGraphButton(td, testName, testResult, testData); + } else if (!("text" in header)) { + td.textContent = testResult[header.title]; + } else if (typeof header.text == "string") { + var data = testResult[header.text]; + if (typeof data == "number") + data = data.toFixed(2); + td.textContent = data; + } else + td.textContent = header.text(testResult); + }, this); + } +}); + +Utilities.extendObject(window.benchmarkRunnerClient, { + testsCount: null, + progressBar: null, + + initialize: function(suites, options) + { + this.testsCount = this.iterationCount * suites.reduce(function (count, suite) { return count + suite.tests.length; }, 0); + this.options = options; + }, + + willStartFirstIteration: function() + { + this.results = new ResultsDashboard(this.options); + this.progressBar = new ProgressBar(document.getElementById("progress-completed"), this.testsCount); + }, + + didRunTest: function(testData) + { + this.progressBar.incrementRange(); + this.results.calculateScore(testData); + } +}); + +Utilities.extendObject(window.sectionsManager, { + setSectionHeader: function(sectionIdentifier, title) + { + document.querySelector("#" + sectionIdentifier + " h1").textContent = title; + }, + + populateTable: function(tableIdentifier, headers, dashboard) + { + var table = new DeveloperResultsTable(document.getElementById(tableIdentifier), headers); + table.showIterations(dashboard); + } +}); + +window.optionsManager = +{ + valueForOption: function(name) + { + var formElement = document.forms["benchmark-options"].elements[name]; + if (formElement.type == "checkbox") + return formElement.checked; + else if (formElement.constructor === HTMLCollection) { + for (var i = 0; i < formElement.length; ++i) { + var radio = formElement[i]; + if (radio.checked) + return formElement.value; + } + return null; + } + return formElement.value; + }, + + updateUIFromLocalStorage: function() + { + var formElements = document.forms["benchmark-options"].elements; + + for (var i = 0; i < formElements.length; ++i) { + var formElement = formElements[i]; + var name = formElement.id || formElement.name; + var type = formElement.type; + + var value = localStorage.getItem(name); + if (value === null) + continue; + + if (type == "number") + formElements[name].value = +value; + else if (type == "checkbox") + formElements[name].checked = value == "true"; + else if (type == "radio") + formElements[name].value = value; + } + }, + + updateLocalStorageFromUI: function() + { + var formElements = document.forms["benchmark-options"].elements; + var options = {}; + + for (var i = 0; i < formElements.length; ++i) { + var formElement = formElements[i]; + var name = formElement.id || formElement.name; + var type = formElement.type; + + if (type == "number") + options[name] = +formElement.value; + else if (type == "checkbox") + options[name] = formElement.checked; + else if (type == "radio") { + var radios = formElements[name]; + if (radios.constructor === HTMLCollection) { + for (var j = 0; j < radios.length; ++j) { + var radio = radios[j]; + if (radio.checked) { + options[name] = radio.value; + break; + } + } + } else + options[name] = formElements[name].value; + } + + try { + localStorage.setItem(name, options[name]); + } catch (e) {} + } + + return options; + }, + + updateDisplay: function() + { + document.body.classList.remove("display-minimal"); + document.body.classList.remove("display-progress-bar"); + + document.body.classList.add("display-" + optionsManager.valueForOption("display")); + }, + + updateTiles: function() + { + document.body.classList.remove("tiles-big"); + document.body.classList.remove("tiles-classic"); + + document.body.classList.add("tiles-" + optionsManager.valueForOption("tiles")); + } +}; + +window.suitesManager = +{ + _treeElement: function() + { + return document.querySelector("#suites > .tree"); + }, + + _suitesElements: function() + { + return document.querySelectorAll("#suites > ul > li"); + }, + + _checkboxElement: function(element) + { + return element.querySelector("input[type='checkbox']:not(.expand-button)"); + }, + + _editElement: function(element) + { + return element.querySelector("input[type='number']"); + }, + + _editsElements: function() + { + return document.querySelectorAll("#suites input[type='number']"); + }, + + _localStorageNameForTest: function(suiteName, testName) + { + return suiteName + "/" + testName; + }, + + _updateSuiteCheckboxState: function(suiteCheckbox) + { + var numberEnabledTests = 0; + suiteCheckbox.testsElements.forEach(function(testElement) { + var testCheckbox = this._checkboxElement(testElement); + if (testCheckbox.checked) + ++numberEnabledTests; + }, this); + suiteCheckbox.checked = numberEnabledTests > 0; + suiteCheckbox.indeterminate = numberEnabledTests > 0 && numberEnabledTests < suiteCheckbox.testsElements.length; + }, + + isAtLeastOneTestSelected: function() + { + var suitesElements = this._suitesElements(); + + for (var i = 0; i < suitesElements.length; ++i) { + var suiteElement = suitesElements[i]; + var suiteCheckbox = this._checkboxElement(suiteElement); + + if (suiteCheckbox.checked) + return true; + } + + return false; + }, + + _onChangeSuiteCheckbox: function(event) + { + var selected = event.target.checked; + event.target.testsElements.forEach(function(testElement) { + var testCheckbox = this._checkboxElement(testElement); + testCheckbox.checked = selected; + }, this); + benchmarkController.updateStartButtonState(); + }, + + _onChangeTestCheckbox: function(suiteCheckbox) + { + this._updateSuiteCheckboxState(suiteCheckbox); + benchmarkController.updateStartButtonState(); + }, + + _createSuiteElement: function(treeElement, suite, id) + { + var suiteElement = Utilities.createElement("li", {}, treeElement); + var expand = Utilities.createElement("input", { type: "checkbox", class: "expand-button", id: id }, suiteElement); + var label = Utilities.createElement("label", { class: "tree-label", for: id }, suiteElement); + + var suiteCheckbox = Utilities.createElement("input", { type: "checkbox" }, label); + suiteCheckbox.suite = suite; + suiteCheckbox.onchange = this._onChangeSuiteCheckbox.bind(this); + suiteCheckbox.testsElements = []; + + label.appendChild(document.createTextNode(" " + suite.name)); + return suiteElement; + }, + + _createTestElement: function(listElement, test, suiteCheckbox) + { + var testElement = Utilities.createElement("li", {}, listElement); + var span = Utilities.createElement("label", { class: "tree-label" }, testElement); + + var testCheckbox = Utilities.createElement("input", { type: "checkbox" }, span); + testCheckbox.test = test; + testCheckbox.onchange = function(event) { + this._onChangeTestCheckbox(event.target.suiteCheckbox); + }.bind(this); + testCheckbox.suiteCheckbox = suiteCheckbox; + + suiteCheckbox.testsElements.push(testElement); + span.appendChild(document.createTextNode(" " + test.name + " ")); + + testElement.appendChild(document.createTextNode(" ")); + var link = Utilities.createElement("span", {}, testElement); + link.classList.add("link"); + link.textContent = "link"; + link.suiteName = Utilities.stripNonASCIICharacters(suiteCheckbox.suite.name); + link.testName = test.name; + link.onclick = function(event) { + var element = event.target; + var title = "Link to run “" + element.testName + "” with current options:"; + var url = location.href.split(/[?#]/)[0]; + var options = optionsManager.updateLocalStorageFromUI(); + Utilities.extendObject(options, { + "suite-name": element.suiteName, + "test-name": Utilities.stripNonASCIICharacters(element.testName) + }); + var complexity = suitesManager._editElement(element.parentNode).value; + if (complexity) + options.complexity = complexity; + prompt(title, url + Utilities.convertObjectToQueryString(options)); + }; + + var complexity = Utilities.createElement("input", { type: "number" }, testElement); + complexity.relatedCheckbox = testCheckbox; + complexity.oninput = function(event) { + var relatedCheckbox = event.target.relatedCheckbox; + relatedCheckbox.checked = true; + this._onChangeTestCheckbox(relatedCheckbox.suiteCheckbox); + }.bind(this); + return testElement; + }, + + createElements: function() + { + var treeElement = this._treeElement(); + + Suites.forEach(function(suite, index) { + var suiteElement = this._createSuiteElement(treeElement, suite, "suite-" + index); + var listElement = Utilities.createElement("ul", {}, suiteElement); + var suiteCheckbox = this._checkboxElement(suiteElement); + + suite.tests.forEach(function(test) { + this._createTestElement(listElement, test, suiteCheckbox); + }, this); + }, this); + }, + + updateEditsElementsState: function() + { + var editsElements = this._editsElements(); + var showComplexityInputs = ["fixed", "step"].indexOf(optionsManager.valueForOption("controller")) != -1; + + for (var i = 0; i < editsElements.length; ++i) { + var editElement = editsElements[i]; + if (showComplexityInputs) + editElement.classList.add("selected"); + else + editElement.classList.remove("selected"); + } + }, + + updateUIFromLocalStorage: function() + { + var suitesElements = this._suitesElements(); + + for (var i = 0; i < suitesElements.length; ++i) { + var suiteElement = suitesElements[i]; + var suiteCheckbox = this._checkboxElement(suiteElement); + var suite = suiteCheckbox.suite; + + suiteCheckbox.testsElements.forEach(function(testElement) { + var testCheckbox = this._checkboxElement(testElement); + var testEdit = this._editElement(testElement); + var test = testCheckbox.test; + + var str = localStorage.getItem(this._localStorageNameForTest(suite.name, test.name)); + if (str === null) + return; + + var value = JSON.parse(str); + testCheckbox.checked = value.checked; + testEdit.value = value.complexity; + }, this); + + this._updateSuiteCheckboxState(suiteCheckbox); + } + + benchmarkController.updateStartButtonState(); + }, + + updateLocalStorageFromUI: function() + { + var suitesElements = this._suitesElements(); + var suites = []; + + for (var i = 0; i < suitesElements.length; ++i) { + var suiteElement = suitesElements[i]; + var suiteCheckbox = this._checkboxElement(suiteElement); + var suite = suiteCheckbox.suite; + + var tests = []; + suiteCheckbox.testsElements.forEach(function(testElement) { + var testCheckbox = this._checkboxElement(testElement); + var testEdit = this._editElement(testElement); + var test = testCheckbox.test; + + if (testCheckbox.checked) { + test.complexity = testEdit.value; + tests.push(test); + } + + var value = { checked: testCheckbox.checked, complexity: testEdit.value }; + try { + localStorage.setItem(this._localStorageNameForTest(suite.name, test.name), JSON.stringify(value)); + } catch (e) {} + }, this); + + if (tests.length) + suites.push(new Suite(suiteCheckbox.suite.name, tests)); + } + + return suites; + }, + + suitesFromQueryString: function(suiteName, testName, oskey=null) + { + var suites = []; + var suiteRegExp = new RegExp(suiteName, "i"); + var testRegExp = new RegExp(testName, "i"); + + for (var i = 0; i < Suites.length; ++i) { + var suite = Suites[i]; + if (!Utilities.stripNonASCIICharacters(suite.name).match(suiteRegExp)) + continue; + + var test; + for (var j = 0; j < suite.tests.length; ++j) { + suiteTest = suite.tests[j]; + // MOZILLA: Run all the tests in a given suite + if (typeof(testName) === "undefined") { + let complexity = {"HTMLsuite": { + "CSSbouncingcircles": {"win": 322, "linux64": 322, "osx": 218}, + "CSSbouncingclippedrects": {"win": 520, "linux64": 520, "osx": 75}, + "CSSbouncinggradientcircles": {"win": 402, "linux64": 402, "osx": 97}, + "CSSbouncingblendcircles": {"win": 171, "linux64": 171, "osx": 254}, + "CSSbouncingfiltercircles": {"win": 189, "linux64": 189, "osx": 189}, + "CSSbouncingSVGimages": {"win": 329, "linux64": 329, "osx": 392}, + "CSSbouncingtaggedimages": {"win": 255, "linux64": 255, "osx": 351}, + "Leaves20": {"win": 262, "linux64": 262, "osx": 191}, + "Focus20": {"win": 15, "linux64": 15, "osx": 18}, + "DOMparticlesSVGmasks": {"win": 390, "linux64": 390, "osx": 54}, + "CompositedTransforms": {"win": 400, "linux64": 400, "osx": 75} + }, "Animometer": { + "Multiply": {"win": 391, "linux64": 391, "osx": 193}, + "CanvasArcs": {"win": 1287, "linux64": 1287, "osx": 575}, + "Leaves": {"win": 550, "linux64": 550, "osx": 271}, + "Paths": {"win": 4070, "linux64": 4070, "osx": 2024}, + "CanvasLines": {"win": 4692, "linux64": 4692, "osx": 10932}, + "Focus": {"win": 44, "linux64": 44, "osx": 32}, + "Images": {"win": 293, "linux64": 293, "osx": 188}, + "Design": {"win": 60, "linux64": 60, "osx": 17}, + "Suits": {"win": 210, "linux64": 210, "osx": 145} + } + }; + if (oskey == null) { + oskey = "linux64"; + } + suiteTest.complexity = complexity[suiteName][Utilities.stripNonASCIICharacters(suiteTest.name)][oskey]; + suites.push(new Suite(suiteName, [suiteTest])); + continue; + } + + if (Utilities.stripNonASCIICharacters(suiteTest.name).match(testRegExp)) { + test = suiteTest; + break; + } + } + + if (!test) + continue; + + suites.push(new Suite(suiteName, [test])); + }; + + return suites; + }, + + updateLocalStorageFromJSON: function(results) + { + for (var suiteName in results[Strings.json.results.tests]) { + var suiteResults = results[Strings.json.results.tests][suiteName]; + for (var testName in suiteResults) { + var testResults = suiteResults[testName]; + var data = testResults[Strings.json.controller]; + var complexity = Math.round(data[Strings.json.measurements.average]); + + var value = { checked: true, complexity: complexity }; + try { + localStorage.setItem(this._localStorageNameForTest(suiteName, testName), JSON.stringify(value)); + } catch (e) {} + } + } + } +} + +Utilities.extendObject(window.benchmarkController, { + initialize: function() + { + document.forms["benchmark-options"].addEventListener("change", benchmarkController.onBenchmarkOptionsChanged, true); + document.forms["graph-type"].addEventListener("change", benchmarkController.onGraphTypeChanged, true); + document.forms["time-graph-options"].addEventListener("change", benchmarkController.onTimeGraphOptionsChanged, true); + document.forms["complexity-graph-options"].addEventListener("change", benchmarkController.onComplexityGraphOptionsChanged, true); + optionsManager.updateUIFromLocalStorage(); + optionsManager.updateDisplay(); + optionsManager.updateTiles(); + + if (benchmarkController.startBenchmarkImmediatelyIfEncoded()) + return; + + benchmarkController.addOrientationListenerIfNecessary(); + suitesManager.createElements(); + suitesManager.updateUIFromLocalStorage(); + suitesManager.updateEditsElementsState(); + + var dropTarget = document.getElementById("drop-target"); + function stopEvent(e) { + e.stopPropagation(); + e.preventDefault(); + } + dropTarget.addEventListener("dragenter", stopEvent, false); + dropTarget.addEventListener("dragover", stopEvent, false); + dropTarget.addEventListener("dragleave", stopEvent, false); + dropTarget.addEventListener("drop", function (e) { + e.stopPropagation(); + e.preventDefault(); + + if (!e.dataTransfer.files.length) + return; + + var file = e.dataTransfer.files[0]; + + var reader = new FileReader(); + reader.filename = file.name; + reader.onload = function(e) { + var run = JSON.parse(e.target.result); + if (run.debugOutput instanceof Array) + run = run.debugOutput[0]; + benchmarkRunnerClient.results = new ResultsDashboard(run.options, run.data); + benchmarkController.showResults(); + }; + + reader.readAsText(file); + document.title = "File: " + reader.filename; + }, false); + }, + + updateStartButtonState: function() + { + var startButton = document.getElementById("run-benchmark"); + if ("isInLandscapeOrientation" in this && !this.isInLandscapeOrientation) { + startButton.disabled = true; + return; + } + startButton.disabled = !suitesManager.isAtLeastOneTestSelected(); + }, + + onBenchmarkOptionsChanged: function(event) + { + switch (event.target.name) { + case "controller": + suitesManager.updateEditsElementsState(); + break; + case "display": + optionsManager.updateDisplay(); + break; + case "tiles": + optionsManager.updateTiles(); + break; + } + }, + + startBenchmark: function() + { + benchmarkController.determineCanvasSize(); + benchmarkController.options = optionsManager.updateLocalStorageFromUI(); + benchmarkController.suites = suitesManager.updateLocalStorageFromUI(); + this._startBenchmark(benchmarkController.suites, benchmarkController.options, "running-test"); + }, + + startBenchmarkImmediatelyIfEncoded: function() + { + benchmarkController.options = Utilities.convertQueryStringToObject(location.search); + if (!benchmarkController.options) + return false; + + this.raptor = benchmarkController.options["raptor"]; + benchmarkController.suites = suitesManager.suitesFromQueryString(benchmarkController.options["suite-name"], + benchmarkController.options["test-name"], + benchmarkController.options["oskey"]); + if (!benchmarkController.suites.length) + return false; + + setTimeout(function() { + this._startBenchmark(benchmarkController.suites, benchmarkController.options, "running-test"); + }.bind(this), 0); + return true; + }, + + restartBenchmark: function() + { + this._startBenchmark(benchmarkController.suites, benchmarkController.options, "running-test"); + }, + + showResults: function() + { + if (!this.addedKeyEvent) { + document.addEventListener("keypress", this.handleKeyPress, false); + this.addedKeyEvent = true; + } + + var dashboard = benchmarkRunnerClient.results; + if (["ramp", "ramp30"].indexOf(dashboard.options["controller"]) != -1) + Headers.details[3].disabled = true; + else { + Headers.details[1].disabled = true; + Headers.details[4].disabled = true; + } + + if (dashboard.options[Strings.json.configuration]) { + document.body.classList.remove("small", "medium", "large"); + document.body.classList.add(dashboard.options[Strings.json.configuration]); + } + + var score = dashboard.score; + var item = dashboard._results['iterationsResults'][0]; + var fullNames = new Array; + var values = new Array; + for (var suite in item['testsResults']) { + for (var subtest in item['testsResults'][suite.toString()]) { + fullNames.push(suite.toString() + "-" + subtest.toString().replace(/ /g, '_')); + values.push(item['testsResults'][suite.toString()][subtest.toString()]['frameLength']['average']); + } + } + if (typeof tpRecordTime !== "undefined") { + tpRecordTime(values.join(','), 0, fullNames.join(',')); + } + if (this.raptor) { + _data = ['raptor-benchmark', 'motionmark', item['testsResults']];
+ window.postMessage(_data, '*'); + } + + var confidence = ((dashboard.scoreLowerBound / score - 1) * 100).toFixed(2) + + "% / +" + ((dashboard.scoreUpperBound / score - 1) * 100).toFixed(2) + "%"; + sectionsManager.setSectionScore("results", score.toFixed(2), confidence); + sectionsManager.populateTable("results-header", Headers.testName, dashboard); + sectionsManager.populateTable("results-score", Headers.score, dashboard); + sectionsManager.populateTable("results-data", Headers.details, dashboard); + sectionsManager.showSection("results", true); + + suitesManager.updateLocalStorageFromJSON(dashboard.results[0]); + }, + + showTestGraph: function(testName, testResult, testData) + { + sectionsManager.setSectionHeader("test-graph", testName); + sectionsManager.showSection("test-graph", true); + this.updateGraphData(testResult, testData, benchmarkRunnerClient.results.options); + } +}); diff --git a/third_party/webkit/PerformanceTests/MotionMark/resources/debug-runner/d3.min.js b/third_party/webkit/PerformanceTests/MotionMark/resources/debug-runner/d3.min.js new file mode 100644 index 0000000000..1a7ae90342 --- /dev/null +++ b/third_party/webkit/PerformanceTests/MotionMark/resources/debug-runner/d3.min.js @@ -0,0 +1,5 @@ +!function(){function n(n,t){return t>n?-1:n>t?1:n>=t?0:0/0}function t(n){return null!=n&&!isNaN(n)}function e(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)<0?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)>0?u=i:r=i+1}return r}}}function r(n){return n.length}function u(n){for(var t=1;n*t%1;)t*=10;return t}function i(n,t){try{for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}catch(r){n.prototype=t}}function o(){}function a(n){return ia+n in this}function c(n){return n=ia+n,n in this&&delete this[n]}function s(){var n=[];return this.forEach(function(t){n.push(t)}),n}function l(){var n=0;for(var t in this)t.charCodeAt(0)===oa&&++n;return n}function f(){for(var n in this)if(n.charCodeAt(0)===oa)return!1;return!0}function h(){}function g(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function p(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.substring(1);for(var e=0,r=aa.length;r>e;++e){var u=aa[e]+t;if(u in n)return u}}function v(){}function d(){}function m(n){function t(){for(var t,r=e,u=-1,i=r.length;++u<i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=[],r=new o;return t.on=function(t,u){var i,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,i=e.indexOf(o)).concat(e.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function y(){Zo.event.preventDefault()}function x(){for(var n,t=Zo.event;n=t.sourceEvent;)t=n;return t}function M(n){for(var t=new d,e=0,r=arguments.length;++e<r;)t[arguments[e]]=m(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEvent=Zo.event;u.target=n,Zo.event=u,t[u.type].apply(e,r)}finally{Zo.event=i}}},t}function _(n){return sa(n,pa),n}function b(n){return"function"==typeof n?n:function(){return la(n,this)}}function w(n){return"function"==typeof n?n:function(){return fa(n,this)}}function S(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function u(){this.setAttribute(n,t)}function i(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=Zo.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?i:u}function k(n){return n.trim().replace(/\s+/g," ")}function E(n){return new RegExp("(?:^|\\s+)"+Zo.requote(n)+"(?:\\s+|$)","g")}function A(n){return(n+"").trim().split(/^|\s+/)}function C(n,t){function e(){for(var e=-1;++e<u;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<u;)n[e](this,r)}n=A(n).map(N);var u=n.length;return"function"==typeof t?r:e}function N(n){var t=E(n);return function(e,r){if(u=e.classList)return r?u.add(n):u.remove(n);var u=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(u)||e.setAttribute("class",k(u+" "+n))):e.setAttribute("class",k(u.replace(t," ")))}}function z(n,t,e){function r(){this.style.removeProperty(n)}function u(){this.style.setProperty(n,t,e)}function i(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?i:u}function L(n,t){function e(){delete this[n]}function r(){this[n]=t}function u(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?u:r}function T(n){return"function"==typeof n?n:(n=Zo.ns.qualify(n)).local?function(){return this.ownerDocument.createElementNS(n.space,n.local)}:function(){return this.ownerDocument.createElementNS(this.namespaceURI,n)}}function q(n){return{__data__:n}}function R(n){return function(){return ga(this,n)}}function D(t){return arguments.length||(t=n),function(n,e){return n&&e?t(n.__data__,e.__data__):!n-!e}}function P(n,t){for(var e=0,r=n.length;r>e;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function U(n){return sa(n,da),n}function j(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t<c;);return o}}function H(){var n=this.__transition__;n&&++n.active}function F(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function u(){var u=c(t,Xo(arguments));r.call(this),this.addEventListener(n,this[o]=u,u.$=e),u._=t}function i(){var t,e=new RegExp("^__on([^.]+)"+Zo.requote(n)+"$");for(var r in this)if(t=r.match(e)){var u=this[r];this.removeEventListener(t[1],u,u.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),c=O;a>0&&(n=n.substring(0,a));var s=ya.get(n);return s&&(n=s,c=Y),a?t?u:r:t?v:i}function O(n,t){return function(e){var r=Zo.event;Zo.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{Zo.event=r}}}function Y(n,t){var e=O(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function I(){var n=".dragsuppress-"+ ++Ma,t="click"+n,e=Zo.select(Wo).on("touchmove"+n,y).on("dragstart"+n,y).on("selectstart"+n,y);if(xa){var r=Bo.style,u=r[xa];r[xa]="none"}return function(i){function o(){e.on(t,null)}e.on(n,null),xa&&(r[xa]=u),i&&(e.on(t,function(){y(),o()},!0),setTimeout(o,0))}}function Z(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>_a&&(Wo.scrollX||Wo.scrollY)){e=Zo.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();_a=!(u.f||u.e),e.remove()}return _a?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var i=n.getBoundingClientRect();return[t.clientX-i.left-n.clientLeft,t.clientY-i.top-n.clientTop]}function V(){return Zo.event.changedTouches[0].identifier}function X(){return Zo.event.target}function $(){return Wo}function B(n){return n>0?1:0>n?-1:0}function W(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function J(n){return n>1?0:-1>n?ba:Math.acos(n)}function G(n){return n>1?Sa:-1>n?-Sa:Math.asin(n)}function K(n){return((n=Math.exp(n))-1/n)/2}function Q(n){return((n=Math.exp(n))+1/n)/2}function nt(n){return((n=Math.exp(2*n))-1)/(n+1)}function tt(n){return(n=Math.sin(n/2))*n}function et(){}function rt(n,t,e){return this instanceof rt?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof rt?new rt(n.h,n.s,n.l):mt(""+n,yt,rt):new rt(n,t,e)}function ut(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,new gt(u(n+120),u(n),u(n-120))}function it(n,t,e){return this instanceof it?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof it?new it(n.h,n.c,n.l):n instanceof at?st(n.l,n.a,n.b):st((n=xt((n=Zo.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new it(n,t,e)}function ot(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new at(e,Math.cos(n*=Aa)*t,Math.sin(n)*t)}function at(n,t,e){return this instanceof at?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof at?new at(n.l,n.a,n.b):n instanceof it?ot(n.l,n.c,n.h):xt((n=gt(n)).r,n.g,n.b):new at(n,t,e)}function ct(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=lt(u)*ja,r=lt(r)*Ha,i=lt(i)*Fa,new gt(ht(3.2404542*u-1.5371385*r-.4985314*i),ht(-.969266*u+1.8760108*r+.041556*i),ht(.0556434*u-.2040259*r+1.0572252*i))}function st(n,t,e){return n>0?new it(Math.atan2(e,t)*Ca,Math.sqrt(t*t+e*e),n):new it(0/0,0/0,n)}function lt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function ft(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function ht(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function gt(n,t,e){return this instanceof gt?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof gt?new gt(n.r,n.g,n.b):mt(""+n,gt,ut):new gt(n,t,e)}function pt(n){return new gt(n>>16,255&n>>8,255&n)}function vt(n){return pt(n)+""}function dt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function mt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/i.exec(n))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(_t(u[0]),_t(u[1]),_t(u[2]))}return(i=Ia.get(n))?t(i.r,i.g,i.b):(null==n||"#"!==n.charAt(0)||isNaN(i=parseInt(n.substring(1),16))||(4===n.length?(o=(3840&i)>>4,o=o>>4|o,a=240&i,a=a>>4|a,c=15&i,c=c<<4|c):7===n.length&&(o=(16711680&i)>>16,a=(65280&i)>>8,c=255&i)),t(o,a,c))}function yt(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),new rt(r,u,c)}function xt(n,t,e){n=Mt(n),t=Mt(t),e=Mt(e);var r=ft((.4124564*n+.3575761*t+.1804375*e)/ja),u=ft((.2126729*n+.7151522*t+.072175*e)/Ha),i=ft((.0193339*n+.119192*t+.9503041*e)/Fa);return at(116*u-16,500*(r-u),200*(u-i))}function Mt(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function _t(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function bt(n){return"function"==typeof n?n:function(){return n}}function wt(n){return n}function St(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),kt(t,e,n,r)}}function kt(n,t,e,r){function u(){var n,t=c.status;if(!t&&c.responseText||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return o.error.call(i,r),void 0}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=Zo.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,s=null;return!Wo.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=Zo.event;Zo.event=n;try{o.progress.call(i,c)}finally{Zo.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(s=n,i):s},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(Xo(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var l in a)c.setRequestHeader(l,a[l]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=s&&(c.responseType=s),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},Zo.rebind(i,o,"on"),null==r?i:i.get(Et(r))}function Et(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function At(){var n=Ct(),t=Nt()-n;t>24?(isFinite(t)&&(clearTimeout($a),$a=setTimeout(At,t)),Xa=0):(Xa=1,Wa(At))}function Ct(){var n=Date.now();for(Ba=Za;Ba;)n>=Ba.t&&(Ba.f=Ba.c(n-Ba.t)),Ba=Ba.n;return n}function Nt(){for(var n,t=Za,e=1/0;t;)t.f?t=n?n.n=t.n:Za=t.n:(t.t<e&&(e=t.t),t=(n=t).n);return Va=n,e}function zt(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Lt(n,t){var e=Math.pow(10,3*ua(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Tt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r?function(n){for(var t=n.length,u=[],i=0,o=r[0];t>0&&o>0;)u.push(n.substring(t-=o,t+o)),o=r[i=(i+1)%r.length];return u.reverse().join(e)}:wt;return function(n){var e=Ga.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"",c=e[4]||"",s=e[5],l=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1;switch(h&&(h=+h.substring(1)),(s||"0"===r&&"="===o)&&(s=r="0",o="=",f&&(l-=Math.floor((l-1)/4))),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=Ka.get(g)||qt;var y=s&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):a;if(0>p){var c=Zo.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x=n.lastIndexOf("."),M=0>x?n:n.substring(0,x),_=0>x?"":t+n.substring(x+1);!s&&f&&(M=i(M));var b=v.length+M.length+_.length+(y?0:u.length),w=l>b?new Array(b=l-b+1).join(r):"";return y&&(M=i(w+M)),u+=v,n=M+_,("<"===o?u+n+w:">"===o?w+u+n:"^"===o?w.substring(0,b>>=1)+u+n+w.substring(b):u+(y?n:w+n))+e}}}function qt(n){return n+""}function Rt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Dt(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new nc(e-1)),1),e}function i(n,e){return t(n=new nc(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{nc=Rt;var r=new Rt;return r._=n,o(r,t,e)}finally{nc=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Pt(n);return c.floor=c,c.round=Pt(r),c.ceil=Pt(u),c.offset=Pt(i),c.range=a,n}function Pt(n){return function(t,e){try{nc=Rt;var r=new Rt;return r._=t,n(r,e)._}finally{nc=Date}}}function Ut(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.substring(c,a)),null!=(u=ec[e=n.charAt(++a)])&&(e=n.charAt(++a)),(i=C[e])&&(e=i(t,null==u?"e"===e?" ":"0":u)),o.push(e),c=a+1);return o.push(n.substring(c,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},u=e(r,n,t,0);if(u!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var i=null!=r.Z&&nc!==Rt,o=new(i?Rt:nc);return"j"in r?o.setFullYear(r.y,0,r.j):"w"in r&&("W"in r||"U"in r)?(o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+Math.floor(r.Z/100),r.M+r.Z%100,r.S,r.L),i?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var u,i,o,a=0,c=t.length,s=e.length;c>a;){if(r>=s)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=N[o in ec?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){b.lastIndex=0;var r=b.exec(t.substring(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){M.lastIndex=0;var r=M.exec(t.substring(e));return r?(n.w=_.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.substring(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.substring(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,C.c.toString(),t,r)}function c(n,t,r){return e(n,C.x.toString(),t,r)}function s(n,t,r){return e(n,C.X.toString(),t,r)}function l(n,t,e){var r=x.get(t.substring(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{nc=Rt;var t=new nc;return t._=n,r(t)}finally{nc=Date}}var r=t(n);return e.parse=function(n){try{nc=Rt;var t=r.parse(n);return t&&t._}finally{nc=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=re;var x=Zo.map(),M=Ht(v),_=Ft(v),b=Ht(d),w=Ft(d),S=Ht(m),k=Ft(m),E=Ht(y),A=Ft(y);p.forEach(function(n,t){x.set(n.toLowerCase(),t)});var C={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return jt(n.getDate(),t,2)},e:function(n,t){return jt(n.getDate(),t,2)},H:function(n,t){return jt(n.getHours(),t,2)},I:function(n,t){return jt(n.getHours()%12||12,t,2)},j:function(n,t){return jt(1+Qa.dayOfYear(n),t,3)},L:function(n,t){return jt(n.getMilliseconds(),t,3)},m:function(n,t){return jt(n.getMonth()+1,t,2)},M:function(n,t){return jt(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return jt(n.getSeconds(),t,2)},U:function(n,t){return jt(Qa.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return jt(Qa.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return jt(n.getFullYear()%100,t,2)},Y:function(n,t){return jt(n.getFullYear()%1e4,t,4)},Z:te,"%":function(){return"%"}},N={a:r,A:u,b:i,B:o,c:a,d:Wt,e:Wt,H:Gt,I:Gt,j:Jt,L:ne,m:Bt,M:Kt,p:l,S:Qt,U:Yt,w:Ot,W:It,x:c,X:s,y:Vt,Y:Zt,Z:Xt,"%":ee};return t}function jt(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function Ht(n){return new RegExp("^(?:"+n.map(Zo.requote).join("|")+")","i")}function Ft(n){for(var t=new o,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function Ot(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Yt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e));return r?(n.U=+r[0],e+r[0].length):-1}function It(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e));return r?(n.W=+r[0],e+r[0].length):-1}function Zt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Vt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.y=$t(+r[0]),e+r[0].length):-1}function Xt(n,t,e){return/^[+-]\d{4}$/.test(t=t.substring(e,e+5))?(n.Z=-t,e+5):-1}function $t(n){return n+(n>68?1900:2e3)}function Bt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Wt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function Jt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function Gt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function Kt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function Qt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ne(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function te(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=~~(ua(t)/60),u=ua(t)%60;return e+jt(r,"0",2)+jt(u,"0",2)}function ee(n,t,e){uc.lastIndex=0;var r=uc.exec(t.substring(e,e+1));return r?e+r[0].length:-1}function re(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function ue(){}function ie(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function oe(n,t){n&&cc.hasOwnProperty(n.type)&&cc[n.type](n,t)}function ae(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++u<i;)r=n[u],t.point(r[0],r[1],r[2]);t.lineEnd()}function ce(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)ae(n[e],t,1);t.polygonEnd()}function se(){function n(n,t){n*=Aa,t=t*Aa/2+ba/4;var e=n-r,o=e>=0?1:-1,a=o*e,c=Math.cos(t),s=Math.sin(t),l=i*s,f=u*c+l*Math.cos(a),h=l*o*Math.sin(a);lc.add(Math.atan2(h,f)),r=n,u=c,i=s}var t,e,r,u,i;fc.point=function(o,a){fc.point=n,r=(t=o)*Aa,u=Math.cos(a=(e=a)*Aa/2+ba/4),i=Math.sin(a)},fc.lineEnd=function(){n(t,e)}}function le(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function fe(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function he(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function ge(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function pe(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function ve(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function de(n){return[Math.atan2(n[1],n[0]),G(n[2])]}function me(n,t){return ua(n[0]-t[0])<ka&&ua(n[1]-t[1])<ka}function ye(n,t){n*=Aa;var e=Math.cos(t*=Aa);xe(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function xe(n,t,e){++hc,pc+=(n-pc)/hc,vc+=(t-vc)/hc,dc+=(e-dc)/hc}function Me(){function n(n,u){n*=Aa;var i=Math.cos(u*=Aa),o=i*Math.cos(n),a=i*Math.sin(n),c=Math.sin(u),s=Math.atan2(Math.sqrt((s=e*c-r*a)*s+(s=r*o-t*c)*s+(s=t*a-e*o)*s),t*o+e*a+r*c);gc+=s,mc+=s*(t+(t=o)),yc+=s*(e+(e=a)),xc+=s*(r+(r=c)),xe(t,e,r)}var t,e,r;wc.point=function(u,i){u*=Aa;var o=Math.cos(i*=Aa);t=o*Math.cos(u),e=o*Math.sin(u),r=Math.sin(i),wc.point=n,xe(t,e,r)}}function _e(){wc.point=ye}function be(){function n(n,t){n*=Aa;var e=Math.cos(t*=Aa),o=e*Math.cos(n),a=e*Math.sin(n),c=Math.sin(t),s=u*c-i*a,l=i*o-r*c,f=r*a-u*o,h=Math.sqrt(s*s+l*l+f*f),g=r*o+u*a+i*c,p=h&&-J(g)/h,v=Math.atan2(h,g);Mc+=p*s,_c+=p*l,bc+=p*f,gc+=v,mc+=v*(r+(r=o)),yc+=v*(u+(u=a)),xc+=v*(i+(i=c)),xe(r,u,i)}var t,e,r,u,i;wc.point=function(o,a){t=o,e=a,wc.point=n,o*=Aa;var c=Math.cos(a*=Aa);r=c*Math.cos(o),u=c*Math.sin(o),i=Math.sin(a),xe(r,u,i)},wc.lineEnd=function(){n(t,e),wc.lineEnd=_e,wc.point=ye}}function we(){return!0}function Se(n,t,e,r,u){var i=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(me(e,r)){u.lineStart();for(var a=0;t>a;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c=new Ee(e,n,null,!0),s=new Ee(e,null,c,!1);c.o=s,i.push(c),o.push(s),c=new Ee(r,n,null,!1),s=new Ee(r,null,c,!0),c.o=s,i.push(c),o.push(s)}}),o.sort(t),ke(i),ke(o),i.length){for(var a=0,c=e,s=o.length;s>a;++a)o[a].e=c=!c;for(var l,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;l=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,s=l.length;s>a;++a)u.point((f=l[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){l=g.p.z;for(var a=l.length-1;a>=0;--a)u.point((f=l[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,l=g.z,p=!p}while(!g.v);u.lineEnd()}}}function ke(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r<t;)u.n=e=n[r],e.p=u,u=e;u.n=e=n[0],e.p=u}}function Ee(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Ae(n,t,e,r){return function(u,i){function o(t,e){var r=u(t,e);n(t=r[0],e=r[1])&&i.point(t,e)}function a(n,t){var e=u(n,t);d.point(e[0],e[1])}function c(){y.point=a,d.lineStart()}function s(){y.point=o,d.lineEnd()}function l(n,t){v.push([n,t]);var e=u(n,t);M.point(e[0],e[1])}function f(){M.lineStart(),v=[]}function h(){l(v[0][0],v[0][1]),M.lineEnd();var n,t=M.clean(),e=x.buffer(),r=e.length;if(v.pop(),p.push(v),v=null,r)if(1&t){n=e[0];var u,r=n.length-1,o=-1;if(r>0){for(_||(i.polygonStart(),_=!0),i.lineStart();++o<r;)i.point((u=n[o])[0],u[1]);i.lineEnd()}}else r>1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Ce))}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:s,polygonStart:function(){y.point=l,y.lineStart=f,y.lineEnd=h,g=[],p=[]},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=s,g=Zo.merge(g);var n=Le(m,p);g.length?(_||(i.polygonStart(),_=!0),Se(g,ze,n,e,i)):n&&(_||(i.polygonStart(),_=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),_&&(i.polygonEnd(),_=!1),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},x=Ne(),M=t(x),_=!1;return y}}function Ce(n){return n.length>1}function Ne(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:v,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function ze(n,t){return((n=n.x)[0]<0?n[1]-Sa-ka:Sa-n[1])-((t=t.x)[0]<0?t[1]-Sa-ka:Sa-t[1])}function Le(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;lc.reset();for(var a=0,c=t.length;c>a;++a){var s=t[a],l=s.length;if(l)for(var f=s[0],h=f[0],g=f[1]/2+ba/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===l&&(d=0),n=s[d];var m=n[0],y=n[1]/2+ba/4,x=Math.sin(y),M=Math.cos(y),_=m-h,b=_>=0?1:-1,w=b*_,S=w>ba,k=p*x;if(lc.add(Math.atan2(k*b*Math.sin(w),v*M+k*Math.cos(w))),i+=S?_+b*wa:_,S^h>=e^m>=e){var E=he(le(f),le(n));ve(E);var A=he(u,E);ve(A);var C=(S^_>=0?-1:1)*G(A[2]);(r>C||r===C&&(E[0]||E[1]))&&(o+=S^_>=0?1:-1)}if(!d++)break;h=m,p=x,v=M,f=n}}return(-ka>i||ka>i&&0>lc)^1&o}function Te(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?ba:-ba,c=ua(i-e);ua(c-ba)<ka?(n.point(e,r=(r+o)/2>0?Sa:-Sa),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=ba&&(ua(e-u)<ka&&(e-=u*ka),ua(i-a)<ka&&(i-=a*ka),r=qe(e,r,i,o),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=i,r=o),u=a},lineEnd:function(){n.lineEnd(),e=r=0/0},clean:function(){return 2-t}}}function qe(n,t,e,r){var u,i,o=Math.sin(n-e);return ua(o)>ka?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function Re(n,t,e,r){var u;if(null==n)u=e*Sa,r.point(-ba,u),r.point(0,u),r.point(ba,u),r.point(ba,0),r.point(ba,-u),r.point(0,-u),r.point(-ba,-u),r.point(-ba,0),r.point(-ba,u);else if(ua(n[0]-t[0])>ka){var i=n[0]<t[0]?ba:-ba;u=e*i/2,r.point(-i,u),r.point(0,u),r.point(i,u)}else r.point(t[0],t[1])}function De(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,s,l;return{lineStart:function(){s=c=!1,l=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?ba:-ba),h):0;if(!e&&(s=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(me(e,g)||me(p,g))&&(p[0]+=ka,p[1]+=ka,v=t(p[0],p[1]))),v!==c)l=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(l=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&me(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return l|(s&&c)<<1}}}function r(n,t,e){var r=le(n),u=le(t),o=[1,0,0],a=he(r,u),c=fe(a,a),s=a[0],l=c-s*s;if(!l)return!e&&n;var f=i*c/l,h=-i*s/l,g=he(o,a),p=pe(o,f),v=pe(a,h);ge(p,v);var d=g,m=fe(p,d),y=fe(d,d),x=m*m-y*(fe(p,p)-1);if(!(0>x)){var M=Math.sqrt(x),_=pe(d,(-m-M)/y);if(ge(_,p),_=de(_),!e)return _;var b,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(b=w,w=S,S=b);var A=S-w,C=ua(A-ba)<ka,N=C||ka>A;if(!C&&k>E&&(b=k,k=E,E=b),N?C?k+E>0^_[1]<(ua(_[0]-w)<ka?k:E):k<=_[1]&&_[1]<=E:A>ba^(w<=_[0]&&_[0]<=S)){var z=pe(d,(-m+M)/y);return ge(z,p),[_,de(z)]}}}function u(t,e){var r=o?n:ba-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=ua(i)>ka,c=sr(n,6*Aa);return Ae(t,e,c,o?[0,-n]:[-ba,n-ba])}function Pe(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,s=o.y,l=a.x,f=a.y,h=0,g=1,p=l-c,v=f-s;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-s,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-s,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:s+h*v}),1>g&&(u.b={x:c+g*p,y:s+g*v}),u}}}}}}function Ue(n,t,e,r){function u(r,u){return ua(r[0]-n)<ka?u>0?0:3:ua(r[0]-e)<ka?u>0?2:1:ua(r[1]-t)<ka?u>0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,s=a[0];c>o;++o)i=a[o],s[1]<=r?i[1]>r&&W(s,i,n)>0&&++t:i[1]<=r&&W(s,i,n)<0&&--t,s=i;return 0!==t}function s(i,a,c,s){var l=0,f=0;if(null==i||(l=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do s.point(0===l||3===l?n:e,l>1?r:t);while((l=(l+c+4)%4)!==f)}else s.point(a[0],a[1])}function l(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){l(n,t)&&a.point(n,t)}function h(){N.point=p,d&&d.push(m=[]),S=!0,w=!1,_=b=0/0}function g(){v&&(p(y,x),M&&w&&A.rejoin(),v.push(A.buffer())),N.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-kc,Math.min(kc,n)),t=Math.max(-kc,Math.min(kc,t));var e=l(n,t);if(d&&m.push([n,t]),S)y=n,x=t,M=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:_,y:b},b:{x:n,y:t}};C(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}_=n,b=t,w=e}var v,d,m,y,x,M,_,b,w,S,k,E=a,A=Ne(),C=Pe(n,t,e,r),N={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=Zo.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),s(null,null,1,a),a.lineEnd()),u&&Se(v,i,t,s,a),a.polygonEnd()),v=d=m=null}};return N}}function je(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function He(n){var t=0,e=ba/3,r=tr(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*ba/180,e=n[1]*ba/180):[180*(t/ba),180*(e/ba)]},u}function Fe(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,G((i-(n*n+e*e)*u*u)/(2*u))]},e}function Oe(){function n(n,t){Ac+=u*n-r*t,r=n,u=t}var t,e,r,u;Tc.point=function(i,o){Tc.point=n,t=r=i,e=u=o},Tc.lineEnd=function(){n(t,e)}}function Ye(n,t){Cc>n&&(Cc=n),n>zc&&(zc=n),Nc>t&&(Nc=t),t>Lc&&(Lc=t)}function Ie(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Ze(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Ze(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Ze(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Ve(n,t){pc+=n,vc+=t,++dc}function Xe(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);mc+=o*(t+n)/2,yc+=o*(e+r)/2,xc+=o,Ve(t=n,e=r)}var t,e;Rc.point=function(r,u){Rc.point=n,Ve(t=r,e=u)}}function $e(){Rc.point=Ve}function Be(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);mc+=o*(r+n)/2,yc+=o*(u+t)/2,xc+=o,o=u*n-r*t,Mc+=o*(r+n),_c+=o*(u+t),bc+=3*o,Ve(r=n,u=t)}var t,e,r,u;Rc.point=function(i,o){Rc.point=n,Ve(t=r=i,e=u=o)},Rc.lineEnd=function(){n(t,e)}}function We(n){function t(t,e){n.moveTo(t,e),n.arc(t,e,o,0,wa)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:v};return a}function Je(n){function t(n){return(a?r:e)(n)}function e(t){return Qe(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){x=0/0,S.point=i,t.lineStart()}function i(e,r){var i=le([e,r]),o=n(e,r);u(x,M,y,_,b,w,x=o[0],M=o[1],y=e,_=i[0],b=i[1],w=i[2],a,t),t.point(x,M)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=s,S.lineEnd=l}function s(n,t){i(f=n,h=t),g=x,p=M,v=_,d=b,m=w,S.point=i}function l(){u(x,M,y,_,b,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,x,M,_,b,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,s,l,f,h,g,p,v,d,m){var y=l-t,x=f-e,M=y*y+x*x;if(M>4*i&&d--){var _=a+g,b=c+p,w=s+v,S=Math.sqrt(_*_+b*b+w*w),k=Math.asin(w/=S),E=ua(ua(w)-1)<ka||ua(r-h)<ka?(r+h)/2:Math.atan2(b,_),A=n(E,k),C=A[0],N=A[1],z=C-t,L=N-e,T=x*z-y*L;(T*T/M>i||ua((y*z+x*L)/M-.5)>.3||o>a*g+c*p+s*v)&&(u(t,e,r,a,c,s,C,N,E,_/=S,b/=S,w,d,m),m.point(C,N),u(C,N,E,_,b,w,l,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Aa),a=16; +return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function Ge(n){var t=Je(function(t,e){return n([t*Ca,e*Ca])});return function(n){return er(t(n))}}function Ke(n){this.stream=n}function Qe(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function nr(n){return tr(function(){return n})()}function tr(n){function t(n){return n=a(n[0]*Aa,n[1]*Aa),[n[0]*h+c,s-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(s-n[1])/h),n&&[n[0]*Ca,n[1]*Ca]}function r(){a=je(o=ir(m,y,x),i);var n=i(v,d);return c=g-n[0]*h,s=p+n[1]*h,u()}function u(){return l&&(l.valid=!1,l=null),t}var i,o,a,c,s,l,f=Je(function(n,t){return n=i(n,t),[n[0]*h+c,s-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,y=0,x=0,M=Sc,_=wt,b=null,w=null;return t.stream=function(n){return l&&(l.valid=!1),l=er(M(o,f(_(n)))),l.valid=!0,l},t.clipAngle=function(n){return arguments.length?(M=null==n?(b=n,Sc):De((b=+n)*Aa),u()):b},t.clipExtent=function(n){return arguments.length?(w=n,_=n?Ue(n[0][0],n[0][1],n[1][0],n[1][1]):wt,u()):w},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Aa,d=n[1]%360*Aa,r()):[v*Ca,d*Ca]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Aa,y=n[1]%360*Aa,x=n.length>2?n[2]%360*Aa:0,r()):[m*Ca,y*Ca,x*Ca]},Zo.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function er(n){return Qe(n,function(t,e){n.point(t*Aa,e*Aa)})}function rr(n,t){return[n,t]}function ur(n,t){return[n>ba?n-wa:-ba>n?n+wa:n,t]}function ir(n,t,e){return n?t||e?je(ar(n),cr(t,e)):ar(n):t||e?cr(t,e):ur}function or(n){return function(t,e){return t+=n,[t>ba?t-wa:-ba>t?t+wa:t,e]}}function ar(n){var t=or(n);return t.invert=or(-n),t}function cr(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*r+a*u;return[Math.atan2(c*i-l*o,a*r-s*u),G(l*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*i-c*o;return[Math.atan2(c*i+s*o,a*r+l*u),G(l*r-a*u)]},e}function sr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=lr(e,u),i=lr(e,i),(o>0?i>u:u>i)&&(u+=o*wa)):(u=n+o*wa,i=n-.5*c);for(var s,l=u;o>0?l>i:i>l;l-=c)a.point((s=de([e,-r*Math.cos(l),-r*Math.sin(l)]))[0],s[1])}}function lr(n,t){var e=le(t);e[0]-=n,ve(e);var r=J(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-ka)%(2*Math.PI)}function fr(n,t,e){var r=Zo.range(n,t-ka,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function hr(n,t,e){var r=Zo.range(n,t-ka,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function gr(n){return n.source}function pr(n){return n.target}function vr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),s=u*Math.sin(n),l=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(tt(r-t)+u*o*tt(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*l,u=e*s+t*f,o=e*i+t*a;return[Math.atan2(u,r)*Ca,Math.atan2(o,Math.sqrt(r*r+u*u))*Ca]}:function(){return[n*Ca,t*Ca]};return p.distance=h,p}function dr(){function n(n,u){var i=Math.sin(u*=Aa),o=Math.cos(u),a=ua((n*=Aa)-t),c=Math.cos(a);Dc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;Pc.point=function(u,i){t=u*Aa,e=Math.sin(i*=Aa),r=Math.cos(i),Pc.point=n},Pc.lineEnd=function(){Pc.point=Pc.lineEnd=v}}function mr(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function yr(n,t){function e(n,t){o>0?-Sa+ka>t&&(t=-Sa+ka):t>Sa-ka&&(t=Sa-ka);var e=o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(ba/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=B(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Sa]},e):Mr}function xr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return ua(u)<ka?rr:(e.invert=function(n,t){var e=i-t;return[Math.atan2(n,e)/u,i-B(u)*Math.sqrt(n*n+e*e)]},e)}function Mr(n,t){return[n,Math.log(Math.tan(ba/4+t/2))]}function _r(n){var t,e=nr(n),r=e.scale,u=e.translate,i=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=u.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=i.apply(e,arguments);if(o===e){if(t=null==n){var a=ba*r(),c=u();i([[c[0]-a,c[1]-a],[c[0]+a,c[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function br(n,t){return[Math.log(Math.tan(ba/4+t/2)),-n]}function wr(n){return n[0]}function Sr(n){return n[1]}function kr(n){for(var t=n.length,e=[0,1],r=2,u=2;t>u;u++){for(;r>1&&W(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function Er(n,t){return n[0]-t[0]||n[1]-t[1]}function Ar(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Cr(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],s=e[1],l=t[1]-c,f=r[1]-s,h=(a*(c-s)-f*(u-i))/(f*o-a*l);return[u+h*o,c+h*l]}function Nr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function zr(){Gr(this),this.edge=this.site=this.circle=null}function Lr(n){var t=Bc.pop()||new zr;return t.site=n,t}function Tr(n){Yr(n),Vc.remove(n),Bc.push(n),Gr(n)}function qr(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Tr(n);for(var c=i;c.circle&&ua(e-c.circle.x)<ka&&ua(r-c.circle.cy)<ka;)i=c.P,a.unshift(c),Tr(c),c=i;a.unshift(c),Yr(c);for(var s=o;s.circle&&ua(e-s.circle.x)<ka&&ua(r-s.circle.cy)<ka;)o=s.N,a.push(s),Tr(s),s=o;a.push(s),Yr(s);var l,f=a.length;for(l=1;f>l;++l)s=a[l],c=a[l-1],Br(s.edge,c.site,s.site,u);c=a[0],s=a[f-1],s.edge=Xr(c.site,s.site,null,u),Or(c),Or(s)}function Rr(n){for(var t,e,r,u,i=n.x,o=n.y,a=Vc._;a;)if(r=Dr(a,o)-i,r>ka)a=a.L;else{if(u=i-Pr(a,o),!(u>ka)){r>-ka?(t=a.P,e=a):u>-ka?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Lr(n);if(Vc.insert(t,c),t||e){if(t===e)return Yr(t),e=Lr(t.site),Vc.insert(c,e),c.edge=e.edge=Xr(t.site,c.site),Or(t),Or(e),void 0;if(!e)return c.edge=Xr(t.site,c.site),void 0;Yr(t),Yr(e);var s=t.site,l=s.x,f=s.y,h=n.x-l,g=n.y-f,p=e.site,v=p.x-l,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,x=v*v+d*d,M={x:(d*y-g*x)/m+l,y:(h*x-v*y)/m+f};Br(e.edge,s,p,M),c.edge=Xr(s,n,null,M),e.edge=Xr(n,p,null,M),Or(t),Or(e)}}function Dr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,s=c-t;if(!s)return a;var l=a-r,f=1/i-1/s,h=l/s;return f?(-h+Math.sqrt(h*h-2*f*(l*l/(-2*s)-c+s/2+u-i/2)))/f+r:(r+a)/2}function Pr(n,t){var e=n.N;if(e)return Dr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Ur(n){this.site=n,this.edges=[]}function jr(n){for(var t,e,r,u,i,o,a,c,s,l,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Zc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)l=a[o].end(),r=l.x,u=l.y,s=a[++o%c].start(),t=s.x,e=s.y,(ua(r-t)>ka||ua(u-e)>ka)&&(a.splice(o,0,new Wr($r(i.site,l,ua(r-f)<ka&&p-u>ka?{x:f,y:ua(t-f)<ka?e:p}:ua(u-p)<ka&&h-r>ka?{x:ua(e-p)<ka?t:h,y:p}:ua(r-h)<ka&&u-g>ka?{x:h,y:ua(t-h)<ka?e:g}:ua(u-g)<ka&&r-f>ka?{x:ua(e-g)<ka?t:f,y:g}:null),i.site,null)),++c)}function Hr(n,t){return t.angle-n.angle}function Fr(){Gr(this),this.x=this.y=this.arc=this.site=this.cy=null}function Or(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,u=n.site,i=e.site;if(r!==i){var o=u.x,a=u.y,c=r.x-o,s=r.y-a,l=i.x-o,f=i.y-a,h=2*(c*f-s*l);if(!(h>=-Ea)){var g=c*c+s*s,p=l*l+f*f,v=(f*g-s*p)/h,d=(c*p-l*g)/h,f=d+a,m=Wc.pop()||new Fr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,x=$c._;x;)if(m.y<x.y||m.y===x.y&&m.x<=x.x){if(!x.L){y=x.P;break}x=x.L}else{if(!x.R){y=x;break}x=x.R}$c.insert(y,m),y||(Xc=m)}}}}function Yr(n){var t=n.circle;t&&(t.P||(Xc=t.N),$c.remove(t),Wc.push(t),Gr(t),n.circle=null)}function Ir(n){for(var t,e=Ic,r=Pe(n[0][0],n[0][1],n[1][0],n[1][1]),u=e.length;u--;)t=e[u],(!Zr(t,n)||!r(t)||ua(t.a.x-t.b.x)<ka&&ua(t.a.y-t.b.y)<ka)&&(t.a=t.b=null,e.splice(u,1))}function Zr(n,t){var e=n.b;if(e)return!0;var r,u,i=n.a,o=t[0][0],a=t[1][0],c=t[0][1],s=t[1][1],l=n.l,f=n.r,h=l.x,g=l.y,p=f.x,v=f.y,d=(h+p)/2,m=(g+v)/2;if(v===g){if(o>d||d>=a)return;if(h>p){if(i){if(i.y>=s)return}else i={x:d,y:c};e={x:d,y:s}}else{if(i){if(i.y<c)return}else i={x:d,y:s};e={x:d,y:c}}}else if(r=(h-p)/(v-g),u=m-r*d,-1>r||r>1)if(h>p){if(i){if(i.y>=s)return}else i={x:(c-u)/r,y:c};e={x:(s-u)/r,y:s}}else{if(i){if(i.y<c)return}else i={x:(s-u)/r,y:s};e={x:(c-u)/r,y:c}}else if(v>g){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.x<o)return}else i={x:a,y:r*a+u};e={x:o,y:r*o+u}}return n.a=i,n.b=e,!0}function Vr(n,t){this.l=n,this.r=t,this.a=this.b=null}function Xr(n,t,e,r){var u=new Vr(n,t);return Ic.push(u),e&&Br(u,n,t,e),r&&Br(u,t,n,r),Zc[n.i].edges.push(new Wr(u,n,t)),Zc[t.i].edges.push(new Wr(u,t,n)),u}function $r(n,t,e){var r=new Vr(n,null);return r.a=t,r.b=e,Ic.push(r),r}function Br(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function Wr(n,t,e){var r=n.a,u=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(u.x-r.x,r.y-u.y):Math.atan2(r.x-u.x,u.y-r.y)}function Jr(){this._=null}function Gr(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function Kr(n,t){var e=t,r=t.R,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function Qr(n,t){var e=t,r=t.L,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function nu(n){for(;n.L;)n=n.L;return n}function tu(n,t){var e,r,u,i=n.sort(eu).pop();for(Ic=[],Zc=new Array(n.length),Vc=new Jr,$c=new Jr;;)if(u=Xc,i&&(!u||i.y<u.y||i.y===u.y&&i.x<u.x))(i.x!==e||i.y!==r)&&(Zc[i.i]=new Ur(i),Rr(i),e=i.x,r=i.y),i=n.pop();else{if(!u)break;qr(u.arc)}t&&(Ir(t),jr(t));var o={cells:Zc,edges:Ic};return Vc=$c=Ic=Zc=null,o}function eu(n,t){return t.y-n.y||t.x-n.x}function ru(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function uu(n){return n.x}function iu(n){return n.y}function ou(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function au(n,t,e,r,u,i){if(!n(t,e,r,u,i)){var o=.5*(e+u),a=.5*(r+i),c=t.nodes;c[0]&&au(n,c[0],e,r,o,a),c[1]&&au(n,c[1],o,r,u,a),c[2]&&au(n,c[2],e,a,o,i),c[3]&&au(n,c[3],o,a,u,i)}}function cu(n,t){n=Zo.rgb(n),t=Zo.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+dt(Math.round(e+i*n))+dt(Math.round(r+o*n))+dt(Math.round(u+a*n))}}function su(n,t){var e,r={},u={};for(e in n)e in t?r[e]=hu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function lu(n,t){return t-=n=+n,function(e){return n+t*e}}function fu(n,t){var e,r,u,i=Gc.lastIndex=Kc.lastIndex=0,o=-1,a=[],c=[];for(n+="",t+="";(e=Gc.exec(n))&&(r=Kc.exec(t));)(u=r.index)>i&&(u=t.substring(i,u),a[o]?a[o]+=u:a[++o]=u),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,c.push({i:o,x:lu(e,r)})),i=Kc.lastIndex;return i<t.length&&(u=t.substring(i),a[o]?a[o]+=u:a[++o]=u),a.length<2?c[0]?(t=c[0].x,function(n){return t(n)+""}):function(){return t}:(t=c.length,function(n){for(var e,r=0;t>r;++r)a[(e=c[r]).i]=e.x(n);return a.join("")})}function hu(n,t){for(var e,r=Zo.interpolators.length;--r>=0&&!(e=Zo.interpolators[r](n,t)););return e}function gu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(hu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function pu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function vu(n){return function(t){return 1-n(1-t)}}function du(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function mu(n){return n*n}function yu(n){return n*n*n}function xu(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function Mu(n){return function(t){return Math.pow(t,n)}}function _u(n){return 1-Math.cos(n*Sa)}function bu(n){return Math.pow(2,10*(n-1))}function wu(n){return 1-Math.sqrt(1-n*n)}function Su(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/wa*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*wa/t)}}function ku(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function Eu(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Au(n,t){n=Zo.hcl(n),t=Zo.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return ot(e+i*n,r+o*n,u+a*n)+""}}function Cu(n,t){n=Zo.hsl(n),t=Zo.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return ut(e+i*n,r+o*n,u+a*n)+""}}function Nu(n,t){n=Zo.lab(n),t=Zo.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ct(e+i*n,r+o*n,u+a*n)+""}}function zu(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Lu(n){var t=[n.a,n.b],e=[n.c,n.d],r=qu(t),u=Tu(t,e),i=qu(Ru(e,t,-u))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,u*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*Ca,this.translate=[n.e,n.f],this.scale=[r,i],this.skew=i?Math.atan2(u,i)*Ca:0}function Tu(n,t){return n[0]*t[0]+n[1]*t[1]}function qu(n){var t=Math.sqrt(Tu(n,n));return t&&(n[0]/=t,n[1]/=t),t}function Ru(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Du(n,t){var e,r=[],u=[],i=Zo.transform(n),o=Zo.transform(t),a=i.translate,c=o.translate,s=i.rotate,l=o.rotate,f=i.skew,h=o.skew,g=i.scale,p=o.scale;return a[0]!=c[0]||a[1]!=c[1]?(r.push("translate(",null,",",null,")"),u.push({i:1,x:lu(a[0],c[0])},{i:3,x:lu(a[1],c[1])})):c[0]||c[1]?r.push("translate("+c+")"):r.push(""),s!=l?(s-l>180?l+=360:l-s>180&&(s+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:lu(s,l)})):l&&r.push(r.pop()+"rotate("+l+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:lu(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:lu(g[0],p[0])},{i:e-2,x:lu(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i<e;)r[(t=u[i]).i]=t.x(n);return r.join("")}}function Pu(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return(e-n)*t}}function Uu(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return Math.max(0,Math.min(1,(e-n)*t))}}function ju(n){for(var t=n.source,e=n.target,r=Fu(t,e),u=[t];t!==r;)t=t.parent,u.push(t);for(var i=u.length;e!==r;)u.splice(i,0,e),e=e.parent;return u}function Hu(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Fu(n,t){if(n===t)return n;for(var e=Hu(n),r=Hu(t),u=e.pop(),i=r.pop(),o=null;u===i;)o=u,u=e.pop(),i=r.pop();return o}function Ou(n){n.fixed|=2}function Yu(n){n.fixed&=-7}function Iu(n){n.fixed|=4,n.px=n.x,n.py=n.y}function Zu(n){n.fixed&=-5}function Vu(n,t,e){var r=0,u=0;if(n.charge=0,!n.leaf)for(var i,o=n.nodes,a=o.length,c=-1;++c<a;)i=o[c],null!=i&&(Vu(i,t,e),n.charge+=i.charge,r+=i.charge*i.cx,u+=i.charge*i.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var s=t*e[n.point.index];n.charge+=n.pointCharge=s,r+=s*n.point.x,u+=s*n.point.y}n.cx=r/n.charge,n.cy=u/n.charge}function Xu(n,t){return Zo.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=Ku,n}function $u(n,t){for(var e=[n];null!=(n=e.pop());)if(t(n),(u=n.children)&&(r=u.length))for(var r,u;--r>=0;)e.push(u[r])}function Bu(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(i=n.children)&&(u=i.length))for(var u,i,o=-1;++o<u;)e.push(i[o]);for(;null!=(n=r.pop());)t(n)}function Wu(n){return n.children}function Ju(n){return n.value}function Gu(n,t){return t.value-n.value}function Ku(n){return Zo.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function Qu(n){return n.x}function ni(n){return n.y}function ti(n,t,e){n.y0=t,n.y=e}function ei(n){return Zo.range(n.length)}function ri(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function ui(n){for(var t,e=1,r=0,u=n[0][1],i=n.length;i>e;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function ii(n){return n.reduce(oi,0)}function oi(n,t){return n+t[1]}function ai(n,t){return ci(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function ci(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function si(n){return[Zo.min(n),Zo.max(n)]}function li(n,t){return n.value-t.value}function fi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function hi(n,t){n._pack_next=t,t._pack_prev=n}function gi(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function pi(n){function t(n){l=Math.min(n.x-n.r,l),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(s=e.length)){var e,r,u,i,o,a,c,s,l=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(vi),r=e[0],r.x=-r.r,r.y=0,t(r),s>1&&(u=e[1],u.x=u.r,u.y=0,t(u),s>2))for(i=e[2],yi(r,u,i),t(i),fi(r,i),r._pack_prev=i,fi(i,u),u=r._pack_next,o=3;s>o;o++){yi(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(gi(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!gi(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.r<r.r?hi(r,u=a):hi(r=c,u),o--):(fi(r,i),u=i,t(i))}var m=(l+f)/2,y=(h+g)/2,x=0;for(o=0;s>o;o++)i=e[o],i.x-=m,i.y-=y,x=Math.max(x,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=x,e.forEach(di)}}function vi(n){n._pack_next=n._pack_prev=n}function di(n){delete n._pack_next,delete n._pack_prev}function mi(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i<o;)mi(u[i],t,e,r)}function yi(n,t,e){var r=n.r+e.r,u=t.x-n.x,i=t.y-n.y;if(r&&(u||i)){var o=t.r+e.r,a=u*u+i*i;o*=o,r*=r;var c=.5+(r-o)/(2*a),s=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+c*u+s*i,e.y=n.y+c*i-s*u}else e.x=n.x+r,e.y=n.y}function xi(n,t){return n.parent==t.parent?1:2}function Mi(n){var t=n.children;return t.length?t[0]:n.t}function _i(n){var t,e=n.children;return(t=e.length)?e[t-1]:n.t}function bi(n,t,e){var r=e/(t.i-n.i);t.c-=r,t.s+=e,n.c+=r,t.z+=e,t.m+=e}function wi(n){for(var t,e=0,r=0,u=n.children,i=u.length;--i>=0;)t=u[i],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Si(n,t,e){return n.a.parent===t.parent?n.a:e}function ki(n){return 1+Zo.max(n,function(n){return n.y})}function Ei(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Ai(n){var t=n.children;return t&&t.length?Ai(t[0]):n}function Ci(n){var t,e=n.children;return e&&(t=e.length)?Ci(e[t-1]):n}function Ni(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function zi(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function Li(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ti(n){return n.rangeExtent?n.rangeExtent():Li(n.range())}function qi(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Ri(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Di(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ss}function Pi(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)u.push(e(n[o-1],n[o])),i.push(r(t[o-1],t[o]));return function(t){var e=Zo.bisect(n,t,1,a)-1;return i[e](u[e](t))}}function Ui(n,t,e,r){function u(){var u=Math.min(n.length,t.length)>2?Pi:qi,c=r?Uu:Pu;return o=u(n,t,c,e),a=u(t,n,c,hu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(zu)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Oi(n,t)},i.tickFormat=function(t,e){return Yi(n,t,e)},i.nice=function(t){return Hi(n,t),u()},i.copy=function(){return Ui(n,t,e,r)},u()}function ji(n,t){return Zo.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Hi(n,t){return Ri(n,Di(Fi(n,t)[2]))}function Fi(n,t){null==t&&(t=10);var e=Li(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Oi(n,t){return Zo.range.apply(Zo,Fi(n,t))}function Yi(n,t,e){var r=Fi(n,t);if(e){var u=Ga.exec(e);if(u.shift(),"s"===u[8]){var i=Zo.formatPrefix(Math.max(ua(r[0]),ua(r[1])));return u[7]||(u[7]="."+Ii(i.scale(r[2]))),u[8]="f",e=Zo.format(u.join("")),function(n){return e(i.scale(n))+i.symbol}}u[7]||(u[7]="."+Zi(u[8],r)),e=u.join("")}else e=",."+Ii(r[2])+"f";return Zo.format(e)}function Ii(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Zi(n,t){var e=Ii(t[2]);return n in ls?Math.abs(e-Ii(Math.max(ua(t[0]),ua(t[1]))))+ +("e"!==n):e-2*("%"===n)}function Vi(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Ri(r.map(u),e?Math:hs);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=Li(r),o=[],a=n[0],c=n[1],s=Math.floor(u(a)),l=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(l-s)){if(e){for(;l>s;s++)for(var h=1;f>h;h++)o.push(i(s)*h);o.push(i(s))}else for(o.push(i(s));s++<l;)for(var h=f-1;h>0;h--)o.push(i(s)*h);for(s=0;o[s]<a;s++);for(l=o.length;o[l-1]>c;l--);o=o.slice(s,l)}return o},o.tickFormat=function(n,t){if(!arguments.length)return fs;arguments.length<2?t=fs:"function"!=typeof t&&(t=Zo.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return Vi(n.copy(),t,e,r)},ji(o,n)}function Xi(n,t,e){function r(t){return n(u(t))}var u=$i(t),i=$i(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Oi(e,n)},r.tickFormat=function(n,t){return Yi(e,n,t)},r.nice=function(n){return r.domain(Hi(e,n))},r.exponent=function(o){return arguments.length?(u=$i(t=o),i=$i(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Xi(n.copy(),t,e)},ji(r,n)}function $i(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Bi(n,t){function e(e){return i[((u.get(e)||("range"===t.t?u.set(e,n.push(e)):0/0))-1)%i.length]}function r(t,e){return Zo.range(n.length).map(function(n){return t+e*n})}var u,i,a;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new o;for(var i,a=-1,c=r.length;++a<c;)u.has(i=r[a])||u.set(i,n.push(i));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(i=n,a=0,t={t:"range",a:arguments},e):i},e.rangePoints=function(u,o){arguments.length<2&&(o=0);var c=u[0],s=u[1],l=(s-c)/(Math.max(1,n.length-1)+o);return i=r(n.length<2?(c+s)/2:c+l*o/2,l),a=0,t={t:"rangePoints",a:arguments},e},e.rangeBands=function(u,o,c){arguments.length<2&&(o=0),arguments.length<3&&(c=o);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=(f-l)/(n.length-o+2*c);return i=r(l+h*c,h),s&&i.reverse(),a=h*(1-o),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(u,o,c){arguments.length<2&&(o=0),arguments.length<3&&(c=o);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=Math.floor((f-l)/(n.length-o+2*c)),g=f-l-(n.length-o)*h;return i=r(l+Math.round(g/2),h),s&&i.reverse(),a=Math.round(h*(1-o)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return a},e.rangeExtent=function(){return Li(t.a[0])},e.copy=function(){return Bi(n,t)},e.domain(n)}function Wi(e,r){function u(){var n=0,t=r.length;for(o=[];++n<t;)o[n-1]=Zo.quantile(e,n/t);return i}function i(n){return isNaN(n=+n)?void 0:r[Zo.bisect(o,n)]}var o;return i.domain=function(r){return arguments.length?(e=r.filter(t).sort(n),u()):e},i.range=function(n){return arguments.length?(r=n,u()):r},i.quantiles=function(){return o},i.invertExtent=function(n){return n=r.indexOf(n),0>n?[0/0,0/0]:[n>0?o[n-1]:e[0],n<o.length?o[n]:e[e.length-1]]},i.copy=function(){return Wi(e,r)},u()}function Ji(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(i*(t-n))))]}function u(){return i=e.length/(t-n),o=e.length-1,r}var i,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],u()):[n,t]},r.range=function(n){return arguments.length?(e=n,u()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return Ji(n,t,e)},u()}function Gi(n,t){function e(e){return e>=e?t[Zo.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return Gi(n,t)},e}function Ki(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Oi(n,t)},t.tickFormat=function(t,e){return Yi(n,t,e)},t.copy=function(){return Ki(n)},t}function Qi(n){return n.innerRadius}function no(n){return n.outerRadius}function to(n){return n.startAngle}function eo(n){return n.endAngle}function ro(n){function t(t){function o(){s.push("M",i(n(l),a))}for(var c,s=[],l=[],f=-1,h=t.length,g=bt(e),p=bt(r);++f<h;)u.call(this,c=t[f],f)?l.push([+g.call(this,c,f),+p.call(this,c,f)]):l.length&&(o(),l=[]);return l.length&&o(),s.length?s.join(""):null}var e=wr,r=Sr,u=we,i=uo,o=i.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(u=n,t):u},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?i=n:(i=xs.get(n)||uo).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function uo(n){return n.join("L")}function io(n){return uo(n)+"Z"}function oo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&u.push("H",r[0]),u.join("")}function ao(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("V",(r=n[t])[1],"H",r[0]);return u.join("")}function co(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r=n[t])[0],"V",r[1]);return u.join("")}function so(n,t){return n.length<4?uo(n):n[1]+ho(n.slice(1,n.length-1),go(n,t))}function lo(n,t){return n.length<3?uo(n):n[0]+ho((n.push(n[0]),n),go([n[n.length-2]].concat(n,[n[1]]),t))}function fo(n,t){return n.length<3?uo(n):n[0]+ho(n,go(n,t))}function ho(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return uo(n);var e=n.length!=t.length,r="",u=n[0],i=n[1],o=t[0],a=o,c=1;if(e&&(r+="Q"+(i[0]-2*o[0]/3)+","+(i[1]-2*o[1]/3)+","+i[0]+","+i[1],u=n[1],c=2),t.length>1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var s=2;s<t.length;s++,c++)i=n[c],a=t[s],r+="S"+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1]}if(e){var l=n[c];r+="Q"+(i[0]+2*a[0]/3)+","+(i[1]+2*a[1]/3)+","+l[0]+","+l[1]}return r}function go(n,t){for(var e,r=[],u=(1-t)/2,i=n[0],o=n[1],a=1,c=n.length;++a<c;)e=i,i=o,o=n[a],r.push([u*(o[0]-e[0]),u*(o[1]-e[1])]);return r}function po(n){if(n.length<3)return uo(n);var t=1,e=n.length,r=n[0],u=r[0],i=r[1],o=[u,u,u,(r=n[1])[0]],a=[i,i,i,r[1]],c=[u,",",i,"L",xo(bs,o),",",xo(bs,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),Mo(c,o,a);return n.pop(),c.push("L",r),c.join("")}function vo(n){if(n.length<4)return uo(n);for(var t,e=[],r=-1,u=n.length,i=[0],o=[0];++r<3;)t=n[r],i.push(t[0]),o.push(t[1]);for(e.push(xo(bs,i)+","+xo(bs,o)),--r;++r<u;)t=n[r],i.shift(),i.push(t[0]),o.shift(),o.push(t[1]),Mo(e,i,o);return e.join("")}function mo(n){for(var t,e,r=-1,u=n.length,i=u+4,o=[],a=[];++r<4;)e=n[r%u],o.push(e[0]),a.push(e[1]);for(t=[xo(bs,o),",",xo(bs,a)],--r;++r<i;)e=n[r%u],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),Mo(t,o,a);return t.join("")}function yo(n,t){var e=n.length-1;if(e)for(var r,u,i=n[0][0],o=n[0][1],a=n[e][0]-i,c=n[e][1]-o,s=-1;++s<=e;)r=n[s],u=s/e,r[0]=t*r[0]+(1-t)*(i+u*a),r[1]=t*r[1]+(1-t)*(o+u*c);return po(n)}function xo(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function Mo(n,t,e){n.push("C",xo(Ms,t),",",xo(Ms,e),",",xo(_s,t),",",xo(_s,e),",",xo(bs,t),",",xo(bs,e))}function _o(n,t){return(t[1]-n[1])/(t[0]-n[0])}function bo(n){for(var t=0,e=n.length-1,r=[],u=n[0],i=n[1],o=r[0]=_o(u,i);++t<e;)r[t]=(o+(o=_o(u=i,i=n[t+1])))/2;return r[t]=o,r}function wo(n){for(var t,e,r,u,i=[],o=bo(n),a=-1,c=n.length-1;++a<c;)t=_o(n[a],n[a+1]),ua(t)<ka?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,u=e*e+r*r,u>9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function So(n){return n.length<3?uo(n):n[0]+ho(n,wo(n))}function ko(n){for(var t,e,r,u=-1,i=n.length;++u<i;)t=n[u],e=t[0],r=t[1]+ms,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Eo(n){function t(t){function c(){v.push("M",a(n(m),f),l,s(n(d.reverse()),f),"Z")}for(var h,g,p,v=[],d=[],m=[],y=-1,x=t.length,M=bt(e),_=bt(u),b=e===r?function(){return g}:bt(r),w=u===i?function(){return p}:bt(i);++y<x;)o.call(this,h=t[y],y)?(d.push([g=+M.call(this,h,y),p=+_.call(this,h,y)]),m.push([+b.call(this,h,y),+w.call(this,h,y)])):d.length&&(c(),d=[],m=[]);return d.length&&c(),v.length?v.join(""):null}var e=wr,r=wr,u=0,i=Sr,o=we,a=uo,c=a.key,s=a,l="L",f=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r},t.y=function(n){return arguments.length?(u=i=n,t):i},t.y0=function(n){return arguments.length?(u=n,t):u},t.y1=function(n){return arguments.length?(i=n,t):i},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(c="function"==typeof n?a=n:(a=xs.get(n)||uo).key,s=a.reverse||a,l=a.closed?"M":"L",t):c},t.tension=function(n){return arguments.length?(f=n,t):f},t}function Ao(n){return n.radius}function Co(n){return[n.x,n.y]}function No(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]+ms;return[e*Math.cos(r),e*Math.sin(r)]}}function zo(){return 64}function Lo(){return"circle"}function To(n){var t=Math.sqrt(n/ba);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function qo(n,t){return sa(n,Cs),n.id=t,n}function Ro(n,t,e,r){var u=n.id;return P(n,"function"==typeof e?function(n,i,o){n.__transition__[u].tween.set(t,r(e.call(n,n.__data__,i,o)))}:(e=r(e),function(n){n.__transition__[u].tween.set(t,e)}))}function Do(n){return null==n&&(n=""),function(){this.textContent=n}}function Po(n,t,e,r){var u=n.__transition__||(n.__transition__={active:0,count:0}),i=u[e];if(!i){var a=r.time;i=u[e]={tween:new o,time:a,ease:r.ease,delay:r.delay,duration:r.duration},++u.count,Zo.timer(function(r){function o(r){return u.active>e?s():(u.active=e,i.event&&i.event.start.call(n,l,t),i.tween.forEach(function(e,r){(r=r.call(n,l,t))&&v.push(r)}),Zo.timer(function(){return p.c=c(r||1)?we:c,1},0,a),void 0)}function c(r){if(u.active!==e)return s();for(var o=r/g,a=f(o),c=v.length;c>0;)v[--c].call(n,a); +return o>=1?(i.event&&i.event.end.call(n,l,t),s()):void 0}function s(){return--u.count?delete u[e]:delete n.__transition__,1}var l=n.__data__,f=i.ease,h=i.delay,g=i.duration,p=Ba,v=[];return p.t=h+a,r>=h?o(r-h):(p.c=o,void 0)},0,a)}}function Uo(n,t){n.attr("transform",function(n){return"translate("+t(n)+",0)"})}function jo(n,t){n.attr("transform",function(n){return"translate(0,"+t(n)+")"})}function Ho(n){return n.toISOString()}function Fo(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=Zo.bisect(Us,u);return i==Us.length?[t.year,Fi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Us[i-1]<Us[i]/u?i-1:i]:[Fs,Fi(n,e)[2]]}return r.invert=function(t){return Oo(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(Oo)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,Oo(+e+1),t).length}var i=r.domain(),o=Li(i),a=null==n?u(o,10):"number"==typeof n&&u(o,n);return a&&(n=a[0],t=a[1]),r.domain(Ri(i,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=Oo(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Oo(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Li(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Oo(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Fo(n.copy(),t,e)},ji(r,n)}function Oo(n){return new Date(n)}function Yo(n){return JSON.parse(n.responseText)}function Io(n){var t=$o.createRange();return t.selectNode($o.body),t.createContextualFragment(n.responseText)}var Zo={version:"3.4.11"};Date.now||(Date.now=function(){return+new Date});var Vo=[].slice,Xo=function(n){return Vo.call(n)},$o=document,Bo=$o.documentElement,Wo=window;try{Xo(Bo.childNodes)[0].nodeType}catch(Jo){Xo=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{$o.createElement("div").style.setProperty("opacity",0,"")}catch(Go){var Ko=Wo.Element.prototype,Qo=Ko.setAttribute,na=Ko.setAttributeNS,ta=Wo.CSSStyleDeclaration.prototype,ea=ta.setProperty;Ko.setAttribute=function(n,t){Qo.call(this,n,t+"")},Ko.setAttributeNS=function(n,t,e){na.call(this,n,t,e+"")},ta.setProperty=function(n,t,e){ea.call(this,n,t+"",e)}}Zo.ascending=n,Zo.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},Zo.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&e>r&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&e>r&&(e=r)}return e},Zo.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&r>e&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&r>e&&(e=r)}return e},Zo.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i<o&&!(null!=(e=u=n[i])&&e>=e);)e=u=void 0;for(;++i<o;)null!=(r=n[i])&&(e>r&&(e=r),r>u&&(u=r))}else{for(;++i<o&&!(null!=(e=u=t.call(n,n[i],i))&&e>=e);)e=void 0;for(;++i<o;)null!=(r=t.call(n,n[i],i))&&(e>r&&(e=r),r>u&&(u=r))}return[e,u]},Zo.sum=function(n,t){var e,r=0,u=n.length,i=-1;if(1===arguments.length)for(;++i<u;)isNaN(e=+n[i])||(r+=e);else for(;++i<u;)isNaN(e=+t.call(n,n[i],i))||(r+=e);return r},Zo.mean=function(n,e){var r,u=0,i=n.length,o=-1,a=i;if(1===arguments.length)for(;++o<i;)t(r=n[o])?u+=r:--a;else for(;++o<i;)t(r=e.call(n,n[o],o))?u+=r:--a;return a?u/a:void 0},Zo.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),u=+n[r-1],i=e-r;return i?u+i*(n[r]-u):u},Zo.median=function(e,r){return arguments.length>1&&(e=e.map(r)),e=e.filter(t),e.length?Zo.quantile(e.sort(n),.5):void 0};var ra=e(n);Zo.bisectLeft=ra.left,Zo.bisect=Zo.bisectRight=ra.right,Zo.bisector=function(t){return e(1===t.length?function(e,r){return n(t(e),r)}:t)},Zo.shuffle=function(n){for(var t,e,r=n.length;r;)e=0|Math.random()*r--,t=n[r],n[r]=n[e],n[e]=t;return n},Zo.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},Zo.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},Zo.zip=function(){if(!(u=arguments.length))return[];for(var n=-1,t=Zo.min(arguments,r),e=new Array(t);++n<t;)for(var u,i=-1,o=e[n]=new Array(u);++i<u;)o[i]=arguments[i][n];return e},Zo.transpose=function(n){return Zo.zip.apply(Zo,n)},Zo.keys=function(n){var t=[];for(var e in n)t.push(e);return t},Zo.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},Zo.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},Zo.merge=function(n){for(var t,e,r,u=n.length,i=-1,o=0;++i<u;)o+=n[i].length;for(e=new Array(o);--u>=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var ua=Math.abs;Zo.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),1/0===(t-n)/e)throw new Error("infinite range");var r,i=[],o=u(ua(e)),a=-1;if(n*=o,t*=o,e*=o,0>e)for(;(r=n+e*++a)>t;)i.push(r/o);else for(;(r=n+e*++a)<t;)i.push(r/o);return i},Zo.map=function(n){var t=new o;if(n instanceof o)n.forEach(function(n,e){t.set(n,e)});else for(var e in n)t.set(e,n[e]);return t},i(o,{has:a,get:function(n){return this[ia+n]},set:function(n,t){return this[ia+n]=t},remove:c,keys:s,values:function(){var n=[];return this.forEach(function(t,e){n.push(e)}),n},entries:function(){var n=[];return this.forEach(function(t,e){n.push({key:t,value:e})}),n},size:l,empty:f,forEach:function(n){for(var t in this)t.charCodeAt(0)===oa&&n.call(this,t.substring(1),this[t])}});var ia="\x00",oa=ia.charCodeAt(0);Zo.nest=function(){function n(t,a,c){if(c>=i.length)return r?r.call(u,a):e?a.sort(e):a;for(var s,l,f,h,g=-1,p=a.length,v=i[c++],d=new o;++g<p;)(h=d.get(s=v(l=a[g])))?h.push(l):d.set(s,[l]);return t?(l=t(),f=function(e,r){l.set(e,n(t,r,c))}):(l={},f=function(e,r){l[e]=n(t,r,c)}),d.forEach(f),l}function t(n,e){if(e>=i.length)return n;var r=[],u=a[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,u={},i=[],a=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(Zo.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return a[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},Zo.set=function(n){var t=new h;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},i(h,{has:a,add:function(n){return this[ia+n]=!0,n},remove:function(n){return n=ia+n,n in this&&delete this[n]},values:s,size:l,empty:f,forEach:function(n){for(var t in this)t.charCodeAt(0)===oa&&n.call(this,t.substring(1))}}),Zo.behavior={},Zo.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r<u;)n[e=arguments[r]]=g(n,t,t[e]);return n};var aa=["webkit","ms","moz","Moz","o","O"];Zo.dispatch=function(){for(var n=new d,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=m(n);return n},d.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.substring(e+1),n=n.substring(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},Zo.event=null,Zo.requote=function(n){return n.replace(ca,"\\$&")};var ca=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,sa={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},la=function(n,t){return t.querySelector(n)},fa=function(n,t){return t.querySelectorAll(n)},ha=Bo.matches||Bo[p(Bo,"matchesSelector")],ga=function(n,t){return ha.call(n,t)};"function"==typeof Sizzle&&(la=function(n,t){return Sizzle(n,t)[0]||null},fa=Sizzle,ga=Sizzle.matchesSelector),Zo.selection=function(){return ma};var pa=Zo.selection.prototype=[];pa.select=function(n){var t,e,r,u,i=[];n=b(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var c=-1,s=r.length;++c<s;)(u=r[c])?(t.push(e=n.call(u,u.__data__,c,o)),e&&"__data__"in u&&(e.__data__=u.__data__)):t.push(null)}return _(i)},pa.selectAll=function(n){var t,e,r=[];n=w(n);for(var u=-1,i=this.length;++u<i;)for(var o=this[u],a=-1,c=o.length;++a<c;)(e=o[a])&&(r.push(t=Xo(n.call(e,e.__data__,a,u))),t.parentNode=e);return _(r)};var va={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};Zo.ns={prefix:va,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&(e=n.substring(0,t),n=n.substring(t+1)),va.hasOwnProperty(e)?{space:va[e],local:n}:n}},pa.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=Zo.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(S(t,n[t]));return this}return this.each(S(n,t))},pa.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=A(n)).length,u=-1;if(t=e.classList){for(;++u<r;)if(!t.contains(n[u]))return!1}else for(t=e.getAttribute("class");++u<r;)if(!E(n[u]).test(t))return!1;return!0}for(t in n)this.each(C(t,n[t]));return this}return this.each(C(n,t))},pa.style=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(z(e,n[e],t));return this}if(2>r)return Wo.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(z(n,t,e))},pa.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(L(t,n[t]));return this}return this.each(L(n,t))},pa.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},pa.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},pa.append=function(n){return n=T(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},pa.insert=function(n,t){return n=T(n),t=b(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},pa.remove=function(){return this.each(function(){var n=this.parentNode;n&&n.removeChild(this)})},pa.data=function(n,t){function e(n,e){var r,u,i,a=n.length,f=e.length,h=Math.min(a,f),g=new Array(f),p=new Array(f),v=new Array(a);if(t){var d,m=new o,y=new o,x=[];for(r=-1;++r<a;)d=t.call(u=n[r],u.__data__,r),m.has(d)?v[r]=u:m.set(d,u),x.push(d);for(r=-1;++r<f;)d=t.call(e,i=e[r],r),(u=m.get(d))?(g[r]=u,u.__data__=i):y.has(d)||(p[r]=q(i)),y.set(d,i),m.remove(d);for(r=-1;++r<a;)m.has(x[r])&&(v[r]=n[r])}else{for(r=-1;++r<h;)u=n[r],i=e[r],u?(u.__data__=i,g[r]=u):p[r]=q(i);for(;f>r;++r)p[r]=q(e[r]);for(;a>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,c.push(p),s.push(g),l.push(v)}var r,u,i=-1,a=this.length;if(!arguments.length){for(n=new Array(a=(r=this[0]).length);++i<a;)(u=r[i])&&(n[i]=u.__data__);return n}var c=U([]),s=_([]),l=_([]);if("function"==typeof n)for(;++i<a;)e(r=this[i],n.call(r,r.parentNode.__data__,i));else for(;++i<a;)e(r=this[i],n);return s.enter=function(){return c},s.exit=function(){return l},s},pa.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},pa.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=R(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return _(u)},pa.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],u=r.length-1,i=r[u];--u>=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},pa.sort=function(n){n=D.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},pa.each=function(n){return P(this,function(t,e,r){n.call(t,t.__data__,e,r)})},pa.call=function(n){var t=Xo(arguments);return n.apply(t[0]=this,t),this},pa.empty=function(){return!this.node()},pa.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},pa.size=function(){var n=0;return this.each(function(){++n}),n};var da=[];Zo.selection.enter=U,Zo.selection.enter.prototype=da,da.append=pa.append,da.empty=pa.empty,da.node=pa.node,da.call=pa.call,da.size=pa.size,da.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++a<c;){r=(u=this[a]).update,o.push(t=[]),t.parentNode=u.parentNode;for(var s=-1,l=u.length;++s<l;)(i=u[s])?(t.push(r[s]=e=n.call(u.parentNode,i.__data__,s,a)),e.__data__=i.__data__):t.push(null)}return _(o)},da.insert=function(n,t){return arguments.length<2&&(t=j(this)),pa.insert.call(this,n,t)},pa.transition=function(){for(var n,t,e=Ss||++Ns,r=[],u=ks||{time:Date.now(),ease:xu,delay:0,duration:250},i=-1,o=this.length;++i<o;){r.push(n=[]);for(var a=this[i],c=-1,s=a.length;++c<s;)(t=a[c])&&Po(t,c,e,u),n.push(t)}return qo(r,e)},pa.interrupt=function(){return this.each(H)},Zo.select=function(n){var t=["string"==typeof n?la(n,$o):n];return t.parentNode=Bo,_([t])},Zo.selectAll=function(n){var t=Xo("string"==typeof n?fa(n,$o):n);return t.parentNode=Bo,_([t])};var ma=Zo.select(Bo);pa.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(F(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(F(n,t,e))};var ya=Zo.map({mouseenter:"mouseover",mouseleave:"mouseout"});ya.forEach(function(n){"on"+n in $o&&ya.remove(n)});var xa="onselectstart"in $o?null:p(Bo.style,"userSelect"),Ma=0;Zo.mouse=function(n){return Z(n,x())};var _a=/WebKit/.test(Wo.navigator.userAgent)?-1:0;Zo.touches=function(n,t){return arguments.length<2&&(t=x().touches),t?Xo(t).map(function(t){var e=Z(n,t);return e.identifier=t.identifier,e}):[]},Zo.behavior.drag=function(){function n(){this.on("mousedown.drag",u).on("touchstart.drag",i)}function t(n,t,u,i,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-x[0],e=r[1]-x[1],p|=n|e,x=r,g({type:"drag",x:r[0]+s[0],y:r[1]+s[1],dx:n,dy:e}))}function c(){t(h,v)&&(m.on(i+d,null).on(o+d,null),y(p&&Zo.event.target===f),g({type:"dragend"}))}var s,l=this,f=Zo.event.target,h=l.parentNode,g=e.of(l,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=Zo.select(u()).on(i+d,a).on(o+d,c),y=I(),x=t(h,v);r?(s=r.apply(l,arguments),s=[s.x-x[0],s.y-x[1]]):s=[0,0],g({type:"dragstart"})}}var e=M(n,"drag","dragstart","dragend"),r=null,u=t(v,Zo.mouse,$,"mousemove","mouseup"),i=t(V,Zo.touch,X,"touchmove","touchend");return n.origin=function(t){return arguments.length?(r=t,n):r},Zo.rebind(n,e,"on")};var ba=Math.PI,wa=2*ba,Sa=ba/2,ka=1e-6,Ea=ka*ka,Aa=ba/180,Ca=180/ba,Na=Math.SQRT2,za=2,La=4;Zo.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=Q(v),o=i/(za*h)*(e*nt(Na*t+v)-K(v));return[r+o*s,u+o*l,i*e/Q(Na*t+v)]}return[r+n*s,u+n*l,i*Math.exp(Na*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],s=o-r,l=a-u,f=s*s+l*l,h=Math.sqrt(f),g=(c*c-i*i+La*f)/(2*i*za*h),p=(c*c-i*i-La*f)/(2*c*za*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Na;return e.duration=1e3*y,e},Zo.behavior.zoom=function(){function n(n){n.on(A,s).on(Ra+".zoom",f).on("dblclick.zoom",h).on(z,l)}function t(n){return[(n[0]-S.x)/S.k,(n[1]-S.y)/S.k]}function e(n){return[n[0]*S.k+S.x,n[1]*S.k+S.y]}function r(n){S.k=Math.max(E[0],Math.min(E[1],n))}function u(n,t){t=e(t),S.x+=n[0]-t[0],S.y+=n[1]-t[1]}function i(){_&&_.domain(x.range().map(function(n){return(n-S.x)/S.k}).map(x.invert)),w&&w.domain(b.range().map(function(n){return(n-S.y)/S.k}).map(b.invert))}function o(n){n({type:"zoomstart"})}function a(n){i(),n({type:"zoom",scale:S.k,translate:[S.x,S.y]})}function c(n){n({type:"zoomend"})}function s(){function n(){l=1,u(Zo.mouse(r),h),a(s)}function e(){f.on(C,null).on(N,null),g(l&&Zo.event.target===i),c(s)}var r=this,i=Zo.event.target,s=L.of(r,arguments),l=0,f=Zo.select(Wo).on(C,n).on(N,e),h=t(Zo.mouse(r)),g=I();H.call(r),o(s)}function l(){function n(){var n=Zo.touches(g);return h=S.k,n.forEach(function(n){n.identifier in v&&(v[n.identifier]=t(n))}),n}function e(){var t=Zo.event.target;Zo.select(t).on(M,i).on(_,f),b.push(t);for(var e=Zo.event.changedTouches,o=0,c=e.length;c>o;++o)v[e[o].identifier]=null;var s=n(),l=Date.now();if(1===s.length){if(500>l-m){var h=s[0],g=v[h.identifier];r(2*S.k),u(h,g),y(),a(p)}m=l}else if(s.length>1){var h=s[0],x=s[1],w=h[0]-x[0],k=h[1]-x[1];d=w*w+k*k}}function i(){for(var n,t,e,i,o=Zo.touches(g),c=0,s=o.length;s>c;++c,i=null)if(e=o[c],i=v[e.identifier]){if(t)break;n=e,t=i}if(i){var l=(l=e[0]-n[0])*l+(l=e[1]-n[1])*l,f=d&&Math.sqrt(l/d);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*h)}m=null,u(n,t),a(p)}function f(){if(Zo.event.touches.length){for(var t=Zo.event.changedTouches,e=0,r=t.length;r>e;++e)delete v[t[e].identifier];for(var u in v)return void n()}Zo.selectAll(b).on(x,null),w.on(A,s).on(z,l),k(),c(p)}var h,g=this,p=L.of(g,arguments),v={},d=0,x=".zoom-"+Zo.event.changedTouches[0].identifier,M="touchmove"+x,_="touchend"+x,b=[],w=Zo.select(g).on(A,null).on(z,e),k=I();H.call(g),e(),o(p)}function f(){var n=L.of(this,arguments);d?clearTimeout(d):(g=t(p=v||Zo.mouse(this)),H.call(this),o(n)),d=setTimeout(function(){d=null,c(n)},50),y(),r(Math.pow(2,.002*Ta())*S.k),u(p,g),a(n)}function h(){var n=L.of(this,arguments),e=Zo.mouse(this),i=t(e),s=Math.log(S.k)/Math.LN2;o(n),r(Math.pow(2,Zo.event.shiftKey?Math.ceil(s)-1:Math.floor(s)+1)),u(e,i),a(n),c(n)}var g,p,v,d,m,x,_,b,w,S={x:0,y:0,k:1},k=[960,500],E=qa,A="mousedown.zoom",C="mousemove.zoom",N="mouseup.zoom",z="touchstart.zoom",L=M(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=L.of(this,arguments),t=S;Ss?Zo.select(this).transition().each("start.zoom",function(){S=this.__chart__||{x:0,y:0,k:1},o(n)}).tween("zoom:zoom",function(){var e=k[0],r=k[1],u=e/2,i=r/2,o=Zo.interpolateZoom([(u-S.x)/S.k,(i-S.y)/S.k,e/S.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),c=e/r[2];this.__chart__=S={x:u-r[0]*c,y:i-r[1]*c,k:c},a(n)}}).each("end.zoom",function(){c(n)}):(this.__chart__=S,o(n),a(n),c(n))})},n.translate=function(t){return arguments.length?(S={x:+t[0],y:+t[1],k:S.k},i(),n):[S.x,S.y]},n.scale=function(t){return arguments.length?(S={x:S.x,y:S.y,k:+t},i(),n):S.k},n.scaleExtent=function(t){return arguments.length?(E=null==t?qa:[+t[0],+t[1]],n):E},n.center=function(t){return arguments.length?(v=t&&[+t[0],+t[1]],n):v},n.size=function(t){return arguments.length?(k=t&&[+t[0],+t[1]],n):k},n.x=function(t){return arguments.length?(_=t,x=t.copy(),S={x:0,y:0,k:1},n):_},n.y=function(t){return arguments.length?(w=t,b=t.copy(),S={x:0,y:0,k:1},n):w},Zo.rebind(n,L,"on")};var Ta,qa=[0,1/0],Ra="onwheel"in $o?(Ta=function(){return-Zo.event.deltaY*(Zo.event.deltaMode?120:1)},"wheel"):"onmousewheel"in $o?(Ta=function(){return Zo.event.wheelDelta},"mousewheel"):(Ta=function(){return-Zo.event.detail},"MozMousePixelScroll");Zo.color=et,et.prototype.toString=function(){return this.rgb()+""},Zo.hsl=rt;var Da=rt.prototype=new et;Da.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new rt(this.h,this.s,this.l/n)},Da.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new rt(this.h,this.s,n*this.l)},Da.rgb=function(){return ut(this.h,this.s,this.l)},Zo.hcl=it;var Pa=it.prototype=new et;Pa.brighter=function(n){return new it(this.h,this.c,Math.min(100,this.l+Ua*(arguments.length?n:1)))},Pa.darker=function(n){return new it(this.h,this.c,Math.max(0,this.l-Ua*(arguments.length?n:1)))},Pa.rgb=function(){return ot(this.h,this.c,this.l).rgb()},Zo.lab=at;var Ua=18,ja=.95047,Ha=1,Fa=1.08883,Oa=at.prototype=new et;Oa.brighter=function(n){return new at(Math.min(100,this.l+Ua*(arguments.length?n:1)),this.a,this.b)},Oa.darker=function(n){return new at(Math.max(0,this.l-Ua*(arguments.length?n:1)),this.a,this.b)},Oa.rgb=function(){return ct(this.l,this.a,this.b)},Zo.rgb=gt;var Ya=gt.prototype=new et;Ya.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),new gt(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new gt(u,u,u)},Ya.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new gt(n*this.r,n*this.g,n*this.b)},Ya.hsl=function(){return yt(this.r,this.g,this.b)},Ya.toString=function(){return"#"+dt(this.r)+dt(this.g)+dt(this.b)};var Ia=Zo.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Ia.forEach(function(n,t){Ia.set(n,pt(t))}),Zo.functor=bt,Zo.xhr=St(wt),Zo.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=kt(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(l>=s)return o;if(u)return u=!1,i;var t=l;if(34===n.charCodeAt(t)){for(var e=t;e++<s;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}l=e+2;var r=n.charCodeAt(e+1);return 13===r?(u=!0,10===n.charCodeAt(e+2)&&++l):10===r&&(u=!0),n.substring(t+1,e).replace(/""/g,'"')}for(;s>l;){var r=n.charCodeAt(l++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(l)&&(++l,++a);else if(r!==c)continue;return n.substring(t,l-a)}return n.substring(t)}for(var r,u,i={},o={},a=[],s=n.length,l=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();(!t||(h=t(h,f++)))&&a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new h,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},Zo.csv=Zo.dsv(",","text/csv"),Zo.tsv=Zo.dsv(" ","text/tab-separated-values"),Zo.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=x().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return Z(n,r)};var Za,Va,Xa,$a,Ba,Wa=Wo[p(Wo,"requestAnimationFrame")]||function(n){setTimeout(n,17)};Zo.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};Va?Va.n=i:Za=i,Va=i,Xa||($a=clearTimeout($a),Xa=1,Wa(At))},Zo.timer.flush=function(){Ct(),Nt()},Zo.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var Ja=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Lt);Zo.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=Zo.round(n,zt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),Ja[8+e/3]};var Ga=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,Ka=Zo.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=Zo.round(n,zt(n,t))).toFixed(Math.max(0,Math.min(20,zt(n*(1+1e-15),t))))}}),Qa=Zo.time={},nc=Date;Rt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){tc.setUTCDate.apply(this._,arguments)},setDay:function(){tc.setUTCDay.apply(this._,arguments)},setFullYear:function(){tc.setUTCFullYear.apply(this._,arguments)},setHours:function(){tc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){tc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){tc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){tc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){tc.setUTCSeconds.apply(this._,arguments)},setTime:function(){tc.setTime.apply(this._,arguments)}};var tc=Date.prototype;Qa.year=Dt(function(n){return n=Qa.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),Qa.years=Qa.year.range,Qa.years.utc=Qa.year.utc.range,Qa.day=Dt(function(n){var t=new nc(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),Qa.days=Qa.day.range,Qa.days.utc=Qa.day.utc.range,Qa.dayOfYear=function(n){var t=Qa.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=Qa[n]=Dt(function(n){return(n=Qa.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=Qa.year(n).getDay();return Math.floor((Qa.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});Qa[n+"s"]=e.range,Qa[n+"s"].utc=e.utc.range,Qa[n+"OfYear"]=function(n){var e=Qa.year(n).getDay();return Math.floor((Qa.dayOfYear(n)+(e+t)%7)/7)}}),Qa.week=Qa.sunday,Qa.weeks=Qa.sunday.range,Qa.weeks.utc=Qa.sunday.utc.range,Qa.weekOfYear=Qa.sundayOfYear;var ec={"-":"",_:" ",0:"0"},rc=/^\s*\d+/,uc=/^%/;Zo.locale=function(n){return{numberFormat:Tt(n),timeFormat:Ut(n)}};var ic=Zo.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});Zo.format=ic.numberFormat,Zo.geo={},ue.prototype={s:0,t:0,add:function(n){ie(n,this.t,oc),ie(oc.s,this.s,this),this.s?this.t+=oc.t:this.s=oc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var oc=new ue;Zo.geo.stream=function(n,t){n&&ac.hasOwnProperty(n.type)?ac[n.type](n,t):oe(n,t)};var ac={Feature:function(n,t){oe(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++r<u;)oe(e[r].geometry,t)}},cc={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){ae(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)ae(e[r],t,0)},Polygon:function(n,t){ce(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)ce(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,u=e.length;++r<u;)oe(e[r],t)}};Zo.geo.area=function(n){return sc=0,Zo.geo.stream(n,fc),sc};var sc,lc=new ue,fc={sphere:function(){sc+=4*ba},point:v,lineStart:v,lineEnd:v,polygonStart:function(){lc.reset(),fc.lineStart=se},polygonEnd:function(){var n=2*lc;sc+=0>n?4*ba+n:n,fc.lineStart=fc.lineEnd=fc.point=v}};Zo.geo.bounds=function(){function n(n,t){x.push(M=[l=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=le([t*Aa,e*Aa]);if(m){var u=he(m,r),i=[u[1],-u[0],0],o=he(i,u);ve(o),o=de(o);var c=t-p,s=c>0?1:-1,v=o[0]*Ca*s,d=ua(c)>180;if(d^(v>s*p&&s*t>v)){var y=o[1]*Ca;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>s*p&&s*t>v)){var y=-o[1]*Ca;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t):h>=l?(l>t&&(l=t),t>h&&(h=t)):t>p?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t)}else n(t,e);m=r,p=t}function e(){_.point=t}function r(){M[0]=l,M[1]=h,_.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=ua(r)>180?r+(r>0?360:-360):r}else v=n,d=e;fc.point(n,e),t(n,e)}function i(){fc.lineStart()}function o(){u(v,d),fc.lineEnd(),ua(y)>ka&&(l=-(h=180)),M[0]=l,M[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function s(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var l,f,h,g,p,v,d,m,y,x,M,_={point:n,lineStart:e,lineEnd:r,polygonStart:function(){_.point=u,_.lineStart=i,_.lineEnd=o,y=0,fc.polygonStart()},polygonEnd:function(){fc.polygonEnd(),_.point=n,_.lineStart=e,_.lineEnd=r,0>lc?(l=-(h=180),f=-(g=90)):y>ka?g=90:-ka>y&&(f=-90),M[0]=l,M[1]=h}};return function(n){g=h=-(l=f=1/0),x=[],Zo.geo.stream(n,_);var t=x.length;if(t){x.sort(c);for(var e,r=1,u=x[0],i=[u];t>r;++r)e=x[r],s(e[0],u)||s(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e); +for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,l=e[0],h=u[1])}return x=M=null,1/0===l||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[l,f],[h,g]]}}(),Zo.geo.centroid=function(n){hc=gc=pc=vc=dc=mc=yc=xc=Mc=_c=bc=0,Zo.geo.stream(n,wc);var t=Mc,e=_c,r=bc,u=t*t+e*e+r*r;return Ea>u&&(t=mc,e=yc,r=xc,ka>gc&&(t=pc,e=vc,r=dc),u=t*t+e*e+r*r,Ea>u)?[0/0,0/0]:[Math.atan2(e,t)*Ca,G(r/Math.sqrt(u))*Ca]};var hc,gc,pc,vc,dc,mc,yc,xc,Mc,_c,bc,wc={sphere:v,point:ye,lineStart:Me,lineEnd:_e,polygonStart:function(){wc.lineStart=be},polygonEnd:function(){wc.lineStart=Me}},Sc=Ae(we,Te,Re,[-ba,-ba/2]),kc=1e9;Zo.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Ue(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(Zo.geo.conicEqualArea=function(){return He(Fe)}).raw=Fe,Zo.geo.albers=function(){return Zo.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},Zo.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=Zo.geo.albers(),o=Zo.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=Zo.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var s=i.scale(),l=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[l-.455*s,f-.238*s],[l+.455*s,f+.238*s]]).stream(c).point,r=o.translate([l-.307*s,f+.201*s]).clipExtent([[l-.425*s+ka,f+.12*s+ka],[l-.214*s-ka,f+.234*s-ka]]).stream(c).point,u=a.translate([l-.205*s,f+.212*s]).clipExtent([[l-.214*s+ka,f+.166*s+ka],[l-.115*s-ka,f+.234*s-ka]]).stream(c).point,n},n.scale(1070)};var Ec,Ac,Cc,Nc,zc,Lc,Tc={point:v,lineStart:v,lineEnd:v,polygonStart:function(){Ac=0,Tc.lineStart=Oe},polygonEnd:function(){Tc.lineStart=Tc.lineEnd=Tc.point=v,Ec+=ua(Ac/2)}},qc={point:Ye,lineStart:v,lineEnd:v,polygonStart:v,polygonEnd:v},Rc={point:Ve,lineStart:Xe,lineEnd:$e,polygonStart:function(){Rc.lineStart=Be},polygonEnd:function(){Rc.point=Ve,Rc.lineStart=Xe,Rc.lineEnd=$e}};Zo.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),Zo.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Ec=0,Zo.geo.stream(n,u(Tc)),Ec},n.centroid=function(n){return pc=vc=dc=mc=yc=xc=Mc=_c=bc=0,Zo.geo.stream(n,u(Rc)),bc?[Mc/bc,_c/bc]:xc?[mc/xc,yc/xc]:dc?[pc/dc,vc/dc]:[0/0,0/0]},n.bounds=function(n){return zc=Lc=-(Cc=Nc=1/0),Zo.geo.stream(n,u(qc)),[[Cc,Nc],[zc,Lc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||Ge(n):wt,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new Ie:new We(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(Zo.geo.albersUsa()).context(null)},Zo.geo.transform=function(n){return{stream:function(t){var e=new Ke(t);for(var r in n)e[r]=n[r];return e}}},Ke.prototype={point:function(n,t){this.stream.point(n,t)},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()}},Zo.geo.projection=nr,Zo.geo.projectionMutator=tr,(Zo.geo.equirectangular=function(){return nr(rr)}).raw=rr.invert=rr,Zo.geo.rotation=function(n){function t(t){return t=n(t[0]*Aa,t[1]*Aa),t[0]*=Ca,t[1]*=Ca,t}return n=ir(n[0]%360*Aa,n[1]*Aa,n.length>2?n[2]*Aa:0),t.invert=function(t){return t=n.invert(t[0]*Aa,t[1]*Aa),t[0]*=Ca,t[1]*=Ca,t},t},ur.invert=rr,Zo.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=ir(-n[0]*Aa,-n[1]*Aa,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Ca,n[1]*=Ca}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=sr((t=+r)*Aa,u*Aa),n):t},n.precision=function(r){return arguments.length?(e=sr(t*Aa,(u=+r)*Aa),n):u},n.angle(90)},Zo.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Aa,u=n[1]*Aa,i=t[1]*Aa,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),s=Math.cos(u),l=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=s*l-c*f*a)*e),c*l+s*f*a)},Zo.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return Zo.range(Math.ceil(i/d)*d,u,d).map(h).concat(Zo.range(Math.ceil(s/m)*m,c,m).map(g)).concat(Zo.range(Math.ceil(r/p)*p,e,p).filter(function(n){return ua(n%d)>ka}).map(l)).concat(Zo.range(Math.ceil(a/v)*v,o,v).filter(function(n){return ua(n%m)>ka}).map(f))}var e,r,u,i,o,a,c,s,l,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(s).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],s=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),s>c&&(t=s,s=c,c=t),n.precision(y)):[[i,s],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,l=fr(a,o,90),f=hr(r,e,y),h=fr(s,c,90),g=hr(i,u,y),n):y},n.majorExtent([[-180,-90+ka],[180,90-ka]]).minorExtent([[-180,-80-ka],[180,80+ka]])},Zo.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=gr,u=pr;return n.distance=function(){return Zo.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},Zo.geo.interpolate=function(n,t){return vr(n[0]*Aa,n[1]*Aa,t[0]*Aa,t[1]*Aa)},Zo.geo.length=function(n){return Dc=0,Zo.geo.stream(n,Pc),Dc};var Dc,Pc={sphere:v,point:v,lineStart:dr,lineEnd:v,polygonStart:v,polygonEnd:v},Uc=mr(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(Zo.geo.azimuthalEqualArea=function(){return nr(Uc)}).raw=Uc;var jc=mr(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},wt);(Zo.geo.azimuthalEquidistant=function(){return nr(jc)}).raw=jc,(Zo.geo.conicConformal=function(){return He(yr)}).raw=yr,(Zo.geo.conicEquidistant=function(){return He(xr)}).raw=xr;var Hc=mr(function(n){return 1/n},Math.atan);(Zo.geo.gnomonic=function(){return nr(Hc)}).raw=Hc,Mr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Sa]},(Zo.geo.mercator=function(){return _r(Mr)}).raw=Mr;var Fc=mr(function(){return 1},Math.asin);(Zo.geo.orthographic=function(){return nr(Fc)}).raw=Fc;var Oc=mr(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(Zo.geo.stereographic=function(){return nr(Oc)}).raw=Oc,br.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Sa]},(Zo.geo.transverseMercator=function(){var n=_r(br),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=br,Zo.geom={},Zo.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=bt(e),i=bt(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(Er),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var s=kr(a),l=kr(c),f=l[0]===s[0],h=l[l.length-1]===s[s.length-1],g=[];for(t=s.length-1;t>=0;--t)g.push(n[a[s[t]][2]]);for(t=+f;t<l.length-h;++t)g.push(n[a[l[t]][2]]);return g}var e=wr,r=Sr;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},Zo.geom.polygon=function(n){return sa(n,Yc),n};var Yc=Zo.geom.polygon.prototype=[];Yc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],u=0;++t<e;)n=r,r=this[t],u+=n[1]*r[0]-n[0]*r[1];return.5*u},Yc.centroid=function(n){var t,e,r=-1,u=this.length,i=0,o=0,a=this[u-1];for(arguments.length||(n=-1/(6*this.area()));++r<u;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],i+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[i*n,o*n]},Yc.clip=function(n){for(var t,e,r,u,i,o,a=Nr(n),c=-1,s=this.length-Nr(this),l=this[s-1];++c<s;){for(t=n.slice(),n.length=0,u=this[c],i=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],Ar(o,l,u)?(Ar(i,l,u)||n.push(Cr(i,o,l,u)),n.push(o)):Ar(i,l,u)&&n.push(Cr(i,o,l,u)),i=o;a&&n.push(n[0]),l=u}return n};var Ic,Zc,Vc,Xc,$c,Bc=[],Wc=[];Ur.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(Hr),t.length},Wr.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},Jr.prototype={insert:function(n,t){var e,r,u;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=nu(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(u=r.R,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.R&&(Kr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Qr(this,r))):(u=r.L,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.L&&(Qr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Kr(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,u=n.U,i=n.L,o=n.R;if(e=i?o?nu(o):i:o,u?u.L===n?u.L=e:u.R=e:this._=e,i&&o?(r=e.C,e.C=n.C,e.L=i,i.U=e,e!==o?(u=e.U,e.U=n.U,n=e.R,u.L=n,e.R=o,o.U=e):(e.U=u,u=e,n=e.R)):(r=n.C,n=e),n&&(n.U=u),!r){if(n&&n.C)return n.C=!1,void 0;do{if(n===this._)break;if(n===u.L){if(t=u.R,t.C&&(t.C=!1,u.C=!0,Kr(this,u),t=u.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,Qr(this,t),t=u.R),t.C=u.C,u.C=t.R.C=!1,Kr(this,u),n=this._;break}}else if(t=u.L,t.C&&(t.C=!1,u.C=!0,Qr(this,u),t=u.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,Kr(this,t),t=u.L),t.C=u.C,u.C=t.L.C=!1,Qr(this,u),n=this._;break}t.C=!0,n=u,u=u.U}while(!n.C);n&&(n.C=!1)}}},Zo.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],u=a[0][1],i=a[1][0],o=a[1][1];return tu(e(n),a).cells.forEach(function(e,a){var c=e.edges,s=e.site,l=t[a]=c.length?c.map(function(n){var t=n.start();return[t.x,t.y]}):s.x>=r&&s.x<=i&&s.y>=u&&s.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];l.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/ka)*ka,y:Math.round(o(n,t)/ka)*ka,i:t}})}var r=wr,u=Sr,i=r,o=u,a=Jc;return n?t(n):(t.links=function(n){return tu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return tu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(Hr),c=-1,s=a.length,l=a[s-1].edge,f=l.l===o?l.r:l.l;++c<s;)u=l,i=f,l=a[c].edge,f=l.l===o?l.r:l.l,r<i.i&&r<f.i&&ru(o,i,f)<0&&t.push([n[r],n[i.i],n[f.i]])}),t},t.x=function(n){return arguments.length?(i=bt(r=n),t):r},t.y=function(n){return arguments.length?(o=bt(u=n),t):u},t.clipExtent=function(n){return arguments.length?(a=null==n?Jc:n,t):a===Jc?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===Jc?null:a&&a[1]},t)};var Jc=[[-1e6,-1e6],[1e6,1e6]];Zo.geom.delaunay=function(n){return Zo.geom.voronoi().triangles(n)},Zo.geom.quadtree=function(n,t,e,r,u){function i(n){function i(n,t,e,r,u,i,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var c=n.x,l=n.y;if(null!=c)if(ua(c-e)+ua(l-r)<.01)s(n,t,e,r,u,i,o,a);else{var f=n.point;n.x=n.y=n.point=null,s(n,f,c,l,u,i,o,a),s(n,t,e,r,u,i,o,a)}else n.x=e,n.y=r,n.point=t}else s(n,t,e,r,u,i,o,a)}function s(n,t,e,r,u,o,a,c){var s=.5*(u+a),l=.5*(o+c),f=e>=s,h=r>=l,g=(h<<1)+f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=ou()),f?u=s:a=s,h?o=l:c=l,i(n,t,e,r,u,o,a,c)}var l,f,h,g,p,v,d,m,y,x=bt(a),M=bt(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)l=n[g],l.x<v&&(v=l.x),l.y<d&&(d=l.y),l.x>m&&(m=l.x),l.y>y&&(y=l.y),f.push(l.x),h.push(l.y);else for(g=0;p>g;++g){var _=+x(l=n[g],g),b=+M(l,g);v>_&&(v=_),d>b&&(d=b),_>m&&(m=_),b>y&&(y=b),f.push(_),h.push(b)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=ou();if(k.add=function(n){i(k,n,+x(n,++g),+M(n,g),v,d,m,y)},k.visit=function(n){au(n,k,v,d,m,y)},g=-1,null==t){for(;++g<p;)i(k,n[g],f[g],h[g],v,d,m,y);--g}else n.forEach(k.add);return f=h=n=l=null,k}var o,a=wr,c=Sr;return(o=arguments.length)?(a=uu,c=iu,3===o&&(u=e,r=t,e=t=0),i(n)):(i.x=function(n){return arguments.length?(a=n,i):a},i.y=function(n){return arguments.length?(c=n,i):c},i.extent=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],u=+n[1][1]),i):null==t?null:[[t,e],[r,u]]},i.size=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=e=0,r=+n[0],u=+n[1]),i):null==t?null:[r-t,u-e]},i)},Zo.interpolateRgb=cu,Zo.interpolateObject=su,Zo.interpolateNumber=lu,Zo.interpolateString=fu;var Gc=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,Kc=new RegExp(Gc.source,"g");Zo.interpolate=hu,Zo.interpolators=[function(n,t){var e=typeof t;return("string"===e?Ia.has(t)||/^(#|rgb\(|hsl\()/.test(t)?cu:fu:t instanceof et?cu:Array.isArray(t)?gu:"object"===e&&isNaN(t)?su:lu)(n,t)}],Zo.interpolateArray=gu;var Qc=function(){return wt},ns=Zo.map({linear:Qc,poly:Mu,quad:function(){return mu},cubic:function(){return yu},sin:function(){return _u},exp:function(){return bu},circle:function(){return wu},elastic:Su,back:ku,bounce:function(){return Eu}}),ts=Zo.map({"in":wt,out:vu,"in-out":du,"out-in":function(n){return du(vu(n))}});Zo.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.substring(0,t):n,r=t>=0?n.substring(t+1):"in";return e=ns.get(e)||Qc,r=ts.get(r)||wt,pu(r(e.apply(null,Vo.call(arguments,1))))},Zo.interpolateHcl=Au,Zo.interpolateHsl=Cu,Zo.interpolateLab=Nu,Zo.interpolateRound=zu,Zo.transform=function(n){var t=$o.createElementNS(Zo.ns.prefix.svg,"g");return(Zo.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Lu(e?e.matrix:es)})(n)},Lu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var es={a:1,b:0,c:0,d:1,e:0,f:0};Zo.interpolateTransform=Du,Zo.layout={},Zo.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(ju(n[e]));return t}},Zo.layout.chord=function(){function n(){var n,s,f,h,g,p={},v=[],d=Zo.range(i),m=[];for(e=[],r=[],n=0,h=-1;++h<i;){for(s=0,g=-1;++g<i;)s+=u[h][g];v.push(s),m.push(Zo.range(i)),n+=s}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&m.forEach(function(n,t){n.sort(function(n,e){return a(u[t][n],u[t][e])})}),n=(wa-l*i)/n,s=0,h=-1;++h<i;){for(f=s,g=-1;++g<i;){var y=d[h],x=m[y][g],M=u[y][x],_=s,b=s+=M*n;p[y+"-"+x]={index:y,subindex:x,startAngle:_,endAngle:b,value:M}}r[y]={index:y,startAngle:f,endAngle:s,value:(s-f)/n},s+=l}for(h=-1;++h<i;)for(g=h-1;++g<i;){var w=p[h+"-"+g],S=p[g+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}c&&t()}function t(){e.sort(function(n,t){return c((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,u,i,o,a,c,s={},l=0;return s.matrix=function(n){return arguments.length?(i=(u=n)&&u.length,e=r=null,s):u},s.padding=function(n){return arguments.length?(l=n,e=r=null,s):l},s.sortGroups=function(n){return arguments.length?(o=n,e=r=null,s):o},s.sortSubgroups=function(n){return arguments.length?(a=n,e=null,s):a},s.sortChords=function(n){return arguments.length?(c=n,e&&t(),s):c},s.chords=function(){return e||n(),e},s.groups=function(){return r||n(),r},s},Zo.layout.force=function(){function n(n){return function(t,e,r,u){if(t.point!==n){var i=t.cx-n.x,o=t.cy-n.y,a=u-e,c=i*i+o*o;if(c>a*a/d){if(p>c){var s=t.charge/c;n.px-=i*s,n.py-=o*s}return!0}if(t.point&&c&&p>c){var s=t.pointCharge/c;n.px-=i*s,n.py-=o*s}}return!t.charge}}function t(n){n.px=Zo.event.x,n.py=Zo.event.y,a.resume()}var e,r,u,i,o,a={},c=Zo.dispatch("start","tick","end"),s=[1,1],l=.9,f=rs,h=us,g=-30,p=is,v=.1,d=.64,m=[],y=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,x,M,_=m.length,b=y.length;for(e=0;b>e;++e)a=y[e],f=a.source,h=a.target,x=h.x-f.x,M=h.y-f.y,(p=x*x+M*M)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,x*=p,M*=p,h.x-=x*(d=f.weight/(h.weight+f.weight)),h.y-=M*d,f.x+=x*(d=1-d),f.y+=M*d);if((d=r*v)&&(x=s[0]/2,M=s[1]/2,e=-1,d))for(;++e<_;)a=m[e],a.x+=(x-a.x)*d,a.y+=(M-a.y)*d;if(g)for(Vu(t=Zo.geom.quadtree(m),r,o),e=-1;++e<_;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<_;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*l,a.y-=(a.py-(a.py=a.y))*l);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(y=n,a):y},a.size=function(n){return arguments.length?(s=n,a):s},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(l=+n,a):l},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),Zo.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=y[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,s=o.length;++a<s;)if(!isNaN(i=o[a][n]))return i;return Math.random()*r}var t,e,r,c=m.length,l=y.length,p=s[0],v=s[1];for(t=0;c>t;++t)(r=m[t]).index=t,r.weight=0;for(t=0;l>t;++t)r=y[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;l>t;++t)u[t]=+f.call(this,y[t],t);else for(t=0;l>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;l>t;++t)i[t]=+h.call(this,y[t],t);else for(t=0;l>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=Zo.behavior.drag().origin(wt).on("dragstart.force",Ou).on("drag.force",t).on("dragend.force",Yu)),arguments.length?(this.on("mouseover.force",Iu).on("mouseout.force",Zu).call(e),void 0):e},Zo.rebind(a,c,"on")};var rs=20,us=1,is=1/0;Zo.layout.hierarchy=function(){function n(u){var i,o=[u],a=[];for(u.depth=0;null!=(i=o.pop());)if(a.push(i),(s=e.call(n,i,i.depth))&&(c=s.length)){for(var c,s,l;--c>=0;)o.push(l=s[c]),l.parent=i,l.depth=i.depth+1;r&&(i.value=0),i.children=s}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return Bu(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),a}var t=Gu,e=Wu,r=Ju;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&($u(t,function(n){n.children&&(n.value=0)}),Bu(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},Zo.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,s=-1;for(r=t.value?r/t.value:0;++s<o;)n(a=i[s],e,c=a.value*r,u),e+=c}}function t(n){var e=n.children,r=0;if(e&&(u=e.length))for(var u,i=-1;++i<u;)r=Math.max(r,t(e[i]));return 1+r}function e(e,i){var o=r.call(this,e,i);return n(o[0],0,u[0],u[1]/t(o[0])),o}var r=Zo.layout.hierarchy(),u=[1,1];return e.size=function(n){return arguments.length?(u=n,e):u},Xu(e,r)},Zo.layout.pie=function(){function n(i){var o=i.map(function(e,r){return+t.call(n,e,r)}),a=+("function"==typeof r?r.apply(this,arguments):r),c=(("function"==typeof u?u.apply(this,arguments):u)-a)/Zo.sum(o),s=Zo.range(i.length);null!=e&&s.sort(e===os?function(n,t){return o[t]-o[n]}:function(n,t){return e(i[n],i[t])});var l=[];return s.forEach(function(n){var t;l[n]={data:i[n],value:t=o[n],startAngle:a,endAngle:a+=t*c}}),l}var t=Number,e=os,r=0,u=wa;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n};var os={};Zo.layout.stack=function(){function n(a,c){var s=a.map(function(e,r){return t.call(n,e,r)}),l=s.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,l,c);s=Zo.permute(s,f),l=Zo.permute(l,f);var h,g,p,v=r.call(n,l,c),d=s.length,m=s[0].length;for(g=0;m>g;++g)for(u.call(n,s[0][g],p=v[g],l[0][g][1]),h=1;d>h;++h)u.call(n,s[h][g],p+=l[h-1][g][1],l[h][g][1]);return a}var t=wt,e=ei,r=ri,u=ti,i=Qu,o=ni;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:as.get(t)||ei,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:cs.get(t)||ri,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var as=Zo.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(ui),i=n.map(ii),o=Zo.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,s=[],l=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],s.push(e)):(c+=i[e],l.push(e));return l.reverse().concat(s)},reverse:function(n){return Zo.range(n.length).reverse()},"default":ei}),cs=Zo.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,s,l=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=s=0,e=1;h>e;++e){for(t=0,u=0;l>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];l>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,s>c&&(s=c)}for(e=0;h>e;++e)g[e]-=s;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ri});Zo.layout.histogram=function(){function n(n,i){for(var o,a,c=[],s=n.map(e,this),l=r.call(this,s,i),f=u.call(this,l,s,i),i=-1,h=s.length,g=f.length-1,p=t?1:1/h;++i<g;)o=c[i]=[],o.dx=f[i+1]-(o.x=f[i]),o.y=0;if(g>0)for(i=-1;++i<h;)a=s[i],a>=l[0]&&a<=l[1]&&(o=c[Zo.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=si,u=ai;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=bt(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return ci(n,t)}:bt(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},Zo.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],s=u[1],l=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,Bu(a,function(n){n.r=+l(n.value)}),Bu(a,pi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/s))/2;Bu(a,function(n){n.r+=f}),Bu(a,pi),Bu(a,function(n){n.r-=f})}return mi(a,c/2,s/2,t?1:1/Math.max(2*a.r/c,2*a.r/s)),o}var t,e=Zo.layout.hierarchy().sort(li),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Xu(n,e)},Zo.layout.tree=function(){function n(n,u){var l=o.call(this,n,u),f=l[0],h=t(f);if(Bu(h,e),h.parent.m=-h.z,$u(h,r),s)$u(f,i);else{var g=f,p=f,v=f;$u(f,function(n){n.x<g.x&&(g=n),n.x>p.x&&(p=n),n.depth>v.depth&&(v=n)});var d=a(g,p)/2-g.x,m=c[0]/(p.x+a(p,g)/2+d),y=c[1]/(v.depth||1);$u(f,function(n){n.x=(n.x+d)*m,n.y=n.depth*y})}return l}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var u,i=t.children,o=0,a=i.length;a>o;++o)r.push((i[o]=u={_:i[o],parent:t,children:(u=i[o].children)&&u.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=u);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){wi(n);var i=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-i):n.z=i}else r&&(n.z=r.z+a(n._,r._));n.parent.A=u(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function u(n,t,e){if(t){for(var r,u=n,i=n,o=t,c=u.parent.children[0],s=u.m,l=i.m,f=o.m,h=c.m;o=_i(o),u=Mi(u),o&&u;)c=Mi(c),i=_i(i),i.a=n,r=o.z+f-u.z-s+a(o._,u._),r>0&&(bi(Si(o,n,e),n,r),s+=r,l+=r),f+=o.m,s+=u.m,h+=c.m,l+=i.m;o&&!_i(i)&&(i.t=o,i.m+=f-l),u&&!Mi(c)&&(c.t=u,c.m+=s-h,e=n)}return e}function i(n){n.x*=c[0],n.y=n.depth*c[1]}var o=Zo.layout.hierarchy().sort(null).value(null),a=xi,c=[1,1],s=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(s=null==(c=t)?i:null,n):s?null:c},n.nodeSize=function(t){return arguments.length?(s=null==(c=t)?null:i,n):s?c:null},Xu(n,o)},Zo.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],s=0;Bu(c,function(n){var t=n.children;t&&t.length?(n.x=Ei(t),n.y=ki(t)):(n.x=o?s+=e(n,o):0,n.y=0,o=n)});var l=Ai(c),f=Ci(c),h=l.x-e(l,f)/2,g=f.x+e(f,l)/2;return Bu(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=Zo.layout.hierarchy().sort(null).value(null),e=xi,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Xu(n,t)},Zo.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++u<i;)r=(e=n[u]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,s=f(e),l=[],h=i.slice(),p=1/0,v="slice"===g?s.dx:"dice"===g?s.dy:"slice-dice"===g?1&e.depth?s.dy:s.dx:Math.min(s.dx,s.dy);for(n(h,s.dx*s.dy/e.value),l.area=0;(c=h.length)>0;)l.push(o=h[c-1]),l.area+=o.area,"squarify"!==g||(a=r(l,v))<=p?(h.pop(),p=a):(l.area-=l.pop().area,u(l,v,s,!1),v=Math.min(s.dx,s.dy),l.length=l.area=0,p=1/0);l.length&&(u(l,v,s,!0),l.length=l.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(i>e&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,s=e.y,l=t?c(n.area/t):0;if(t==e.dx){for((r||l>e.dy)&&(l=e.dy);++i<o;)u=n[i],u.x=a,u.y=s,u.dy=l,a+=u.dx=Math.min(e.x+e.dx-a,l?c(u.area/l):0);u.z=!0,u.dx+=e.x+e.dx-a,e.y+=l,e.dy-=l}else{for((r||l>e.dx)&&(l=e.dx);++i<o;)u=n[i],u.x=a,u.y=s,u.dx=l,s+=u.dy=Math.min(e.y+e.dy-s,l?c(u.area/l):0);u.z=!1,u.dy+=e.y+e.dy-s,e.x+=l,e.dx-=l}}function i(r){var u=o||a(r),i=u[0];return i.x=0,i.y=0,i.dx=s[0],i.dy=s[1],o&&a.revalue(i),n([i],i.dx*i.dy/i.value),(o?e:t)(i),h&&(o=u),u}var o,a=Zo.layout.hierarchy(),c=Math.round,s=[1,1],l=null,f=Ni,h=!1,g="squarify",p=.5*(1+Math.sqrt(5));return i.size=function(n){return arguments.length?(s=n,i):s},i.padding=function(n){function t(t){var e=n.call(i,t,t.depth);return null==e?Ni(t):zi(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return zi(t,n)}if(!arguments.length)return l;var r;return f=null==(l=n)?Ni:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,i},i.round=function(n){return arguments.length?(c=n?Math.round:Number,i):c!=Number},i.sticky=function(n){return arguments.length?(h=n,o=null,i):h},i.ratio=function(n){return arguments.length?(p=n,i):p},i.mode=function(n){return arguments.length?(g=n+"",i):g},Xu(i,a)},Zo.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=Zo.random.normal.apply(Zo,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=Zo.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},Zo.scale={};var ss={floor:wt,ceil:wt};Zo.scale.linear=function(){return Ui([0,1],[0,1],hu,!1)};var ls={s:1,g:1,p:1,r:1,e:1};Zo.scale.log=function(){return Vi(Zo.scale.linear().domain([0,1]),10,!0,[1,10])};var fs=Zo.format(".0e"),hs={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};Zo.scale.pow=function(){return Xi(Zo.scale.linear(),1,[0,1])},Zo.scale.sqrt=function(){return Zo.scale.pow().exponent(.5)},Zo.scale.ordinal=function(){return Bi([],{t:"range",a:[[]]})},Zo.scale.category10=function(){return Zo.scale.ordinal().range(gs)},Zo.scale.category20=function(){return Zo.scale.ordinal().range(ps)},Zo.scale.category20b=function(){return Zo.scale.ordinal().range(vs)},Zo.scale.category20c=function(){return Zo.scale.ordinal().range(ds)};var gs=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(vt),ps=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(vt),vs=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(vt),ds=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(vt);Zo.scale.quantile=function(){return Wi([],[])},Zo.scale.quantize=function(){return Ji(0,1,[0,1])},Zo.scale.threshold=function(){return Gi([.5],[0,1])},Zo.scale.identity=function(){return Ki([0,1])},Zo.svg={},Zo.svg.arc=function(){function n(){var n=t.apply(this,arguments),i=e.apply(this,arguments),o=r.apply(this,arguments)+ms,a=u.apply(this,arguments)+ms,c=(o>a&&(c=o,o=a,a=c),a-o),s=ba>c?"0":"1",l=Math.cos(o),f=Math.sin(o),h=Math.cos(a),g=Math.sin(a); +return c>=ys?n?"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"M0,"+n+"A"+n+","+n+" 0 1,0 0,"+-n+"A"+n+","+n+" 0 1,0 0,"+n+"Z":"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"Z":n?"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L"+n*h+","+n*g+"A"+n+","+n+" 0 "+s+",0 "+n*l+","+n*f+"Z":"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L0,0"+"Z"}var t=Qi,e=no,r=to,u=eo;return n.innerRadius=function(e){return arguments.length?(t=bt(e),n):t},n.outerRadius=function(t){return arguments.length?(e=bt(t),n):e},n.startAngle=function(t){return arguments.length?(r=bt(t),n):r},n.endAngle=function(t){return arguments.length?(u=bt(t),n):u},n.centroid=function(){var n=(t.apply(this,arguments)+e.apply(this,arguments))/2,i=(r.apply(this,arguments)+u.apply(this,arguments))/2+ms;return[Math.cos(i)*n,Math.sin(i)*n]},n};var ms=-Sa,ys=wa-ka;Zo.svg.line=function(){return ro(wt)};var xs=Zo.map({linear:uo,"linear-closed":io,step:oo,"step-before":ao,"step-after":co,basis:po,"basis-open":vo,"basis-closed":mo,bundle:yo,cardinal:fo,"cardinal-open":so,"cardinal-closed":lo,monotone:So});xs.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Ms=[0,2/3,1/3,0],_s=[0,1/3,2/3,0],bs=[0,1/6,2/3,1/6];Zo.svg.line.radial=function(){var n=ro(ko);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},ao.reverse=co,co.reverse=ao,Zo.svg.area=function(){return Eo(wt)},Zo.svg.area.radial=function(){var n=Eo(ko);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},Zo.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),s=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,s)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,s.r,s.p0)+r(s.r,s.p1,s.a1-s.a0)+u(s.r,s.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)+ms,l=s.call(n,u,r)+ms;return{r:i,a0:o,a1:l,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(l),i*Math.sin(l)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>ba)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=gr,o=pr,a=Ao,c=to,s=eo;return n.radius=function(t){return arguments.length?(a=bt(t),n):a},n.source=function(t){return arguments.length?(i=bt(t),n):i},n.target=function(t){return arguments.length?(o=bt(t),n):o},n.startAngle=function(t){return arguments.length?(c=bt(t),n):c},n.endAngle=function(t){return arguments.length?(s=bt(t),n):s},n},Zo.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=gr,e=pr,r=Co;return n.source=function(e){return arguments.length?(t=bt(e),n):t},n.target=function(t){return arguments.length?(e=bt(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},Zo.svg.diagonal.radial=function(){var n=Zo.svg.diagonal(),t=Co,e=n.projection;return n.projection=function(n){return arguments.length?e(No(t=n)):t},n},Zo.svg.symbol=function(){function n(n,r){return(ws.get(t.call(this,n,r))||To)(e.call(this,n,r))}var t=Lo,e=zo;return n.type=function(e){return arguments.length?(t=bt(e),n):t},n.size=function(t){return arguments.length?(e=bt(t),n):e},n};var ws=Zo.map({circle:To,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*As)),e=t*As;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/Es),e=t*Es/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/Es),e=t*Es/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});Zo.svg.symbolTypes=ws.keys();var Ss,ks,Es=Math.sqrt(3),As=Math.tan(30*Aa),Cs=[],Ns=0;Cs.call=pa.call,Cs.empty=pa.empty,Cs.node=pa.node,Cs.size=pa.size,Zo.transition=function(n){return arguments.length?Ss?n.transition():n:ma.transition()},Zo.transition.prototype=Cs,Cs.select=function(n){var t,e,r,u=this.id,i=[];n=b(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]);for(var c=this[o],s=-1,l=c.length;++s<l;)(r=c[s])&&(e=n.call(r,r.__data__,s,o))?("__data__"in r&&(e.__data__=r.__data__),Po(e,s,u,r.__transition__[u]),t.push(e)):t.push(null)}return qo(i,u)},Cs.selectAll=function(n){var t,e,r,u,i,o=this.id,a=[];n=w(n);for(var c=-1,s=this.length;++c<s;)for(var l=this[c],f=-1,h=l.length;++f<h;)if(r=l[f]){i=r.__transition__[o],e=n.call(r,r.__data__,f,c),a.push(t=[]);for(var g=-1,p=e.length;++g<p;)(u=e[g])&&Po(u,g,o,i),t.push(u)}return qo(a,o)},Cs.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=R(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return qo(u,this.id)},Cs.tween=function(n,t){var e=this.id;return arguments.length<2?this.node().__transition__[e].tween.get(n):P(this,null==t?function(t){t.__transition__[e].tween.remove(n)}:function(r){r.__transition__[e].tween.set(n,t)})},Cs.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Du:hu,a=Zo.ns.qualify(n);return Ro(this,"attr."+n,t,a.local?i:u)},Cs.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=Zo.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Cs.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=Wo.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=hu(u,t),function(t){this.style.setProperty(n,r(t),e)})})}var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}return Ro(this,"style."+n,t,u)},Cs.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,Wo.getComputedStyle(this,null).getPropertyValue(n));return i&&function(t){this.style.setProperty(n,i(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},Cs.text=function(n){return Ro(this,"text",n,Do)},Cs.remove=function(){return this.each("end.transition",function(){var n;this.__transition__.count<2&&(n=this.parentNode)&&n.removeChild(this)})},Cs.ease=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].ease:("function"!=typeof n&&(n=Zo.ease.apply(Zo,arguments)),P(this,function(e){e.__transition__[t].ease=n}))},Cs.delay=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].delay:P(this,"function"==typeof n?function(e,r,u){e.__transition__[t].delay=+n.call(e,e.__data__,r,u)}:(n=+n,function(e){e.__transition__[t].delay=n}))},Cs.duration=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].duration:P(this,"function"==typeof n?function(e,r,u){e.__transition__[t].duration=Math.max(1,n.call(e,e.__data__,r,u))}:(n=Math.max(1,n),function(e){e.__transition__[t].duration=n}))},Cs.each=function(n,t){var e=this.id;if(arguments.length<2){var r=ks,u=Ss;Ss=e,P(this,function(t,r,u){ks=t.__transition__[e],n.call(t,t.__data__,r,u)}),ks=r,Ss=u}else P(this,function(r){var u=r.__transition__[e];(u.event||(u.event=Zo.dispatch("start","end"))).on(n,t)});return this},Cs.transition=function(){for(var n,t,e,r,u=this.id,i=++Ns,o=[],a=0,c=this.length;c>a;a++){o.push(n=[]);for(var t=this[a],s=0,l=t.length;l>s;s++)(e=t[s])&&(r=Object.create(e.__transition__[u]),r.delay+=r.duration,Po(e,s,i,r)),n.push(e)}return qo(o,i)},Zo.svg.axis=function(){function n(n){n.each(function(){var n,s=Zo.select(this),l=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):wt:t,p=s.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",ka),d=Zo.transition(p.exit()).style("opacity",ka).remove(),m=Zo.transition(p.order()).style("opacity",1),y=Ti(f),x=s.selectAll(".domain").data([0]),M=(x.enter().append("path").attr("class","domain"),Zo.transition(x));v.append("line"),v.append("text");var _=v.select("line"),b=m.select("line"),w=p.select("text").text(g),S=v.select("text"),k=m.select("text");switch(r){case"bottom":n=Uo,_.attr("y2",u),S.attr("y",Math.max(u,0)+o),b.attr("x2",0).attr("y2",u),k.attr("x",0).attr("y",Math.max(u,0)+o),w.attr("dy",".71em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+i+"V0H"+y[1]+"V"+i);break;case"top":n=Uo,_.attr("y2",-u),S.attr("y",-(Math.max(u,0)+o)),b.attr("x2",0).attr("y2",-u),k.attr("x",0).attr("y",-(Math.max(u,0)+o)),w.attr("dy","0em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+-i+"V0H"+y[1]+"V"+-i);break;case"left":n=jo,_.attr("x2",-u),S.attr("x",-(Math.max(u,0)+o)),b.attr("x2",-u).attr("y2",0),k.attr("x",-(Math.max(u,0)+o)).attr("y",0),w.attr("dy",".32em").style("text-anchor","end"),M.attr("d","M"+-i+","+y[0]+"H0V"+y[1]+"H"+-i);break;case"right":n=jo,_.attr("x2",u),S.attr("x",Math.max(u,0)+o),b.attr("x2",u).attr("y2",0),k.attr("x",Math.max(u,0)+o).attr("y",0),w.attr("dy",".32em").style("text-anchor","start"),M.attr("d","M"+i+","+y[0]+"H0V"+y[1]+"H"+i)}if(f.rangeBand){var E=f,A=E.rangeBand()/2;l=f=function(n){return E(n)+A}}else l.rangeBand?l=f:d.call(n,f);v.call(n,l),m.call(n,f)})}var t,e=Zo.scale.linear(),r=zs,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Ls?t+"":zs,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var zs="bottom",Ls={top:1,right:1,bottom:1,left:1};Zo.svg.brush=function(){function n(i){i.each(function(){var i=Zo.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=i.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),i.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=i.selectAll(".resize").data(p,wt);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Ts[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,f=Zo.transition(i),h=Zo.transition(o);c&&(l=Ti(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),e(f)),s&&(l=Ti(s),h.attr("y",l[0]).attr("height",l[1]-l[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+l[+/e$/.test(n)]+","+f[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",l[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",l[1]-l[0])}function r(n){n.select(".extent").attr("y",f[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",f[1]-f[0])}function u(){function u(){32==Zo.event.keyCode&&(C||(x=null,z[0]-=l[1],z[1]-=f[1],C=2),y())}function p(){32==Zo.event.keyCode&&2==C&&(z[0]+=l[1],z[1]+=f[1],C=0,y())}function v(){var n=Zo.mouse(_),u=!1;M&&(n[0]+=M[0],n[1]+=M[1]),C||(Zo.event.altKey?(x||(x=[(l[0]+l[1])/2,(f[0]+f[1])/2]),z[0]=l[+(n[0]<x[0])],z[1]=f[+(n[1]<x[1])]):x=null),E&&d(n,c,0)&&(e(S),u=!0),A&&d(n,s,1)&&(r(S),u=!0),u&&(t(S),w({type:"brush",mode:C?"move":"resize"}))}function d(n,t,e){var r,u,a=Ti(t),c=a[0],s=a[1],p=z[e],v=e?f:l,d=v[1]-v[0];return C&&(c-=p,s-=d+p),r=(e?g:h)?Math.max(c,Math.min(s,n[e])):n[e],C?u=(r+=p)+d:(x&&(p=Math.max(c,Math.min(s,2*x[e]-r))),r>p?(u=r,r=p):u=p),v[0]!=r||v[1]!=u?(e?o=null:i=null,v[0]=r,v[1]=u,!0):void 0}function m(){v(),S.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),Zo.select("body").style("cursor",null),L.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),N(),w({type:"brushend"})}var x,M,_=this,b=Zo.select(Zo.event.target),w=a.of(_,arguments),S=Zo.select(_),k=b.datum(),E=!/^(n|s)$/.test(k)&&c,A=!/^(e|w)$/.test(k)&&s,C=b.classed("extent"),N=I(),z=Zo.mouse(_),L=Zo.select(Wo).on("keydown.brush",u).on("keyup.brush",p);if(Zo.event.changedTouches?L.on("touchmove.brush",v).on("touchend.brush",m):L.on("mousemove.brush",v).on("mouseup.brush",m),S.interrupt().selectAll("*").interrupt(),C)z[0]=l[0]-z[0],z[1]=f[0]-z[1];else if(k){var T=+/w$/.test(k),q=+/^n/.test(k);M=[l[1-T]-z[0],f[1-q]-z[1]],z[0]=l[T],z[1]=f[q]}else Zo.event.altKey&&(x=z.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),Zo.select("body").style("cursor",b.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=M(n,"brushstart","brush","brushend"),c=null,s=null,l=[0,0],f=[0,0],h=!0,g=!0,p=qs[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:l,y:f,i:i,j:o},e=this.__chart__||t;this.__chart__=t,Ss?Zo.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,l=e.x,f=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=gu(l,t.x),r=gu(f,t.y);return i=o=null,function(u){l=t.x=e(u),f=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){i=t.i,o=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,p=qs[!c<<1|!s],n):c},n.y=function(t){return arguments.length?(s=t,p=qs[!c<<1|!s],n):s},n.clamp=function(t){return arguments.length?(c&&s?(h=!!t[0],g=!!t[1]):c?h=!!t:s&&(g=!!t),n):c&&s?[h,g]:c?h:s?g:null},n.extent=function(t){var e,r,u,a,h;return arguments.length?(c&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),i=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(h=e,e=r,r=h),(e!=l[0]||r!=l[1])&&(l=[e,r])),s&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],s.invert&&(u=s(u),a=s(a)),u>a&&(h=u,u=a,a=h),(u!=f[0]||a!=f[1])&&(f=[u,a])),n):(c&&(i?(e=i[0],r=i[1]):(e=l[0],r=l[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(h=e,e=r,r=h))),s&&(o?(u=o[0],a=o[1]):(u=f[0],a=f[1],s.invert&&(u=s.invert(u),a=s.invert(a)),u>a&&(h=u,u=a,a=h))),c&&s?[[e,u],[r,a]]:c?[e,r]:s&&[u,a])},n.clear=function(){return n.empty()||(l=[0,0],f=[0,0],i=o=null),n},n.empty=function(){return!!c&&l[0]==l[1]||!!s&&f[0]==f[1]},Zo.rebind(n,a,"on")};var Ts={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},qs=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Rs=Qa.format=ic.timeFormat,Ds=Rs.utc,Ps=Ds("%Y-%m-%dT%H:%M:%S.%LZ");Rs.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Ho:Ps,Ho.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Ho.toString=Ps.toString,Qa.second=Dt(function(n){return new nc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),Qa.seconds=Qa.second.range,Qa.seconds.utc=Qa.second.utc.range,Qa.minute=Dt(function(n){return new nc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),Qa.minutes=Qa.minute.range,Qa.minutes.utc=Qa.minute.utc.range,Qa.hour=Dt(function(n){var t=n.getTimezoneOffset()/60;return new nc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),Qa.hours=Qa.hour.range,Qa.hours.utc=Qa.hour.utc.range,Qa.month=Dt(function(n){return n=Qa.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),Qa.months=Qa.month.range,Qa.months.utc=Qa.month.utc.range;var Us=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],js=[[Qa.second,1],[Qa.second,5],[Qa.second,15],[Qa.second,30],[Qa.minute,1],[Qa.minute,5],[Qa.minute,15],[Qa.minute,30],[Qa.hour,1],[Qa.hour,3],[Qa.hour,6],[Qa.hour,12],[Qa.day,1],[Qa.day,2],[Qa.week,1],[Qa.month,1],[Qa.month,3],[Qa.year,1]],Hs=Rs.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",we]]),Fs={range:function(n,t,e){return Zo.range(Math.ceil(n/e)*e,+t,e).map(Oo)},floor:wt,ceil:wt};js.year=Qa.year,Qa.scale=function(){return Fo(Zo.scale.linear(),js,Hs)};var Os=js.map(function(n){return[n[0].utc,n[1]]}),Ys=Ds.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",we]]);Os.year=Qa.year.utc,Qa.scale.utc=function(){return Fo(Zo.scale.linear(),Os,Ys)},Zo.text=St(function(n){return n.responseText}),Zo.json=function(n,t){return kt(n,"application/json",Yo,t)},Zo.html=function(n,t){return kt(n,"text/html",Io,t)},Zo.xml=St(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(Zo):"object"==typeof module&&module.exports&&(module.exports=Zo),this.d3=Zo}();
\ No newline at end of file diff --git a/third_party/webkit/PerformanceTests/MotionMark/resources/debug-runner/graph.js b/third_party/webkit/PerformanceTests/MotionMark/resources/debug-runner/graph.js new file mode 100644 index 0000000000..4803936219 --- /dev/null +++ b/third_party/webkit/PerformanceTests/MotionMark/resources/debug-runner/graph.js @@ -0,0 +1,615 @@ +Utilities.extendObject(window.benchmarkController, { + updateGraphData: function(testResult, testData, options) + { + var element = document.getElementById("test-graph-data"); + element.innerHTML = ""; + element._testResult = testResult; + element._options = options; + + var margins = new Insets(30, 30, 30, 40); + var size = Point.elementClientSize(element); + size.y = window.innerHeight - element.offsetTop; + size = size.subtract(margins.size); + + // Convert from compact JSON output to propertied data + var samplesWithProperties = {}; + [Strings.json.controller, Strings.json.complexity, Strings.json.complexityAverage].forEach(function(seriesName) { + var series = testData[Strings.json.samples][seriesName]; + samplesWithProperties[seriesName] = series.toArray(); + }) + + this.createTimeGraph(testResult, samplesWithProperties[Strings.json.controller], testData[Strings.json.marks], testData[Strings.json.controller], options, margins, size); + this.onTimeGraphOptionsChanged(); + + this._showOrHideNodes(true, "form[name=graph-type]"); + document.forms["graph-type"].elements["type"] = "complexity"; + this.createComplexityGraph(testResult, testData[Strings.json.controller], samplesWithProperties, options, margins, size); + this.onComplexityGraphOptionsChanged(); + + this.onGraphTypeChanged(); + }, + + _addRegressionLine: function(parent, xScale, yScale, points, range, isAlongYAxis) + { + var polygon = []; + var line = [] + var xRange = isAlongYAxis ? range : 0; + var yRange = isAlongYAxis ? 0 : range; + for (var i = 0; i < points.length; ++i) { + var point = points[i]; + var x; + if (xRange instanceof Array) + x = xRange[0]; + else + x = point[0] + xRange; + polygon.push(xScale(x), yScale(point[1] + yRange)); + line.push(xScale(point[0]), yScale(point[1])); + } + for (var i = points.length - 1; i >= 0; --i) { + var point = points[i]; + var x; + if (xRange instanceof Array) + x = xRange[1]; + else + x = point[0] - xRange; + polygon.push(xScale(x), yScale(point[1] - yRange)); + } + parent.append("polygon") + .attr("points", polygon.join(",")); + parent.append("line") + .attr("x1", line[0]) + .attr("y1", line[1]) + .attr("x2", line[2]) + .attr("y2", line[3]); + }, + + _addRegression: function(data, svg, xScale, yScale) + { + svg.append("circle") + .attr("cx", xScale(data.segment1[1][0])) + .attr("cy", yScale(data.segment1[1][1])) + .attr("r", 5); + this._addRegressionLine(svg, xScale, yScale, data.segment1, data.stdev); + this._addRegressionLine(svg, xScale, yScale, data.segment2, data.stdev); + }, + + createComplexityGraph: function(result, timeRegressions, data, options, margins, size) + { + var svg = d3.select("#test-graph-data").append("svg") + .attr("id", "complexity-graph") + .attr("class", "hidden") + .attr("width", size.width + margins.left + margins.right) + .attr("height", size.height + margins.top + margins.bottom) + .append("g") + .attr("transform", "translate(" + margins.left + "," + margins.top + ")"); + + var timeSamples = data[Strings.json.controller]; + + var xMin = 100000, xMax = 0; + if (timeRegressions) { + timeRegressions.forEach(function(regression) { + for (var i = regression.startIndex; i <= regression.endIndex; ++i) { + xMin = Math.min(xMin, timeSamples[i].complexity); + xMax = Math.max(xMax, timeSamples[i].complexity); + } + }); + } else { + xMin = d3.min(timeSamples, function(s) { return s.complexity; }); + xMax = d3.max(timeSamples, function(s) { return s.complexity; }); + } + + var xScale = d3.scale.linear() + .range([0, size.width]) + .domain([xMin, xMax]); + var yScale = d3.scale.linear() + .range([size.height, 0]) + .domain([1000/20, 1000/60]); + + var xAxis = d3.svg.axis() + .scale(xScale) + .orient("bottom"); + var yAxis = d3.svg.axis() + .scale(yScale) + .tickValues([1000/20, 1000/25, 1000/30, 1000/35, 1000/40, 1000/45, 1000/50, 1000/55, 1000/60]) + .tickFormat(function(d) { return (1000 / d).toFixed(0); }) + .orient("left"); + + // x-axis + svg.append("g") + .attr("class", "x axis") + .attr("transform", "translate(0," + size.height + ")") + .call(xAxis); + + // y-axis + svg.append("g") + .attr("class", "y axis") + .call(yAxis); + + // time result + var mean = svg.append("g") + .attr("class", "mean complexity"); + var timeResult = result[Strings.json.controller]; + var yMin = yScale.domain()[0], yMax = yScale.domain()[1]; + this._addRegressionLine(mean, xScale, yScale, [[timeResult.average, yMin], [timeResult.average, yMax]], timeResult.stdev, true); + + // regression + this._addRegression(result[Strings.json.complexity], svg.append("g").attr("class", "regression raw"), xScale, yScale); + this._addRegression(result[Strings.json.complexityAverage], svg.append("g").attr("class", "regression average"), xScale, yScale); + + var bootstrapResult = result[Strings.json.complexity][Strings.json.bootstrap]; + if (bootstrapResult) { + var histogram = d3.layout.histogram() + .bins(xScale.ticks(100))(bootstrapResult.data); + var yBootstrapScale = d3.scale.linear() + .range([size.height/2, 0]) + .domain([0, d3.max(histogram, function(d) { return d.y; })]); + group = svg.append("g").attr("class", "bootstrap"); + var bar = group.selectAll(".bar") + .data(histogram) + .enter().append("g") + .attr("class", "bar") + .attr("transform", function(d) { return "translate(" + xScale(d.x) + "," + yBootstrapScale(d.y) + ")"; }); + bar.append("rect") + .attr("x", 1) + .attr("y", size.height/2) + .attr("width", xScale(histogram[1].x) - xScale(histogram[0].x) - 1) + .attr("height", function(d) { return size.height/2 - yBootstrapScale(d.y); }); + group = group.append("g").attr("class", "median"); + this._addRegressionLine(group, xScale, yScale, [[bootstrapResult.median, yMin], [bootstrapResult.median, yMax]], [bootstrapResult.confidenceLow, bootstrapResult.confidenceHigh], true); + group.append("circle") + .attr("cx", xScale(bootstrapResult.median)) + .attr("cy", yScale(1000/60)) + .attr("r", 5); + } + + // series + group = svg.append("g") + .attr("class", "series raw") + .selectAll("line") + .data(data[Strings.json.complexity]) + .enter(); + group.append("line") + .attr("x1", function(d) { return xScale(d.complexity) - 3; }) + .attr("x2", function(d) { return xScale(d.complexity) + 3; }) + .attr("y1", function(d) { return yScale(d.frameLength) - 3; }) + .attr("y2", function(d) { return yScale(d.frameLength) + 3; }); + group.append("line") + .attr("x1", function(d) { return xScale(d.complexity) - 3; }) + .attr("x2", function(d) { return xScale(d.complexity) + 3; }) + .attr("y1", function(d) { return yScale(d.frameLength) + 3; }) + .attr("y2", function(d) { return yScale(d.frameLength) - 3; }); + + group = svg.append("g") + .attr("class", "series average") + .selectAll("circle") + .data(data[Strings.json.complexityAverage]) + .enter(); + group.append("circle") + .attr("cx", function(d) { return xScale(d.complexity); }) + .attr("cy", function(d) { return yScale(d.frameLength); }) + .attr("r", 3) + group.append("line") + .attr("x1", function(d) { return xScale(d.complexity); }) + .attr("x2", function(d) { return xScale(d.complexity); }) + .attr("y1", function(d) { return yScale(d.frameLength - d.stdev); }) + .attr("y2", function(d) { return yScale(d.frameLength + d.stdev); }); + + // Cursor + var cursorGroup = svg.append("g").attr("class", "cursor hidden"); + cursorGroup.append("line") + .attr("class", "x") + .attr("x1", 0) + .attr("x2", 0) + .attr("y1", yScale(yAxis.scale().domain()[0]) + 10) + .attr("y2", yScale(yAxis.scale().domain()[1])); + cursorGroup.append("line") + .attr("class", "y") + .attr("x1", xScale(xAxis.scale().domain()[0]) - 10) + .attr("x2", xScale(xAxis.scale().domain()[1])) + .attr("y1", 0) + .attr("y2", 0) + cursorGroup.append("text") + .attr("class", "label x") + .attr("x", 0) + .attr("y", yScale(yAxis.scale().domain()[0]) + 15) + .attr("baseline-shift", "-100%") + .attr("text-anchor", "middle"); + cursorGroup.append("text") + .attr("class", "label y") + .attr("x", xScale(xAxis.scale().domain()[0]) - 15) + .attr("y", 0) + .attr("baseline-shift", "-30%") + .attr("text-anchor", "end"); + // Area to handle mouse events + var area = svg.append("rect") + .attr("fill", "transparent") + .attr("x", 0) + .attr("y", 0) + .attr("width", size.width) + .attr("height", size.height); + + area.on("mouseover", function() { + document.querySelector("#complexity-graph .cursor").classList.remove("hidden"); + }).on("mouseout", function() { + document.querySelector("#complexity-graph .cursor").classList.add("hidden"); + }).on("mousemove", function() { + var location = d3.mouse(this); + var location_domain = [xScale.invert(location[0]), yScale.invert(location[1])]; + cursorGroup.select("line.x") + .attr("x1", location[0]) + .attr("x2", location[0]); + cursorGroup.select("text.x") + .attr("x", location[0]) + .text(location_domain[0].toFixed(1)); + cursorGroup.select("line.y") + .attr("y1", location[1]) + .attr("y2", location[1]); + cursorGroup.select("text.y") + .attr("y", location[1]) + .text((1000 / location_domain[1]).toFixed(1)); + }); + }, + + createTimeGraph: function(result, samples, marks, regressions, options, margins, size) + { + var svg = d3.select("#test-graph-data").append("svg") + .attr("id", "time-graph") + .attr("width", size.width + margins.left + margins.right) + .attr("height", size.height + margins.top + margins.bottom) + .append("g") + .attr("transform", "translate(" + margins.left + "," + margins.top + ")"); + + // Axis scales + var x = d3.scale.linear() + .range([0, size.width]) + .domain([ + Math.min(d3.min(samples, function(s) { return s.time; }), 0), + d3.max(samples, function(s) { return s.time; })]); + var complexityMax = d3.max(samples, function(s) { + if (s.time > 0) + return s.complexity; + return 0; + }); + + var yLeft = d3.scale.linear() + .range([size.height, 0]) + .domain([0, complexityMax]); + var yRight = d3.scale.linear() + .range([size.height, 0]) + .domain([1000/20, 1000/60]); + + // Axes + var xAxis = d3.svg.axis() + .scale(x) + .orient("bottom") + .tickFormat(function(d) { return (d/1000).toFixed(0); }); + var yAxisLeft = d3.svg.axis() + .scale(yLeft) + .orient("left"); + var yAxisRight = d3.svg.axis() + .scale(yRight) + .tickValues([1000/20, 1000/25, 1000/30, 1000/35, 1000/40, 1000/45, 1000/50, 1000/55, 1000/60]) + .tickFormat(function(d) { return (1000/d).toFixed(0); }) + .orient("right"); + + // x-axis + svg.append("g") + .attr("class", "x axis") + .attr("fill", "rgb(235, 235, 235)") + .attr("transform", "translate(0," + size.height + ")") + .call(xAxis) + .append("text") + .attr("class", "label") + .attr("x", size.width) + .attr("y", -6) + .attr("fill", "rgb(235, 235, 235)") + .style("text-anchor", "end") + .text("time"); + + // yLeft-axis + svg.append("g") + .attr("class", "yLeft axis") + .attr("fill", "#7ADD49") + .call(yAxisLeft) + .append("text") + .attr("class", "label") + .attr("transform", "rotate(-90)") + .attr("y", 6) + .attr("fill", "#7ADD49") + .attr("dy", ".71em") + .style("text-anchor", "end") + .text(Strings.text.complexity); + + // yRight-axis + svg.append("g") + .attr("class", "yRight axis") + .attr("fill", "#FA4925") + .attr("transform", "translate(" + size.width + ", 0)") + .call(yAxisRight) + .append("text") + .attr("class", "label") + .attr("x", 9) + .attr("y", -20) + .attr("fill", "#FA4925") + .attr("dy", ".71em") + .style("text-anchor", "start") + .text(Strings.text.frameRate); + + // marks + var yMin = yRight(yAxisRight.scale().domain()[0]); + var yMax = yRight(yAxisRight.scale().domain()[1]); + for (var markName in marks) { + var mark = marks[markName]; + var xLocation = x(mark.time); + + var markerGroup = svg.append("g") + .attr("class", "marker") + .attr("transform", "translate(" + xLocation + ", 0)"); + markerGroup.append("text") + .attr("transform", "translate(10, " + (yMin - 10) + ") rotate(-90)") + .style("text-anchor", "start") + .text(markName) + markerGroup.append("line") + .attr("x1", 0) + .attr("x2", 0) + .attr("y1", yMin) + .attr("y2", yMax); + } + + if (Strings.json.controller in result) { + var complexity = result[Strings.json.controller]; + var regression = svg.append("g") + .attr("class", "complexity mean"); + this._addRegressionLine(regression, x, yLeft, [[samples[0].time, complexity.average], [samples[samples.length - 1].time, complexity.average]], complexity.stdev); + } + if (Strings.json.frameLength in result) { + var frameLength = result[Strings.json.frameLength]; + var regression = svg.append("g") + .attr("class", "fps mean"); + this._addRegressionLine(regression, x, yRight, [[samples[0].time, 1000/frameLength.average], [samples[samples.length - 1].time, 1000/frameLength.average]], frameLength.stdev); + } + + // right-target + if (options["controller"] == "adaptive") { + var targetFrameLength = 1000 / options["frame-rate"]; + svg.append("line") + .attr("x1", x(0)) + .attr("x2", size.width) + .attr("y1", yRight(targetFrameLength)) + .attr("y2", yRight(targetFrameLength)) + .attr("class", "target-fps marker"); + } + + // Cursor + var cursorGroup = svg.append("g").attr("class", "cursor"); + cursorGroup.append("line") + .attr("x1", 0) + .attr("x2", 0) + .attr("y1", yMin) + .attr("y2", yMin); + + // Data + var allData = samples; + var filteredData = samples.filter(function (sample) { + return "smoothedFrameLength" in sample; + }); + + function addData(name, data, yCoordinateCallback, pointRadius, omitLine) { + var svgGroup = svg.append("g").attr("id", name); + if (!omitLine) { + svgGroup.append("path") + .datum(data) + .attr("d", d3.svg.line() + .x(function(d) { return x(d.time); }) + .y(yCoordinateCallback)); + } + svgGroup.selectAll("circle") + .data(data) + .enter() + .append("circle") + .attr("cx", function(d) { return x(d.time); }) + .attr("cy", yCoordinateCallback) + .attr("r", pointRadius); + + cursorGroup.append("circle") + .attr("class", name) + .attr("r", pointRadius + 2); + } + + addData("complexity", allData, function(d) { return yLeft(d.complexity); }, 2); + addData("rawFPS", allData, function(d) { return yRight(d.frameLength); }, 1); + addData("filteredFPS", filteredData, function(d) { return yRight(d.smoothedFrameLength); }, 2); + + // regressions + var regressionGroup = svg.append("g") + .attr("id", "regressions"); + if (regressions) { + var complexities = []; + regressions.forEach(function (regression) { + if (!isNaN(regression.segment1[0][1]) && !isNaN(regression.segment1[1][1])) { + regressionGroup.append("line") + .attr("x1", x(regression.segment1[0][0])) + .attr("x2", x(regression.segment1[1][0])) + .attr("y1", yRight(regression.segment1[0][1])) + .attr("y2", yRight(regression.segment1[1][1])); + } + if (!isNaN(regression.segment2[0][1]) && !isNaN(regression.segment2[1][1])) { + regressionGroup.append("line") + .attr("x1", x(regression.segment2[0][0])) + .attr("x2", x(regression.segment2[1][0])) + .attr("y1", yRight(regression.segment2[0][1])) + .attr("y2", yRight(regression.segment2[1][1])); + } + // inflection point + regressionGroup.append("circle") + .attr("cx", x(regression.segment1[1][0])) + .attr("cy", yLeft(regression.complexity)) + .attr("r", 5); + complexities.push(regression.complexity); + }); + if (complexities.length) { + var yLeftComplexities = d3.svg.axis() + .scale(yLeft) + .tickValues(complexities) + .tickSize(10) + .orient("left"); + svg.append("g") + .attr("class", "complexity yLeft axis") + .call(yLeftComplexities); + } + } + + // Area to handle mouse events + var area = svg.append("rect") + .attr("fill", "transparent") + .attr("x", 0) + .attr("y", 0) + .attr("width", size.width) + .attr("height", size.height); + + var timeBisect = d3.bisector(function(d) { return d.time; }).right; + var statsToHighlight = ["complexity", "rawFPS", "filteredFPS"]; + area.on("mouseover", function() { + document.querySelector("#time-graph .cursor").classList.remove("hidden"); + document.querySelector("#test-graph nav").classList.remove("hide-data"); + }).on("mouseout", function() { + document.querySelector("#time-graph .cursor").classList.add("hidden"); + document.querySelector("#test-graph nav").classList.add("hide-data"); + }).on("mousemove", function() { + var form = document.forms["time-graph-options"].elements; + + var mx_domain = x.invert(d3.mouse(this)[0]); + var index = Math.min(timeBisect(allData, mx_domain), allData.length - 1); + var data = allData[index]; + var cursor_x = x(data.time); + var cursor_y = yAxisRight.scale().domain()[1]; + var ys = [yRight(yAxisRight.scale().domain()[0]), yRight(yAxisRight.scale().domain()[1])]; + + document.querySelector("#test-graph nav .time").textContent = (data.time / 1000).toFixed(4) + "s (" + index + ")"; + statsToHighlight.forEach(function(name) { + var element = document.querySelector("#test-graph nav ." + name); + var content = ""; + var data_y = null; + switch (name) { + case "complexity": + content = data.complexity; + data_y = yLeft(data.complexity); + break; + case "rawFPS": + content = (1000/data.frameLength).toFixed(2); + data_y = yRight(data.frameLength); + break; + case "filteredFPS": + if ("smoothedFrameLength" in data) { + content = (1000/data.smoothedFrameLength).toFixed(2); + data_y = yRight(data.smoothedFrameLength); + } + break; + } + + element.textContent = content; + + if (form[name].checked && data_y !== null) { + ys.push(data_y); + cursorGroup.select("." + name) + .attr("cx", cursor_x) + .attr("cy", data_y); + document.querySelector("#time-graph .cursor ." + name).classList.remove("hidden"); + } else + document.querySelector("#time-graph .cursor ." + name).classList.add("hidden"); + }); + + if (form["rawFPS"].checked) + cursor_y = Math.max(cursor_y, data.frameLength); + cursorGroup.select("line") + .attr("x1", cursor_x) + .attr("x2", cursor_x) + .attr("y1", Math.min.apply(null, ys)) + .attr("y2", Math.max.apply(null, ys)); + + }); + }, + + _showOrHideNodes: function(isShown, selector) { + var nodeList = document.querySelectorAll(selector); + if (isShown) { + for (var i = 0; i < nodeList.length; ++i) + nodeList[i].classList.remove("hidden"); + } else { + for (var i = 0; i < nodeList.length; ++i) + nodeList[i].classList.add("hidden"); + } + }, + + onComplexityGraphOptionsChanged: function() { + var form = document.forms["complexity-graph-options"].elements; + benchmarkController._showOrHideNodes(form["series-raw"].checked, "#complexity-graph .series.raw"); + benchmarkController._showOrHideNodes(form["series-average"].checked, "#complexity-graph .series.average"); + benchmarkController._showOrHideNodes(form["regression-time-score"].checked, "#complexity-graph .mean.complexity"); + benchmarkController._showOrHideNodes(form["bootstrap-score"].checked, "#complexity-graph .bootstrap"); + benchmarkController._showOrHideNodes(form["complexity-regression-aggregate-raw"].checked, "#complexity-graph .regression.raw"); + benchmarkController._showOrHideNodes(form["complexity-regression-aggregate-average"].checked, "#complexity-graph .regression.average"); + }, + + onTimeGraphOptionsChanged: function() { + var form = document.forms["time-graph-options"].elements; + benchmarkController._showOrHideNodes(form["markers"].checked, ".marker"); + benchmarkController._showOrHideNodes(form["averages"].checked, "#test-graph-data .mean"); + benchmarkController._showOrHideNodes(form["complexity"].checked, "#complexity"); + benchmarkController._showOrHideNodes(form["rawFPS"].checked, "#rawFPS"); + benchmarkController._showOrHideNodes(form["filteredFPS"].checked, "#filteredFPS"); + benchmarkController._showOrHideNodes(form["regressions"].checked, "#regressions"); + }, + + onGraphTypeChanged: function() { + var form = document.forms["graph-type"].elements; + var testResult = document.getElementById("test-graph-data")._testResult; + var isTimeSelected = form["graph-type"].value == "time"; + + benchmarkController._showOrHideNodes(isTimeSelected, "#time-graph"); + benchmarkController._showOrHideNodes(isTimeSelected, "form[name=time-graph-options]"); + benchmarkController._showOrHideNodes(!isTimeSelected, "#complexity-graph"); + benchmarkController._showOrHideNodes(!isTimeSelected, "form[name=complexity-graph-options]"); + + var score = "", mean = ""; + if (isTimeSelected) { + score = testResult[Strings.json.score].toFixed(2); + + var regression = testResult[Strings.json.controller]; + mean = [ + "mean: ", + regression.average.toFixed(2), + " ± ", + regression.stdev.toFixed(2), + " (", + regression.percent.toFixed(2), + "%)"]; + if (regression.concern) { + mean = mean.concat([ + ", worst 5%: ", + regression.concern.toFixed(2)]); + } + mean = mean.join(""); + } else { + var complexityRegression = testResult[Strings.json.complexity]; + var complexityAverageRegression = testResult[Strings.json.complexityAverage]; + + document.getElementById("complexity-regression-aggregate-raw").textContent = complexityRegression.complexity.toFixed(2) + ", ±" + complexityRegression.stdev.toFixed(2) + "ms"; + document.getElementById("complexity-regression-aggregate-average").textContent = complexityAverageRegression.complexity.toFixed(2) + ", ±" + complexityAverageRegression.stdev.toFixed(2) + "ms"; + + var bootstrap = complexityRegression[Strings.json.bootstrap]; + if (bootstrap) { + score = bootstrap.median.toFixed(2); + mean = [ + (bootstrap.confidencePercentage * 100).toFixed(0), + "% CI: ", + bootstrap.confidenceLow.toFixed(2), + "–", + bootstrap.confidenceHigh.toFixed(2) + ].join(""); + } + } + + sectionsManager.setSectionScore("test-graph", score, mean); + } +}); diff --git a/third_party/webkit/PerformanceTests/MotionMark/resources/debug-runner/tests.js b/third_party/webkit/PerformanceTests/MotionMark/resources/debug-runner/tests.js new file mode 100644 index 0000000000..accaa3c3df --- /dev/null +++ b/third_party/webkit/PerformanceTests/MotionMark/resources/debug-runner/tests.js @@ -0,0 +1,345 @@ +Utilities.extendObject(Strings.text, { + samples: "Samples", + complexity: "Time Complexity", + frameRate: "FPS", + confidenceInterval: "80% Confidence Interval", + mergedRawComplexity: "Raw Complexity", + graph: "Graph" +}); + + +Utilities.extendObject(Headers, { + details: [ + { + title: Strings.text.graph + }, + { + title: Strings.text.confidenceInterval, + children: + [ + { + text: function(data) { + return data[Strings.json.complexity][Strings.json.bootstrap].confidenceLow.toFixed(2); + }, + className: "right pad-left pad-right" + }, + { + text: function(data) { + return " - " + data[Strings.json.complexity][Strings.json.bootstrap].confidenceHigh.toFixed(2); + }, + className: "left" + }, + { + text: function(data) { + var bootstrap = data[Strings.json.complexity][Strings.json.bootstrap]; + return (100 * (bootstrap.confidenceLow / bootstrap.median - 1)).toFixed(2) + "%"; + }, + className: "left pad-left small" + }, + { + text: function(data) { + var bootstrap = data[Strings.json.complexity][Strings.json.bootstrap]; + return "+" + (100 * (bootstrap.confidenceHigh / bootstrap.median - 1)).toFixed(2) + "%"; + }, + className: "left pad-left small" + } + ] + }, + { + title: Strings.text.complexity, + children: + [ + { + text: function(data) { + return data[Strings.json.controller][Strings.json.measurements.average].toFixed(2); + }, + className: "average" + }, + { + text: function(data) { + return [ + "± ", + data[Strings.json.controller][Strings.json.measurements.percent].toFixed(2), + "%" + ].join(""); + }, + className: function(data) { + var className = "stdev"; + + if (data[Strings.json.controller][Strings.json.measurements.percent] >= 10) + className += " noisy-results"; + return className; + } + } + ] + }, + { + title: Strings.text.frameRate, + children: + [ + { + text: function(data) { + return data[Strings.json.frameLength][Strings.json.measurements.average].toFixed(2); + }, + className: function(data, options) { + var className = "average"; + if (Math.abs(data[Strings.json.frameLength][Strings.json.measurements.average] - options["frame-rate"]) >= 2) + className += " noisy-results"; + return className; + } + }, + { + text: function(data) { + var frameRateData = data[Strings.json.frameLength]; + return [ + "± ", + frameRateData[Strings.json.measurements.percent].toFixed(2), + "%" + ].join(""); + }, + className: function(data) { + var className = "stdev"; + + if (data[Strings.json.frameLength][Strings.json.measurements.percent] >= 10) + className += " noisy-results"; + return className; + } + } + ] + }, + { + title: Strings.text.mergedRawComplexity, + children: + [ + { + text: function(data) { + return data[Strings.json.complexity][Strings.json.complexity].toFixed(2); + }, + className: "average" + }, + { + text: function(data) { + return [ + "± ", + data[Strings.json.complexity][Strings.json.measurements.stdev].toFixed(2), + "ms" + ].join(""); + }, + className: "stdev" + } + ] + } + ] +}) + +/////////// +// Suites + +Suites.push(new Suite("HTML suite", + [ + { + url: "bouncing-particles/bouncing-css-shapes.html?particleWidth=12&particleHeight=12&shape=circle", + name: "CSS bouncing circles" + }, + { + url: "bouncing-particles/bouncing-css-shapes.html?particleWidth=40&particleHeight=40&shape=rect&clip=star", + name: "CSS bouncing clipped rects" + }, + { + url: "bouncing-particles/bouncing-css-shapes.html?particleWidth=50&particleHeight=50&shape=circle&fill=gradient", + name: "CSS bouncing gradient circles" + }, + { + url: "bouncing-particles/bouncing-css-shapes.html?particleWidth=80&particleHeight=80&shape=circle&blend", + name: "CSS bouncing blend circles" + }, + { + url: "bouncing-particles/bouncing-css-shapes.html?particleWidth=80&particleHeight=80&shape=circle&filter", + name: "CSS bouncing filter circles" + }, + { + url: "bouncing-particles/bouncing-css-images.html?particleWidth=80&particleHeight=80&imageSrc=../resources/yin-yang.svg", + name: "CSS bouncing SVG images" + }, + { + url: "bouncing-particles/bouncing-tagged-images.html?particleWidth=100&particleHeight=100", + name: "CSS bouncing tagged images" + }, + { + url: "dom/leaves.html", + name: "Leaves 2.0" + }, + { + url: "dom/focus.html", + name: "Focus 2.0" + }, + { + url: "dom/particles.html", + name: "DOM particles, SVG masks" + }, + { + url: "dom/compositing-transforms.html?particleWidth=50&particleHeight=50&filters=yes&imageSrc=../resources/yin-yang.svg", + name: "Composited Transforms" + } + ] +)); + +Suites.push(new Suite("Canvas suite", + [ + { + url: "bouncing-particles/bouncing-canvas-shapes.html?particleWidth=40&particleHeight=40&shape=rect&clip=star", + name: "canvas bouncing clipped rects" + }, + { + url: "bouncing-particles/bouncing-canvas-shapes.html?particleWidth=50&particleHeight=50&shape=circle&fill=gradient", + name: "canvas bouncing gradient circles" + }, + { + url: "bouncing-particles/bouncing-canvas-images.html?particleWidth=80&particleHeight=80&imageSrc=../resources/yin-yang.svg", + name: "canvas bouncing SVG images" + }, + { + url: "bouncing-particles/bouncing-canvas-images.html?particleWidth=80&particleHeight=80&imageSrc=../resources/yin-yang.png", + name: "canvas bouncing PNG images" + }, + { + url: "simple/simple-canvas-paths.html?pathType=strokes", + name: "Stroke shapes" + }, + { + url: "simple/simple-canvas-paths.html?pathType=fills", + name: "Fill shapes" + }, + { + url: "simple/tiled-canvas-image.html", + name: "Canvas put/get image data" + }, + ] +)); + +Suites.push(new Suite("SVG suite", + [ + { + url: "bouncing-particles/bouncing-svg-shapes.html?particleWidth=12&particleHeight=12&shape=circle", + name: "SVG bouncing circles", + }, + { + url: "bouncing-particles/bouncing-svg-shapes.html?particleWidth=40&particleHeight=40&shape=rect&clip=star", + name: "SVG bouncing clipped rects", + }, + { + url: "bouncing-particles/bouncing-svg-shapes.html?particleWidth=50&particleHeight=50&shape=circle&fill=gradient", + name: "SVG bouncing gradient circles" + }, + { + url: "bouncing-particles/bouncing-svg-images.html?particleWidth=80&particleHeight=80&imageSrc=../resources/yin-yang.svg", + name: "SVG bouncing SVG images" + }, + { + url: "bouncing-particles/bouncing-svg-images.html?particleWidth=80&particleHeight=80&imageSrc=../resources/yin-yang.png", + name: "SVG bouncing PNG images" + }, + ] +)); + +Suites.push(new Suite("3D Graphics", + [ + { + url: "3d/webgl.html", + name: "WebGL" + }, + ] +)); + +Suites.push(new Suite("Basic canvas path suite", + [ + { + url: "simple/simple-canvas-paths.html?pathType=line&lineCap=butt", + name: "Canvas line segments, butt caps" + }, + { + url: "simple/simple-canvas-paths.html?pathType=line&lineCap=round", + name: "Canvas line segments, round caps" + }, + { + url: "simple/simple-canvas-paths.html?pathType=line&lineCap=square", + name: "Canvas line segments, square caps" + }, + { + url: "simple/simple-canvas-paths.html?pathType=linePath&lineJoin=bevel", + name: "Canvas line path, bevel join" + }, + { + url: "simple/simple-canvas-paths.html?pathType=linePath&lineJoin=round", + name: "Canvas line path, round join" + }, + { + url: "simple/simple-canvas-paths.html?pathType=linePath&lineJoin=miter", + name: "Canvas line path, miter join" + }, + { + url: "simple/simple-canvas-paths.html?pathType=linePath&lineDash=1", + name: "Canvas line path with dash pattern" + }, + { + url: "simple/simple-canvas-paths.html?pathType=quadratic", + name: "Canvas quadratic segments" + }, + { + url: "simple/simple-canvas-paths.html?pathType=quadraticPath", + name: "Canvas quadratic path" + }, + { + url: "simple/simple-canvas-paths.html?pathType=bezier", + name: "Canvas bezier segments" + }, + { + url: "simple/simple-canvas-paths.html?pathType=bezierPath", + name: "Canvas bezier path" + }, + { + url: "simple/simple-canvas-paths.html?&pathType=arcTo", + name: "Canvas arcTo segments" + }, + { + url: "simple/simple-canvas-paths.html?pathType=arc", + name: "Canvas arc segments" + }, + { + url: "simple/simple-canvas-paths.html?pathType=rect", + name: "Canvas rects" + }, + { + url: "simple/simple-canvas-paths.html?pathType=ellipse", + name: "Canvas ellipses" + }, + { + url: "simple/simple-canvas-paths.html?pathType=lineFill", + name: "Canvas line path, fill" + }, + { + url: "simple/simple-canvas-paths.html?pathType=quadraticFill", + name: "Canvas quadratic path, fill" + }, + { + url: "simple/simple-canvas-paths.html?pathType=bezierFill", + name: "Canvas bezier path, fill" + }, + { + url: "simple/simple-canvas-paths.html?&pathType=arcToFill", + name: "Canvas arcTo segments, fill" + }, + { + url: "simple/simple-canvas-paths.html?pathType=arcFill", + name: "Canvas arc segments, fill" + }, + { + url: "simple/simple-canvas-paths.html?pathType=rectFill", + name: "Canvas rects, fill" + }, + { + url: "simple/simple-canvas-paths.html?pathType=ellipseFill", + name: "Canvas ellipses, fill" + } + ] +)); diff --git a/third_party/webkit/PerformanceTests/MotionMark/resources/extensions.js b/third_party/webkit/PerformanceTests/MotionMark/resources/extensions.js new file mode 100644 index 0000000000..fb9d500877 --- /dev/null +++ b/third_party/webkit/PerformanceTests/MotionMark/resources/extensions.js @@ -0,0 +1,670 @@ +Utilities = +{ + _parse: function(str, sep) + { + var output = {}; + str.split(sep).forEach(function(part) { + var item = part.split("="); + var value = decodeURIComponent(item[1]); + if (value[0] == "'" ) + output[item[0]] = value.substr(1, value.length - 2); + else + output[item[0]] = value; + }); + return output; + }, + + parseParameters: function() + { + return this._parse(window.location.search.substr(1), "&"); + }, + + parseArguments: function(str) + { + return this._parse(str, " "); + }, + + extendObject: function(obj1, obj2) + { + for (var attrname in obj2) + obj1[attrname] = obj2[attrname]; + return obj1; + }, + + copyObject: function(obj) + { + return this.extendObject({}, obj); + }, + + mergeObjects: function(obj1, obj2) + { + return this.extendObject(this.copyObject(obj1), obj2); + }, + + createClass: function(classConstructor, classMethods) + { + classConstructor.prototype = classMethods; + return classConstructor; + }, + + createSubclass: function(superclass, classConstructor, classMethods) + { + classConstructor.prototype = Object.create(superclass.prototype); + classConstructor.prototype.constructor = classConstructor; + if (classMethods) + Utilities.extendObject(classConstructor.prototype, classMethods); + return classConstructor; + }, + + createElement: function(name, attrs, parentElement) + { + var element = document.createElement(name); + + for (var key in attrs) + element.setAttribute(key, attrs[key]); + + parentElement.appendChild(element); + return element; + }, + + createSVGElement: function(name, attrs, xlinkAttrs, parentElement) + { + const svgNamespace = "http://www.w3.org/2000/svg"; + const xlinkNamespace = "http://www.w3.org/1999/xlink"; + + var element = document.createElementNS(svgNamespace, name); + + for (var key in attrs) + element.setAttribute(key, attrs[key]); + + for (var key in xlinkAttrs) + element.setAttributeNS(xlinkNamespace, key, xlinkAttrs[key]); + + parentElement.appendChild(element); + return element; + }, + + browserPrefix: function() + { + // Get the HTML element's CSSStyleDeclaration + var styles = window.getComputedStyle(document.documentElement, ''); + + // Convert the styles list to an array + var stylesArray = Array.prototype.slice.call(styles); + + // Concatenate all the styles in one big string + var stylesString = stylesArray.join(''); + + // Search the styles string for a known prefix type, settle on Opera if none is found. + var prefixes = stylesString.match(/-(moz|webkit|ms)-/) || (styles.OLink === '' && ['', 'o']); + + // prefixes has two elements; e.g. for webkit it has ['-webkit-', 'webkit']; + var prefix = prefixes[1]; + + // Have 'O' before 'Moz' in the string so it is matched first. + var dom = ('WebKit|O|Moz|MS').match(new RegExp(prefix, 'i'))[0]; + + // Return all the required prefixes. + return { + dom: dom, + lowercase: prefix, + css: '-' + prefix + '-', + js: prefix[0].toUpperCase() + prefix.substr(1) + }; + }, + + setElementPrefixedProperty: function(element, property, value) + { + element.style[property] = element.style[this.browserPrefix().js + property[0].toUpperCase() + property.substr(1)] = value; + }, + + stripNonASCIICharacters: function(inputString) + { + return inputString.replace(/[ .,]/g, ''); + }, + + convertObjectToQueryString: function(object) + { + var queryString = []; + for (var property in object) { + if (object.hasOwnProperty(property)) + queryString.push(encodeURIComponent(property) + "=" + encodeURIComponent(object[property])); + } + return "?" + queryString.join("&"); + }, + + convertQueryStringToObject: function(queryString) + { + queryString = queryString.substring(1); + if (!queryString) + return null; + + var object = {}; + queryString.split("&").forEach(function(parameter) { + var components = parameter.split("="); + object[components[0]] = components[1]; + }); + return object; + }, + + progressValue: function(value, min, max) + { + return (value - min) / (max - min); + }, + + lerp: function(value, min, max) + { + return min + (max - min) * value; + }, + + toFixedNumber: function(number, precision) + { + if (number.toFixed) + return Number(number.toFixed(precision)); + return number; + } +}; + +Array.prototype.swap = function(i, j) +{ + var t = this[i]; + this[i] = this[j]; + this[j] = t; + return this; +} + +if (!Array.prototype.fill) { + Array.prototype.fill = function(value) { + if (this == null) + throw new TypeError('Array.prototype.fill called on null or undefined'); + + var object = Object(this); + var len = parseInt(object.length, 10); + var start = arguments[1]; + var relativeStart = parseInt(start, 10) || 0; + var k = relativeStart < 0 ? Math.max(len + relativeStart, 0) : Math.min(relativeStart, len); + var end = arguments[2]; + var relativeEnd = end === undefined ? len : (parseInt(end) || 0) ; + var final = relativeEnd < 0 ? Math.max(len + relativeEnd, 0) : Math.min(relativeEnd, len); + + for (; k < final; k++) + object[k] = value; + + return object; + }; +} + +if (!Array.prototype.find) { + Array.prototype.find = function(predicate) { + if (this == null) + throw new TypeError('Array.prototype.find called on null or undefined'); + if (typeof predicate !== 'function') + throw new TypeError('predicate must be a function'); + + var list = Object(this); + var length = list.length >>> 0; + var thisArg = arguments[1]; + var value; + + for (var i = 0; i < length; i++) { + value = list[i]; + if (predicate.call(thisArg, value, i, list)) + return value; + } + return undefined; + }; +} + +Array.prototype.shuffle = function() +{ + for (var index = this.length - 1; index >= 0; --index) { + var randomIndex = Math.floor(Math.random() * (index + 1)); + this.swap(index, randomIndex); + } + return this; +} + +Point = Utilities.createClass( + function(x, y) + { + this.x = x; + this.y = y; + }, { + + // Used when the point object is used as a size object. + get width() + { + return this.x; + }, + + // Used when the point object is used as a size object. + get height() + { + return this.y; + }, + + // Used when the point object is used as a size object. + get center() + { + return new Point(this.x / 2, this.y / 2); + }, + + str: function() + { + return "x = " + this.x + ", y = " + this.y; + }, + + add: function(other) + { + if(isNaN(other.x)) + return new Point(this.x + other, this.y + other); + return new Point(this.x + other.x, this.y + other.y); + }, + + subtract: function(other) + { + if(isNaN(other.x)) + return new Point(this.x - other, this.y - other); + return new Point(this.x - other.x, this.y - other.y); + }, + + multiply: function(other) + { + if(isNaN(other.x)) + return new Point(this.x * other, this.y * other); + return new Point(this.x * other.x, this.y * other.y); + }, + + move: function(angle, velocity, timeDelta) + { + return this.add(Point.pointOnCircle(angle, velocity * (timeDelta / 1000))); + }, + + length: function() { + return Math.sqrt( this.x * this.x + this.y * this.y ); + }, + + normalize: function() { + var l = Math.sqrt( this.x * this.x + this.y * this.y ); + this.x /= l; + this.y /= l; + return this; + } +}); + +Utilities.extendObject(Point, { + zero: new Point(0, 0), + + pointOnCircle: function(angle, radius) + { + return new Point(radius * Math.cos(angle), radius * Math.sin(angle)); + }, + + pointOnEllipse: function(angle, radiuses) + { + return new Point(radiuses.x * Math.cos(angle), radiuses.y * Math.sin(angle)); + }, + + elementClientSize: function(element) + { + var rect = element.getBoundingClientRect(); + return new Point(rect.width, rect.height); + } +}); + +Insets = Utilities.createClass( + function(top, right, bottom, left) + { + this.top = top; + this.right = right; + this.bottom = bottom; + this.left = left; + }, { + + get width() + { + return this.left + this.right; + }, + + get height() + { + return this.top + this.bottom; + }, + + get size() + { + return new Point(this.width, this.height); + } +}); + +Insets.elementPadding = function(element) +{ + var styles = window.getComputedStyle(element); + return new Insets( + parseFloat(styles.paddingTop), + parseFloat(styles.paddingRight), + parseFloat(styles.paddingBottom), + parseFloat(styles.paddingTop)); +} + +UnitBezier = Utilities.createClass( + function(point1, point2) + { + // First and last points in the Bézier curve are assumed to be (0,0) and (!,1) + this._c = point1.multiply(3); + this._b = point2.subtract(point1).multiply(3).subtract(this._c); + this._a = new Point(1, 1).subtract(this._c).subtract(this._b); + }, { + + epsilon: 1e-5, + derivativeEpsilon: 1e-6, + + solve: function(x) + { + return this.sampleY(this.solveForT(x)); + }, + + sampleX: function(t) + { + return ((this._a.x * t + this._b.x) * t + this._c.x) * t; + }, + + sampleY: function(t) + { + return ((this._a.y * t + this._b.y) * t + this._c.y) * t; + }, + + sampleDerivativeX: function(t) + { + return(3 * this._a.x * t + 2 * this._b.x) * t + this._c.x; + }, + + solveForT: function(x) + { + var t0, t1, t2, x2, d2, i; + + for (t2 = x, i = 0; i < 8; ++i) { + x2 = this.sampleX(t2) - x; + if (Math.abs(x2) < this.epsilon) + return t2; + d2 = this.sampleDerivativeX(t2); + if (Math.abs(d2) < this.derivativeEpsilon) + break; + t2 = t2 - x2 / d2; + } + + t0 = 0; + t1 = 1; + t2 = x; + + if (t2 < t0) + return t0; + if (t2 > t1) + return t1; + + while (t0 < t1) { + x2 = this.sampleX(t2); + if (Math.abs(x2 - x) < this.epsilon) + return t2; + if (x > x2) + t0 = t2; + else + t1 = t2; + t2 = (t1 - t0) * .5 + t0; + } + + return t2; + } +}); + +SimplePromise = Utilities.createClass( + function() + { + this._chainedPromise = null; + this._callback = null; + }, { + + then: function (callback) + { + if (this._callback) + throw "SimplePromise doesn't support multiple calls to then"; + + this._callback = callback; + this._chainedPromise = new SimplePromise; + + if (this._resolved) + this.resolve(this._resolvedValue); + + return this._chainedPromise; + }, + + resolve: function (value) + { + if (!this._callback) { + this._resolved = true; + this._resolvedValue = value; + return; + } + + var result = this._callback(value); + if (result instanceof SimplePromise) { + var chainedPromise = this._chainedPromise; + result.then(function (result) { chainedPromise.resolve(result); }); + } else + this._chainedPromise.resolve(result); + } +}); + +var Heap = Utilities.createClass( + function(maxSize, compare) + { + this._maxSize = maxSize; + this._compare = compare; + this._size = 0; + this._values = new Array(this._maxSize); + }, { + + // This is a binary heap represented in an array. The root element is stored + // in the first element in the array. The root is followed by its two children. + // Then its four grandchildren and so on. So every level in the binary heap is + // doubled in the following level. Here is an example of the node indices and + // how they are related to their parents and children. + // =========================================================================== + // 0 1 2 3 4 5 6 + // PARENT -1 0 0 1 1 2 2 + // LEFT 1 3 5 7 9 11 13 + // RIGHT 2 4 6 8 10 12 14 + // =========================================================================== + _parentIndex: function(i) + { + return i > 0 ? Math.floor((i - 1) / 2) : -1; + }, + + _leftIndex: function(i) + { + var leftIndex = i * 2 + 1; + return leftIndex < this._size ? leftIndex : -1; + }, + + _rightIndex: function(i) + { + var rightIndex = i * 2 + 2; + return rightIndex < this._size ? rightIndex : -1; + }, + + // Return the child index that may violate the heap property at index i. + _childIndex: function(i) + { + var left = this._leftIndex(i); + var right = this._rightIndex(i); + + if (left != -1 && right != -1) + return this._compare(this._values[left], this._values[right]) > 0 ? left : right; + + return left != -1 ? left : right; + }, + + init: function() + { + this._size = 0; + }, + + top: function() + { + return this._size ? this._values[0] : NaN; + }, + + push: function(value) + { + if (this._size == this._maxSize) { + // If size is bounded and the new value can be a parent of the top() + // if the size were unbounded, just ignore the new value. + if (this._compare(value, this.top()) > 0) + return; + this.pop(); + } + this._values[this._size++] = value; + this._bubble(this._size - 1); + }, + + pop: function() + { + if (!this._size) + return NaN; + + this._values[0] = this._values[--this._size]; + this._sink(0); + }, + + _bubble: function(i) + { + // Fix the heap property at index i given that parent is the only node that + // may violate the heap property. + for (var pi = this._parentIndex(i); pi != -1; i = pi, pi = this._parentIndex(pi)) { + if (this._compare(this._values[pi], this._values[i]) > 0) + break; + + this._values.swap(pi, i); + } + }, + + _sink: function(i) + { + // Fix the heap property at index i given that each of the left and the right + // sub-trees satisfies the heap property. + for (var ci = this._childIndex(i); ci != -1; i = ci, ci = this._childIndex(ci)) { + if (this._compare(this._values[i], this._values[ci]) > 0) + break; + + this._values.swap(ci, i); + } + }, + + str: function() + { + var out = "Heap[" + this._size + "] = ["; + for (var i = 0; i < this._size; ++i) { + out += this._values[i]; + if (i < this._size - 1) + out += ", "; + } + return out + "]"; + }, + + values: function(size) { + // Return the last "size" heap elements values. + var values = this._values.slice(0, this._size); + return values.sort(this._compare).slice(0, Math.min(size, this._size)); + } +}); + +Utilities.extendObject(Heap, { + createMinHeap: function(maxSize) + { + return new Heap(maxSize, function(a, b) { return b - a; }); + }, + + createMaxHeap: function(maxSize) { + return new Heap(maxSize, function(a, b) { return a - b; }); + } +}); + +var SampleData = Utilities.createClass( + function(fieldMap, data) + { + this.fieldMap = fieldMap || {}; + this.data = data || []; + }, { + + get length() + { + return this.data.length; + }, + + addField: function(name, index) + { + this.fieldMap[name] = index; + }, + + push: function(datum) + { + this.data.push(datum); + }, + + sort: function(sortFunction) + { + this.data.sort(sortFunction); + }, + + slice: function(begin, end) + { + return new SampleData(this.fieldMap, this.data.slice(begin, end)); + }, + + forEach: function(iterationFunction) + { + this.data.forEach(iterationFunction); + }, + + createDatum: function() + { + return []; + }, + + getFieldInDatum: function(datum, fieldName) + { + if (typeof datum === 'number') + datum = this.data[datum]; + return datum[this.fieldMap[fieldName]]; + }, + + setFieldInDatum: function(datum, fieldName, value) + { + if (typeof datum === 'number') + datum = this.data[datum]; + return datum[this.fieldMap[fieldName]] = value; + }, + + at: function(index) + { + return this.data[index]; + }, + + toArray: function() + { + var array = []; + + this.data.forEach(function(datum) { + var newDatum = {}; + array.push(newDatum); + + for (var fieldName in this.fieldMap) { + var value = this.getFieldInDatum(datum, fieldName); + if (value !== null && value !== undefined) + newDatum[fieldName] = value; + } + }, this); + + return array; + } +}); diff --git a/third_party/webkit/PerformanceTests/MotionMark/resources/runner/animometer.css b/third_party/webkit/PerformanceTests/MotionMark/resources/runner/animometer.css new file mode 100644 index 0000000000..86da6bea1c --- /dev/null +++ b/third_party/webkit/PerformanceTests/MotionMark/resources/runner/animometer.css @@ -0,0 +1,520 @@ +/* Outer harness */ + +html, +body { + min-height: 100%; +} + +body { + background-color: hsl(0, 0%, 95%); + + font-family: "Helvetica Neue", Helvetica, Verdana, sans-serif; + font-size: 15px; + + cursor: default; + + -webkit-user-select: none; +} + +body.showing-intro, +body.showing-results { + background-color: hsl(35, 100%, 100%); + background-image: url(crystal.svg), url(lines.svg); + background-size: auto 225%, auto 100%; + background-repeat: no-repeat; + + animation: background-fade 1s ease-in 1s, background-color 60s linear infinite 2s; + animation-play-state: paused; + + will-change: background-color; +} + +body.showing-test-container { + overflow: hidden; +} + +body.images-loaded { + animation-play-state: running; +} + +@media screen and (min-width: 667px) { + body { + font-size: 24px; + } + + body.showing-intro, + body.showing-results { + background-size: 200% 100%, 150% auto; + } +} + +@media screen and (min-width: 1025px) { + body.showing-intro, + body.showing-results { + background-size: 150% 100%, 150% auto; + } +} + +::selection { + background-color: black; + color: white; +} + +.hidden { + display: none; +} + +section { + display: none; +} + +section.selected { + display: block; +} + +svg.logo { + width: 350px; + height: 88px; + + max-width: 100%; + + padding-bottom: 1em; + + color: hsl(35, 100%, 50%); + + animation: foreground-color 60s linear infinite 2s; + animation-play-state: paused; + + will-change: color; +} + +body.images-loaded svg.logo { + animation-play-state: running; +} + +@media screen and (min-width: 667px) { + svg.logo { + width: 525px; + height: 130px; + } +} + +section .body { + margin: 0 1em; + max-width: 350px; +} + +section .body p { + margin: 1em 0; + line-height: 1.5em; + + -webkit-user-select: text; + cursor: text; +} + +@media screen and (min-width: 667px) { + section .body { + margin-left: 2.5em; + max-width: 500px; + transform: skewX(-10deg); + } + + section button { + transform: none; + } +} + +button { + background-color: hsl(35, 100%, 50%); + color: white; + + padding: 0.25em; + margin: 1.5em -0.25em 0 0; + + min-width: 50%; + + border: none; + + font-family: inherit; + font-size: inherit; + + transform: skewX(-10deg); + + transition: 100ms filter ease-in-out; + + animation: background-color 60s linear infinite 2s; + animation-play-state: paused; + + will-change: background-color; +} + +body.images-loaded button { + animation-play-state: running; +} + +button:hover { + filter: brightness(115%); +} + +button:active { + filter: brightness(130%); +} + +button:disabled { + opacity: 0.5; + filter: none !important; +} + +@media print { + button { + display: none; + } +} + +.portrait-orientation-check { + display: none; +} + +@media screen and (max-device-width: 1025px) and (orientation: portrait) { + .portrait-orientation-check { + display: block; + } +} + +@media screen and (max-device-width: 1025px) and (orientation: portrait) { + .landscape-orientation-check { + /* This keeps the button color animation in sync with page, while display: none does not. */ + visibility: hidden; + } +} + +@keyframes background-fade { + 100% { + background-color: hsl(35, 100%, 50%); + } +} + +@keyframes background-color { + 0%, 10% { + background-color: hsl(35, 100%, 50%); + } + + 12%, 20% { + background-color: hsl(75, 100%, 30%); + } + + 22%, 30% { + background-color: hsl(115, 100%, 30%); + } + + 32%, 40% { + background-color: hsl(155, 100%, 30%); + } + + 42%, 50% { + background-color: hsl(195, 100%, 30%); + } + + 52%, 60% { + background-color: hsl(235, 100%, 30%); + } + + 62%, 70% { + background-color: hsl(275, 100%, 30%); + } + + 72%, 80% { + background-color: hsl(315, 100%, 30%); + } + + 82%, 90% { + background-color: hsl(355, 100%, 30%); + } + + 92%, 100% { + background-color: hsl(395, 100%, 50%); + } +} + +@keyframes foreground-color { + 0%, 10% { + color: hsl(35, 100%, 50%); + } + + 12%, 20% { + color: hsl(75, 100%, 30%); + } + + 22%, 30% { + color: hsl(115, 100%, 30%); + } + + 32%, 40% { + color: hsl(155, 100%, 30%); + } + + 42%, 50% { + color: hsl(195, 100%, 30%); + } + + 52%, 60% { + color: hsl(235, 100%, 30%); + } + + 62%, 70% { + color: hsl(275, 100%, 30%); + } + + 72%, 80% { + color: hsl(315, 100%, 30%); + } + + 82%, 90% { + color: hsl(355, 100%, 30%); + } + + 92%, 100% { + color: hsl(395, 100%, 50%); + } +} + +/* Intro section, About page */ + +#intro, #about { + padding: 2em; +} + +#intro { + opacity: 0; + transition: opacity 500ms ease-in; +} + +body.images-loaded #intro { + opacity: 1; +} + +#about .body { + transform: none; + margin: 0; + max-width: initial; +} + +#about li { + line-height: 1.5em; +} + +#about button { + padding: .75em 2em; + margin: 1.5em auto 0; + min-width: initial; + transform: skewX(-10deg); +} + +@media screen and (min-width: 667px) { + #about .body { + font-size: .7em; + margin: 1em; + } + + #about ol, #about ul { + padding-left: 3em; + } +} + + +#intro a, #about a, +#intro a:visited, #about a:visited { + color: black; +} + +/* Running test section */ + +.frame-container { + position: absolute; + + top: 50%; + left: 50%; +} + +.frame-container > iframe { + width: 100%; + height: 100%; + + border: 0; + margin: 0; +} + +body.small .frame-container { + width: 568px; + height: 320px; + margin-left: -284px; + margin-top: -160px; +} + +body.medium .frame-container { + width: 900px; + height: 600px; + margin-left: -450px; + margin-top: -300px; +} + +body.large .frame-container { + width: 1600px; + height: 800px; + margin-left: -800px; + margin-top: -400px; +} + +/* Results section */ + +#results { + padding: 2em; +} + +#results .body { + -webkit-user-select: text; +} + +#results .score-container { + padding-bottom: 2em; +} + +#results .table-container { + position: relative; +} + +#results .table-container > div { + margin-left: 40%; +} + +#results .score { + font-size: 5em; + font-weight: bold; + font-style: italic; + line-height: 1; + margin: 0; +} + +#results .confidence { + font-size: 2em; + font-style: italic; + line-height: 1; + margin: 0; + text-indent: 1.75em; + color: hsl(0, 0%, 40%); + padding-bottom: .3em; +} + +#results table { + border-spacing: 0; + margin: 0; + padding: 0; + min-width: 25%; +} + +#results table td, +#results table th { + padding: 0.25em; +} + +#results table td.suites-separator { + padding: 0; +} + +#results table tr:nth-child(even) { + background-color: hsla(0, 0%, 0%, 0.05); +} + +#results #results-header { + top: 0; + left: 0; + width: 40%; + position: absolute; +} + +#results #results-score { + float: left; +} + +#results #results-data span { + font-size: .75em; + color: hsl(0, 0%, 40%); +} + +#results #results-header td, +#results #results-header th { + text-align: right; + padding-right: 1em !important; + padding-left: 0.5em !important; +} + +#results #results-score td, +#results #results-score th { + text-align: left; + padding-right: 0.5em !important; +} + +#results #results-score td { + cursor: text; +} + +@media screen and (min-width: 667px) { + #results .score, + #results .confidence { + font-style: normal; + } +} + +.detail span { + display: none; +} + +body.small .detail .small, +body.medium .detail .medium, +body.large .detail .large { + display: initial; +} + +#overlay { + position: fixed; + + top: 0; + left: 0; + bottom: 0; + right: 0; + + background: hsla(0, 0%, 100%, 0.9); +} + +@supports (-webkit-backdrop-filter: blur(10px)) { + #overlay { + background: hsla(0, 0%, 100%, 0.7); + -webkit-backdrop-filter: blur(20px); + } +} + +#overlay > div { + position: absolute; + + width: 500px; + height: 500px; + + margin-top: -250px; + margin-left: -250px; + + top: 50%; + left: 50%; +} + +#overlay > div div { + overflow: scroll; + + font-size: 12px; + -webkit-user-select: text; + cursor: text; + + max-height: 250px; + + border: 1px solid hsla(0, 0%, 0%, 0.1); + padding: 1em; +} diff --git a/third_party/webkit/PerformanceTests/MotionMark/resources/runner/animometer.js b/third_party/webkit/PerformanceTests/MotionMark/resources/runner/animometer.js new file mode 100644 index 0000000000..65e8c5450d --- /dev/null +++ b/third_party/webkit/PerformanceTests/MotionMark/resources/runner/animometer.js @@ -0,0 +1,626 @@ +ResultsDashboard = Utilities.createClass( + function(options, testData) + { + this._iterationsSamplers = []; + this._options = options; + this._results = null; + if (testData) { + this._iterationsSamplers = testData; + this._processData(); + } + }, { + + push: function(suitesSamplers) + { + this._iterationsSamplers.push(suitesSamplers); + }, + + _processData: function() + { + this._results = {}; + this._results[Strings.json.results.iterations] = []; + + var iterationsScores = []; + this._iterationsSamplers.forEach(function(iteration, index) { + var testsScores = []; + var testsLowerBoundScores = []; + var testsUpperBoundScores = []; + + var result = {}; + this._results[Strings.json.results.iterations][index] = result; + + var suitesResult = {}; + result[Strings.json.results.tests] = suitesResult; + + for (var suiteName in iteration) { + var suiteData = iteration[suiteName]; + + var suiteResult = {}; + suitesResult[suiteName] = suiteResult; + + for (var testName in suiteData) { + if (!suiteData[testName][Strings.json.result]) + this.calculateScore(suiteData[testName]); + + suiteResult[testName] = suiteData[testName][Strings.json.result]; + delete suiteData[testName][Strings.json.result]; + + testsScores.push(suiteResult[testName][Strings.json.score]); + testsLowerBoundScores.push(suiteResult[testName][Strings.json.scoreLowerBound]); + testsUpperBoundScores.push(suiteResult[testName][Strings.json.scoreUpperBound]); + } + } + + result[Strings.json.score] = Statistics.geometricMean(testsScores); + result[Strings.json.scoreLowerBound] = Statistics.geometricMean(testsLowerBoundScores); + result[Strings.json.scoreUpperBound] = Statistics.geometricMean(testsUpperBoundScores); + iterationsScores.push(result[Strings.json.score]); + }, this); + + this._results[Strings.json.score] = Statistics.sampleMean(iterationsScores.length, iterationsScores.reduce(function(a, b) { return a + b; })); + this._results[Strings.json.scoreLowerBound] = this._results[Strings.json.results.iterations][0][Strings.json.scoreLowerBound]; + this._results[Strings.json.scoreUpperBound] = this._results[Strings.json.results.iterations][0][Strings.json.scoreUpperBound]; + }, + + calculateScore: function(data) + { + var result = {}; + data[Strings.json.result] = result; + var samples = data[Strings.json.samples]; + + var desiredFrameLength = 1000/60; + if (this._options["controller"] == "ramp30") + desiredFrameLength = 1000/30; + + function findRegression(series, profile) { + var minIndex = Math.round(.025 * series.length); + var maxIndex = Math.round(.975 * (series.length - 1)); + var minComplexity = series.getFieldInDatum(minIndex, Strings.json.complexity); + var maxComplexity = series.getFieldInDatum(maxIndex, Strings.json.complexity); + + if (Math.abs(maxComplexity - minComplexity) < 20 && maxIndex - minIndex < 20) { + minIndex = 0; + maxIndex = series.length - 1; + minComplexity = series.getFieldInDatum(minIndex, Strings.json.complexity); + maxComplexity = series.getFieldInDatum(maxIndex, Strings.json.complexity); + } + + var complexityIndex = series.fieldMap[Strings.json.complexity]; + var frameLengthIndex = series.fieldMap[Strings.json.frameLength]; + var regressionOptions = { desiredFrameLength: desiredFrameLength }; + if (profile) + regressionOptions.preferredProfile = profile; + return { + minComplexity: minComplexity, + maxComplexity: maxComplexity, + samples: series.slice(minIndex, maxIndex + 1), + regression: new Regression( + series.data, + function (data, i) { return data[i][complexityIndex]; }, + function (data, i) { return data[i][frameLengthIndex]; }, + minIndex, maxIndex, regressionOptions) + }; + } + + var complexitySamples; + // Convert these samples into SampleData objects if needed + [Strings.json.complexity, Strings.json.complexityAverage, Strings.json.controller].forEach(function(seriesName) { + var series = samples[seriesName]; + if (series && !(series instanceof SampleData)) + samples[seriesName] = new SampleData(series.fieldMap, series.data); + }); + + var isRampController = ["ramp", "ramp30"].indexOf(this._options["controller"]) != -1; + var predominantProfile = ""; + if (isRampController) { + var profiles = {}; + data[Strings.json.controller].forEach(function(regression) { + if (regression[Strings.json.regressions.profile]) { + var profile = regression[Strings.json.regressions.profile]; + profiles[profile] = (profiles[profile] || 0) + 1; + } + }); + + var maxProfileCount = 0; + for (var profile in profiles) { + if (profiles[profile] > maxProfileCount) { + predominantProfile = profile; + maxProfileCount = profiles[profile]; + } + } + } + + [Strings.json.complexity, Strings.json.complexityAverage].forEach(function(seriesName) { + if (!(seriesName in samples)) + return; + + var regression = {}; + result[seriesName] = regression; + var regressionResult = findRegression(samples[seriesName], predominantProfile); + if (seriesName == Strings.json.complexity) + complexitySamples = regressionResult.samples; + var calculation = regressionResult.regression; + regression[Strings.json.regressions.segment1] = [ + [regressionResult.minComplexity, calculation.s1 + calculation.t1 * regressionResult.minComplexity], + [calculation.complexity, calculation.s1 + calculation.t1 * calculation.complexity] + ]; + regression[Strings.json.regressions.segment2] = [ + [calculation.complexity, calculation.s2 + calculation.t2 * calculation.complexity], + [regressionResult.maxComplexity, calculation.s2 + calculation.t2 * regressionResult.maxComplexity] + ]; + regression[Strings.json.complexity] = calculation.complexity; + regression[Strings.json.measurements.stdev] = Math.sqrt(calculation.error / samples[seriesName].length); + }); + + if (isRampController) { + var timeComplexity = new Experiment; + data[Strings.json.controller].forEach(function(regression) { + timeComplexity.sample(regression[Strings.json.complexity]); + }); + + var experimentResult = {}; + result[Strings.json.controller] = experimentResult; + experimentResult[Strings.json.score] = timeComplexity.mean(); + experimentResult[Strings.json.measurements.average] = timeComplexity.mean(); + experimentResult[Strings.json.measurements.stdev] = timeComplexity.standardDeviation(); + experimentResult[Strings.json.measurements.percent] = timeComplexity.percentage(); + + const bootstrapIterations = 2500; + var bootstrapResult = Regression.bootstrap(complexitySamples.data, bootstrapIterations, function(resampleData) { + var complexityIndex = complexitySamples.fieldMap[Strings.json.complexity]; + resampleData.sort(function(a, b) { + return a[complexityIndex] - b[complexityIndex]; + }); + + var resample = new SampleData(complexitySamples.fieldMap, resampleData); + var regressionResult = findRegression(resample, predominantProfile); + return regressionResult.regression.complexity; + }, .8); + + result[Strings.json.complexity][Strings.json.bootstrap] = bootstrapResult; + result[Strings.json.score] = bootstrapResult.median; + result[Strings.json.scoreLowerBound] = bootstrapResult.confidenceLow; + result[Strings.json.scoreUpperBound] = bootstrapResult.confidenceHigh; + } else { + var marks = data[Strings.json.marks]; + var samplingStartIndex = 0, samplingEndIndex = -1; + if (Strings.json.samplingStartTimeOffset in marks) + samplingStartIndex = marks[Strings.json.samplingStartTimeOffset].index; + if (Strings.json.samplingEndTimeOffset in marks) + samplingEndIndex = marks[Strings.json.samplingEndTimeOffset].index; + + var averageComplexity = new Experiment; + var averageFrameLength = new Experiment; + var controllerSamples = samples[Strings.json.controller]; + controllerSamples.forEach(function (sample, i) { + if (i >= samplingStartIndex && (samplingEndIndex == -1 || i < samplingEndIndex)) { + averageComplexity.sample(controllerSamples.getFieldInDatum(sample, Strings.json.complexity)); + var smoothedFrameLength = controllerSamples.getFieldInDatum(sample, Strings.json.smoothedFrameLength); + if (smoothedFrameLength && smoothedFrameLength != -1) + averageFrameLength.sample(smoothedFrameLength); + } + }); + + var experimentResult = {}; + result[Strings.json.controller] = experimentResult; + experimentResult[Strings.json.measurements.average] = averageComplexity.mean(); + experimentResult[Strings.json.measurements.concern] = averageComplexity.concern(Experiment.defaults.CONCERN); + experimentResult[Strings.json.measurements.stdev] = averageComplexity.standardDeviation(); + experimentResult[Strings.json.measurements.percent] = averageComplexity.percentage(); + + experimentResult = {}; + result[Strings.json.frameLength] = experimentResult; + experimentResult[Strings.json.measurements.average] = 1000 / averageFrameLength.mean(); + experimentResult[Strings.json.measurements.concern] = averageFrameLength.concern(Experiment.defaults.CONCERN); + experimentResult[Strings.json.measurements.stdev] = averageFrameLength.standardDeviation(); + experimentResult[Strings.json.measurements.percent] = averageFrameLength.percentage(); + + result[Strings.json.score] = averageComplexity.score(Experiment.defaults.CONCERN); + result[Strings.json.scoreLowerBound] = result[Strings.json.score] - averageFrameLength.standardDeviation(); + result[Strings.json.scoreUpperBound] = result[Strings.json.score] + averageFrameLength.standardDeviation(); + } + }, + + get data() + { + return this._iterationsSamplers; + }, + + get results() + { + if (this._results) + return this._results[Strings.json.results.iterations]; + this._processData(); + return this._results[Strings.json.results.iterations]; + }, + + get options() + { + return this._options; + }, + + _getResultsProperty: function(property) + { + if (this._results) + return this._results[property]; + this._processData(); + return this._results[property]; + }, + + get score() + { + return this._getResultsProperty(Strings.json.score); + }, + + get scoreLowerBound() + { + return this._getResultsProperty(Strings.json.scoreLowerBound); + }, + + get scoreUpperBound() + { + return this._getResultsProperty(Strings.json.scoreUpperBound); + } +}); + +ResultsTable = Utilities.createClass( + function(element, headers) + { + this.element = element; + this._headers = headers; + + this._flattenedHeaders = []; + this._headers.forEach(function(header) { + if (header.disabled) + return; + + if (header.children) + this._flattenedHeaders = this._flattenedHeaders.concat(header.children); + else + this._flattenedHeaders.push(header); + }, this); + + this._flattenedHeaders = this._flattenedHeaders.filter(function (header) { + return !header.disabled; + }); + + this.clear(); + }, { + + clear: function() + { + this.element.textContent = ""; + }, + + _addHeader: function() + { + var thead = Utilities.createElement("thead", {}, this.element); + var row = Utilities.createElement("tr", {}, thead); + + this._headers.forEach(function (header) { + if (header.disabled) + return; + + var th = Utilities.createElement("th", {}, row); + if (header.title != Strings.text.graph) + th.innerHTML = header.title; + if (header.children) + th.colSpan = header.children.length; + }); + }, + + _addBody: function() + { + this.tbody = Utilities.createElement("tbody", {}, this.element); + }, + + _addEmptyRow: function() + { + var row = Utilities.createElement("tr", {}, this.tbody); + this._flattenedHeaders.forEach(function (header) { + return Utilities.createElement("td", { class: "suites-separator" }, row); + }); + }, + + _addTest: function(testName, testResult, options) + { + var row = Utilities.createElement("tr", {}, this.tbody); + + this._flattenedHeaders.forEach(function (header) { + var td = Utilities.createElement("td", {}, row); + if (header.text == Strings.text.testName) { + td.textContent = testName; + } else if (typeof header.text == "string") { + var data = testResult[header.text]; + if (typeof data == "number") + data = data.toFixed(2); + td.innerHTML = data; + } else + td.innerHTML = header.text(testResult); + }, this); + }, + + _addIteration: function(iterationResult, iterationData, options) + { + var testsResults = iterationResult[Strings.json.results.tests]; + for (var suiteName in testsResults) { + this._addEmptyRow(); + var suiteResult = testsResults[suiteName]; + var suiteData = iterationData[suiteName]; + for (var testName in suiteResult) + this._addTest(testName, suiteResult[testName], options, suiteData[testName]); + } + }, + + showIterations: function(dashboard) + { + this.clear(); + this._addHeader(); + this._addBody(); + + var iterationsResults = dashboard.results; + iterationsResults.forEach(function(iterationResult, index) { + this._addIteration(iterationResult, dashboard.data[index], dashboard.options); + }, this); + } +}); + +window.benchmarkRunnerClient = { + iterationCount: 1, + options: null, + results: null, + + initialize: function(suites, options) + { + this.options = options; + }, + + willStartFirstIteration: function() + { + this.results = new ResultsDashboard(this.options); + }, + + didRunSuites: function(suitesSamplers) + { + this.results.push(suitesSamplers); + }, + + didRunTest: function(testData) + { + this.results.calculateScore(testData); + }, + + didFinishLastIteration: function() + { + benchmarkController.showResults(); + } +}; + +window.sectionsManager = +{ + showSection: function(sectionIdentifier, pushState) + { + var sections = document.querySelectorAll("main > section"); + for (var i = 0; i < sections.length; ++i) { + document.body.classList.remove("showing-" + sections[i].id); + } + document.body.classList.add("showing-" + sectionIdentifier); + + var currentSectionElement = document.querySelector("section.selected"); + console.assert(currentSectionElement); + + var newSectionElement = document.getElementById(sectionIdentifier); + console.assert(newSectionElement); + + currentSectionElement.classList.remove("selected"); + newSectionElement.classList.add("selected"); + + if (pushState) + history.pushState({section: sectionIdentifier}, document.title); + }, + + setSectionScore: function(sectionIdentifier, score, confidence) + { + document.querySelector("#" + sectionIdentifier + " .score").textContent = score; + if (confidence) + document.querySelector("#" + sectionIdentifier + " .confidence").textContent = confidence; + }, + + populateTable: function(tableIdentifier, headers, dashboard) + { + var table = new ResultsTable(document.getElementById(tableIdentifier), headers); + table.showIterations(dashboard); + } +}; + +window.benchmarkController = { + initialize: function() + { + benchmarkController.addOrientationListenerIfNecessary(); + }, + + determineCanvasSize: function() { + var match = window.matchMedia("(max-device-width: 760px)"); + if (match.matches) { + document.body.classList.add("small"); + return; + } + + match = window.matchMedia("(max-device-width: 1600px)"); + if (match.matches) { + document.body.classList.add("medium"); + return; + } + + match = window.matchMedia("(max-width: 1600px)"); + if (match.matches) { + document.body.classList.add("medium"); + return; + } + + document.body.classList.add("large"); + }, + + addOrientationListenerIfNecessary: function() { + if (!("orientation" in window)) + return; + + this.orientationQuery = window.matchMedia("(orientation: landscape)"); + this._orientationChanged(this.orientationQuery); + this.orientationQuery.addListener(this._orientationChanged); + }, + + _orientationChanged: function(match) + { + benchmarkController.isInLandscapeOrientation = match.matches; + if (match.matches) + document.querySelector(".start-benchmark p").classList.add("hidden"); + else + document.querySelector(".start-benchmark p").classList.remove("hidden"); + benchmarkController.updateStartButtonState(); + }, + + updateStartButtonState: function() + { + document.getElementById("run-benchmark").disabled = !this.isInLandscapeOrientation; + }, + + _startBenchmark: function(suites, options, frameContainerID) + { + benchmarkController.determineCanvasSize(); + + var configuration = document.body.className.match(/small|medium|large/); + if (configuration) + options[Strings.json.configuration] = configuration[0]; + + benchmarkRunnerClient.initialize(suites, options); + var frameContainer = document.getElementById(frameContainerID); + var runner = new BenchmarkRunner(suites, frameContainer, benchmarkRunnerClient); + runner.runMultipleIterations(); + + sectionsManager.showSection("test-container"); + }, + + startBenchmark: function() + { + var options = { + "test-interval": 30, + "display": "minimal", + "tiles": "big", + "controller": "ramp", + "kalman-process-error": 1, + "kalman-measurement-error": 4, + "time-measurement": "performance" + }; + this._startBenchmark(Suites, options, "test-container"); + }, + + showResults: function() + { + if (!this.addedKeyEvent) { + document.addEventListener("keypress", this.handleKeyPress, false); + this.addedKeyEvent = true; + } + + var dashboard = benchmarkRunnerClient.results; + var score = dashboard.score; + var confidence = "±" + (Statistics.largestDeviationPercentage(dashboard.scoreLowerBound, score, dashboard.scoreUpperBound) * 100).toFixed(2) + "%"; + sectionsManager.setSectionScore("results", score.toFixed(2), confidence); + sectionsManager.populateTable("results-header", Headers.testName, dashboard); + sectionsManager.populateTable("results-score", Headers.score, dashboard); + sectionsManager.populateTable("results-data", Headers.details, dashboard); + sectionsManager.showSection("results", true); + }, + + handleKeyPress: function(event) + { + switch (event.charCode) + { + case 27: // esc + benchmarkController.hideDebugInfo(); + break; + case 106: // j + benchmarkController.showDebugInfo(); + break; + case 115: // s + benchmarkController.selectResults(event.target); + break; + } + }, + + hideDebugInfo: function() + { + var overlay = document.getElementById("overlay"); + if (!overlay) + return; + document.body.removeChild(overlay); + }, + + showDebugInfo: function() + { + if (document.getElementById("overlay")) + return; + + var overlay = Utilities.createElement("div", { + id: "overlay" + }, document.body); + var container = Utilities.createElement("div", {}, overlay); + + var header = Utilities.createElement("h3", {}, container); + header.textContent = "Debug Output"; + + var data = Utilities.createElement("div", {}, container); + data.textContent = "Please wait..."; + setTimeout(function() { + var output = { + options: benchmarkRunnerClient.results.options, + data: benchmarkRunnerClient.results.data + }; + data.textContent = JSON.stringify(output, function(key, value) { + if (typeof value === 'number') + return Utilities.toFixedNumber(value, 3); + return value; + }, 1); + }, 0); + data.onclick = function() { + var selection = window.getSelection(); + selection.removeAllRanges(); + var range = document.createRange(); + range.selectNode(data); + selection.addRange(range); + }; + + var button = Utilities.createElement("button", {}, container); + button.textContent = "Done"; + button.onclick = function() { + benchmarkController.hideDebugInfo(); + }; + }, + + selectResults: function(target) + { + target.selectRange = ((target.selectRange || 0) + 1) % 3; + + var selection = window.getSelection(); + selection.removeAllRanges(); + var range = document.createRange(); + switch (target.selectRange) { + case 0: { + range.selectNode(document.getElementById("results-score")); + break; + } + case 1: { + range.setStart(document.querySelector("#results .score"), 0); + range.setEndAfter(document.querySelector("#results-score"), 0); + break; + } + case 2: { + range.selectNodeContents(document.querySelector("#results .score")); + break; + } + } + selection.addRange(range); + } +}; + +window.addEventListener("load", function() { benchmarkController.initialize(); }); diff --git a/third_party/webkit/PerformanceTests/MotionMark/resources/runner/benchmark-runner.js b/third_party/webkit/PerformanceTests/MotionMark/resources/runner/benchmark-runner.js new file mode 100644 index 0000000000..1aa630356c --- /dev/null +++ b/third_party/webkit/PerformanceTests/MotionMark/resources/runner/benchmark-runner.js @@ -0,0 +1,179 @@ +BenchmarkRunnerState = Utilities.createClass( + function(suites) + { + this._suites = suites; + this._suiteIndex = -1; + this._testIndex = 0; + this.next(); + }, { + + currentSuite: function() + { + return this._suites[this._suiteIndex]; + }, + + currentTest: function() + { + var suite = this.currentSuite(); + return suite ? suite.tests[this._testIndex] : null; + }, + + isFirstTest: function() + { + return !this._testIndex; + }, + + next: function() + { + this._testIndex++; + + var suite = this._suites[this._suiteIndex]; + if (suite && this._testIndex < suite.tests.length) + return; + + this._testIndex = 0; + do { + this._suiteIndex++; + } while (this._suiteIndex < this._suites.length && this._suites[this._suiteIndex].disabled); + }, + + prepareCurrentTest: function(runner, frame) + { + var test = this.currentTest(); + var promise = new SimplePromise; + + frame.onload = function() { + promise.resolve(); + }; + + frame.src = "tests/" + test.url; + return promise; + } +}); + +BenchmarkRunner = Utilities.createClass( + function(suites, frameContainer, client) + { + this._suites = suites; + this._client = client; + this._frameContainer = frameContainer; + }, { + + _appendFrame: function() + { + var frame = document.createElement("iframe"); + frame.setAttribute("scrolling", "no"); + + this._frameContainer.insertBefore(frame, this._frameContainer.firstChild); + this._frame = frame; + return frame; + }, + + _removeFrame: function() + { + if (this._frame) { + this._frame.parentNode.removeChild(this._frame); + this._frame = null; + } + }, + + _runBenchmarkAndRecordResults: function(state) + { + var promise = new SimplePromise; + var suite = state.currentSuite(); + var test = state.currentTest(); + + if (this._client && this._client.willRunTest) + this._client.willRunTest(suite, test); + + var contentWindow = this._frame.contentWindow; + var self = this; + + var options = { complexity: test.complexity }; + Utilities.extendObject(options, this._client.options); + Utilities.extendObject(options, contentWindow.Utilities.parseParameters()); + + var benchmark = new contentWindow.benchmarkClass(options); + document.body.style.backgroundColor = benchmark.backgroundColor(); + benchmark.run().then(function(testData) { + var suiteResults = self._suitesResults[suite.name] || {}; + suiteResults[test.name] = testData; + self._suitesResults[suite.name] = suiteResults; + + if (self._client && self._client.didRunTest) + self._client.didRunTest(testData); + + state.next(); + if (state.currentSuite() != suite) + self._removeFrame(); + promise.resolve(state); + }); + + return promise; + }, + + step: function(state) + { + if (!state) { + state = new BenchmarkRunnerState(this._suites); + this._suitesResults = {}; + } + + var suite = state.currentSuite(); + if (!suite) { + this._finalize(); + var promise = new SimplePromise; + promise.resolve(); + return promise; + } + + if (state.isFirstTest()) { + this._appendFrame(); + } + + return state.prepareCurrentTest(this, this._frame).then(function(prepareReturnValue) { + return this._runBenchmarkAndRecordResults(state); + }.bind(this)); + }, + + runAllSteps: function(startingState) + { + var nextCallee = this.runAllSteps.bind(this); + this.step(startingState).then(function(nextState) { + if (nextState) + nextCallee(nextState); + }); + }, + + runMultipleIterations: function() + { + var self = this; + var currentIteration = 0; + + this._runNextIteration = function() { + currentIteration++; + if (currentIteration < self._client.iterationCount) + self.runAllSteps(); + else if (this._client && this._client.didFinishLastIteration) { + document.body.style.backgroundColor = ""; + self._client.didFinishLastIteration(); + } + } + + if (this._client && this._client.willStartFirstIteration) + this._client.willStartFirstIteration(); + + this.runAllSteps(); + }, + + _finalize: function() + { + this._removeFrame(); + + if (this._client && this._client.didRunSuites) + this._client.didRunSuites(this._suitesResults); + + if (this._runNextIteration) + this._runNextIteration(); + } +}); diff --git a/third_party/webkit/PerformanceTests/MotionMark/resources/runner/crystal.svg b/third_party/webkit/PerformanceTests/MotionMark/resources/runner/crystal.svg new file mode 100644 index 0000000000..0090df6c0c --- /dev/null +++ b/third_party/webkit/PerformanceTests/MotionMark/resources/runner/crystal.svg @@ -0,0 +1,92 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright © 2016 Apple Inc. All rights reserved. --> +<svg viewBox="0 0 1000 1000" preserveAspectRatio="none" version="1.1" xmlns="http://www.w3.org/2000/svg"> + <g fill="white" stroke="white" stroke-width="0.15"> + <path fill-opacity="1" stroke-opacity="1" d=" M 0 0 L 327.88 0 C 325.14 2.87 322.60 5.94 319.73 8.68 C 315.84 12.50 311.31 16.05 309.30 21.31 C 303.10 37.43 296.87 53.54 290.57 69.62 C 288.47 75.11 285.91 80.43 284.24 86.07 C 285.81 87.43 287.37 88.81 289.07 90.01 C 311.23 105.31 332.96 121.25 355.21 136.43 C 357.15 140.82 359.76 145.01 360.61 149.80 C 361.24 153.54 361.64 157.34 361.37 161.13 C 358.55 166.08 356.04 171.21 353.27 176.19 C 353.07 176.54 352.67 177.23 352.48 177.57 C 350 179.82 347.14 181.57 344.29 183.30 C 335.73 188.47 327.27 193.80 318.71 198.98 C 308.13 198.76 297.56 199.12 287.01 199.74 C 279.65 200.20 272.27 199.53 264.92 200.02 C 262.30 200.09 259.91 201.30 257.93 202.94 C 238.82 218.89 219.07 234.08 199.86 249.90 C 196.40 252.94 194.22 257.05 191.56 260.74 C 185.35 267.44 176.30 270.51 169.90 276.91 C 167.71 282.16 169.92 288.14 170.35 293.60 C 171.49 300.35 172.29 307.14 173.21 313.92 C 173.56 316.94 174.94 319.79 177.25 321.80 C 191.06 333.94 203.32 347.74 217.23 359.78 C 225.25 367.81 233.44 375.66 241.21 383.92 C 240.08 390.20 237.63 396.53 238.91 402.98 C 243.04 426.95 247.04 450.94 251.10 474.92 C 252.01 480.25 253.09 485.59 253.21 491.02 C 252.78 493.08 252.36 495.16 251.80 497.20 C 245.46 503.93 239.30 510.88 232.53 517.18 C 229.17 519.86 225.15 522.50 223.72 526.76 C 222.48 536.86 222.68 547.08 221.69 557.21 C 221.55 562.43 220.62 567.83 222.17 572.93 C 227.92 589.76 231.93 607.12 236.76 624.23 C 237.77 628.08 239 631.89 239.78 635.81 C 236.34 648.91 232.70 661.96 229.12 675.02 C 221.78 676.32 214.41 674.68 207.03 674.87 C 197.35 675.08 187.73 673.63 178.06 673.91 C 167.70 674.16 157.40 672.47 147.04 672.92 C 134.73 673.25 122.45 671.07 110.15 672.14 C 114.51 679.54 119.71 686.40 124.41 693.59 C 143.51 722.45 162.87 751.15 181.98 780 C 185.26 784.93 191.47 785.96 196.30 788.75 C 197.35 794.78 196.74 800.90 196.84 806.98 C 196.94 817.65 196.93 828.31 196.97 838.98 C 197.12 846.82 196.23 854.78 198.23 862.46 C 198.18 870.99 198.91 879.57 197.90 888.06 C 196.92 891.68 197.94 895.32 199.28 898.70 C 195.30 904.88 190.33 910.34 185.64 915.99 C 178.89 920.62 171.57 924.35 164.65 928.72 C 158.28 932.76 151.41 936 145.28 940.39 C 140 944.77 136.22 950.60 131.64 955.65 C 128.24 959.88 124.34 963.73 121.19 968.16 C 119.32 970.80 120.37 974.22 120.59 977.20 C 121.77 984.78 122.70 992.40 123.77 1000 L 0 1000 L 0 0 Z"/> + <path fill-opacity="0.9883" stroke-opacity="0.9883" d=" M 169.90 276.91 C 176.30 270.51 185.35 267.44 191.56 260.74 C 195.63 265.49 201.89 267.02 207.24 269.80 C 229.32 280.67 251.38 291.56 273.44 302.46 C 289.29 309.67 304.43 318.39 320.48 325.16 C 323.79 331.38 327.72 337.24 331.27 343.31 C 301.44 357.25 271.05 370 241.21 383.92 C 233.44 375.66 225.25 367.81 217.23 359.78 C 203.32 347.74 191.06 333.94 177.25 321.80 C 174.94 319.79 173.56 316.94 173.21 313.92 C 172.29 307.14 171.49 300.35 170.35 293.60 C 169.92 288.14 167.71 282.16 169.90 276.91 Z"/> + <path fill-opacity="0.9804" stroke-opacity="0.9804" d=" M 110.15 672.14 C 122.45 671.07 134.73 673.25 147.04 672.92 C 157.40 672.47 167.70 674.16 178.06 673.91 C 187.73 673.63 197.35 675.08 207.03 674.87 C 214.41 674.68 221.78 676.32 229.12 675.02 C 230.32 677.25 231.56 679.45 232.90 681.60 C 233.20 683.35 233.22 685.15 232.89 686.92 C 226.83 717.17 221.18 747.50 215.10 777.75 C 209.29 781.47 203.40 785.09 197.76 789.07 C 197.63 813.54 198.62 838 198.23 862.46 C 196.23 854.78 197.12 846.82 196.97 838.98 C 196.93 828.31 196.94 817.65 196.84 806.98 C 196.74 800.90 197.35 794.78 196.30 788.75 C 191.47 785.96 185.26 784.93 181.98 780 C 162.87 751.15 143.51 722.45 124.41 693.59 C 119.71 686.40 114.51 679.54 110.15 672.14 Z"/> + <path fill-opacity="0.9687" stroke-opacity="0.9687" d=" M 287.01 199.74 C 297.56 199.12 308.13 198.76 318.71 198.98 C 320.17 228.28 318.86 257.66 320.23 286.97 C 320.34 299.70 320.40 312.43 320.48 325.16 C 304.43 318.39 289.29 309.67 273.44 302.46 C 251.38 291.56 229.32 280.67 207.24 269.80 C 201.89 267.02 195.63 265.49 191.56 260.74 C 194.22 257.05 196.40 252.94 199.86 249.90 C 219.07 234.08 238.82 218.89 257.93 202.94 C 259.91 201.30 262.30 200.09 264.92 200.02 C 272.27 199.53 279.65 200.20 287.01 199.74 Z"/> + <path fill-opacity="0.953" stroke-opacity="0.953" d=" M 327.88 0 L 373.98 0 C 367.79 45.48 361.61 90.97 355.21 136.43 C 332.96 121.25 311.23 105.31 289.07 90.01 C 287.37 88.81 285.81 87.43 284.24 86.07 C 285.91 80.43 288.47 75.11 290.57 69.62 C 296.87 53.54 303.10 37.43 309.30 21.31 C 311.31 16.05 315.84 12.50 319.73 8.68 C 322.60 5.94 325.14 2.87 327.88 0 Z"/> + <path fill-opacity="0.9491" stroke-opacity="0.9491" d=" M 164.65 928.72 C 171.57 924.35 178.89 920.62 185.64 915.99 C 186.75 944 188.72 971.99 190.07 1000 L 123.77 1000 C 122.70 992.40 121.77 984.78 120.59 977.20 C 120.37 974.22 119.32 970.80 121.19 968.16 C 124.34 963.73 128.24 959.88 131.64 955.65 C 136.22 950.60 140 944.77 145.28 940.39 C 151.41 936 158.28 932.76 164.65 928.72 Z"/> + <path fill-opacity="0.9295" stroke-opacity="0.9295" d=" M 331.27 343.31 C 342.73 349.21 354.49 354.50 365.86 360.56 C 366.36 361.84 366.86 363.12 367.37 364.41 C 367.21 366.77 366.28 368.98 365.20 371.06 C 362.81 375.78 360.53 380.54 358.35 385.36 C 345.47 397.11 333.54 409.87 321.09 422.06 C 299.90 443.25 278.73 464.47 257.50 485.61 C 255.90 487.27 254.44 489.06 253.21 491.02 C 253.09 485.59 252.01 480.25 251.10 474.92 C 247.04 450.94 243.04 426.95 238.91 402.98 C 237.63 396.53 240.08 390.20 241.21 383.92 C 271.05 370 301.44 357.25 331.27 343.31 Z"/> + <path fill-opacity="0.8785" stroke-opacity="0.8785" d=" M 223.72 526.76 C 225.15 522.50 229.17 519.86 232.53 517.18 C 238.93 523.27 246.16 528.39 253.01 533.95 C 280.84 556.11 308.83 578.09 336.63 600.29 C 341.10 603.79 346.07 606.93 349.22 611.79 C 350.70 615.38 352.13 618.98 353.74 622.52 C 347.24 625.52 339.96 624.93 333.04 625.88 C 301.97 629.40 270.82 632.13 239.78 635.81 C 239 631.89 237.77 628.08 236.76 624.23 C 231.93 607.12 227.92 589.76 222.17 572.93 C 220.62 567.83 221.55 562.43 221.69 557.21 C 222.68 547.08 222.48 536.86 223.72 526.76 Z"/> + <path fill-opacity="0.8746" stroke-opacity="0.8746" d=" M 199.28 898.70 C 203.46 901.06 207.86 902.98 212.33 904.76 C 214.88 905.73 217.17 907.37 218.69 909.68 C 225.30 927.02 231.55 944.50 238.11 961.86 C 239.21 964.87 240.62 967.82 241.15 971.02 C 241.25 973.62 240.44 976.14 239.87 978.66 C 238.03 985.74 236.68 992.94 234.74 1000 L 190.07 1000 C 188.72 971.99 186.75 944 185.64 915.99 C 190.33 910.34 195.30 904.88 199.28 898.70 Z"/> + <path fill-opacity="0.8706" stroke-opacity="0.8706" d=" M 232.90 681.60 C 235.14 683.02 237.58 684.12 240.11 684.93 C 258.41 690.06 276.85 694.79 294.93 700.68 C 304.80 726.80 314.30 753.06 323.99 779.25 C 321.69 780.75 319.57 782.51 317.43 784.23 C 283.33 781.96 249.22 779.81 215.10 777.75 C 221.18 747.50 226.83 717.17 232.89 686.92 C 233.22 685.15 233.20 683.35 232.90 681.60 Z"/> + <path fill-opacity="0.8589" stroke-opacity="0.8589" d=" M 353.74 622.52 C 354.67 624.51 355 626.71 354.72 628.90 C 354.14 631.20 353.60 633.50 353.05 635.80 C 350.68 639.43 347.58 642.48 344.71 645.70 C 328.13 664.04 311.35 682.20 294.93 700.68 C 276.85 694.79 258.41 690.06 240.11 684.93 C 237.58 684.12 235.14 683.02 232.90 681.60 C 231.56 679.45 230.32 677.25 229.12 675.02 C 232.70 661.96 236.34 648.91 239.78 635.81 C 270.82 632.13 301.97 629.40 333.04 625.88 C 339.96 624.93 347.24 625.52 353.74 622.52 Z"/> + <path fill-opacity="0.855" stroke-opacity="0.855" d=" M 197.76 789.07 C 203.40 785.09 209.29 781.47 215.10 777.75 C 249.22 779.81 283.33 781.96 317.43 784.23 C 315.73 791.84 313.84 799.40 312.11 807 C 310.31 810.16 307.51 812.57 304.47 814.49 C 287.18 825.78 270.27 837.63 253.03 848.98 C 236.55 859.79 220.52 871.26 203.96 881.93 C 201.52 883.50 199.47 885.61 197.90 888.06 C 198.91 879.57 198.18 870.99 198.23 862.46 C 198.62 838 197.63 813.54 197.76 789.07 Z"/> + <path fill-opacity="0.855" stroke-opacity="0.855" d=" M 344.29 183.30 C 347.14 181.57 350 179.82 352.48 177.57 C 352.77 181.76 355.26 185.30 357.10 188.94 C 365.30 204.47 373.30 220.10 381.52 235.62 C 383.12 238.45 384.06 241.61 384.44 244.84 C 387.81 271.89 391.59 298.89 394.85 325.96 C 385.10 337.41 375.36 348.89 365.86 360.56 C 354.49 354.50 342.73 349.21 331.27 343.31 C 327.72 337.24 323.79 331.38 320.48 325.16 C 320.40 312.43 320.34 299.70 320.23 286.97 C 318.86 257.66 320.17 228.28 318.71 198.98 C 327.27 193.80 335.73 188.47 344.29 183.30 Z"/> + <path fill-opacity="0.8432" stroke-opacity="0.8432" d=" M 321.09 422.06 C 333.54 409.87 345.47 397.11 358.35 385.36 C 358.79 393.90 358 402.41 357.61 410.93 C 357.58 424.29 356.35 437.61 356.32 450.97 C 355.30 462.60 355.77 474.29 354.82 485.93 C 354.49 491.91 354.57 497.91 354.23 503.90 C 350.84 504.27 347.41 504.51 344.01 504.17 C 313.30 501.45 282.48 500.24 251.80 497.20 C 252.36 495.16 252.78 493.08 253.21 491.02 C 254.44 489.06 255.90 487.27 257.50 485.61 C 278.73 464.47 299.90 443.25 321.09 422.06 Z"/> + <path fill-opacity="0.8393" stroke-opacity="0.8393" d=" M 373.98 0 L 375.50 0 C 397.90 16.47 420.67 32.46 443.14 48.85 C 449.83 53.79 456.77 58.38 463.25 63.61 C 431.93 89.13 400.82 114.91 369.61 140.56 C 366.28 143.28 362.37 145.67 360.61 149.80 C 359.76 145.01 357.15 140.82 355.21 136.43 C 361.61 90.97 367.79 45.48 373.98 0 Z"/> + <path fill-opacity="0.8275" stroke-opacity="0.8275" d=" M 251.80 497.20 C 282.48 500.24 313.30 501.45 344.01 504.17 C 347.41 504.51 350.84 504.27 354.23 503.90 C 357.03 506.62 361.90 508.29 361.97 512.80 C 358.05 541.20 353.99 569.58 349.99 597.97 C 349.44 602.54 347.90 607.21 349.22 611.79 C 346.07 606.93 341.10 603.79 336.63 600.29 C 308.83 578.09 280.84 556.11 253.01 533.95 C 246.16 528.39 238.93 523.27 232.53 517.18 C 239.30 510.88 245.46 503.93 251.80 497.20 Z"/> + <path fill-opacity="0.8197" stroke-opacity="0.8197" d=" M 304.47 814.49 C 307.51 812.57 310.31 810.16 312.11 807 C 310.99 813.29 311.73 819.70 311.72 826.05 C 312.47 837.02 312.51 848.02 312.50 859.01 C 300.69 875.28 289.35 891.88 277.41 908.05 C 270.37 909.81 263.17 908.36 256.04 908.19 C 249.68 907.96 243.30 908.12 236.94 907.87 C 231.21 907.71 225.49 906.94 219.75 907.36 C 219.49 907.94 218.96 909.10 218.69 909.68 C 217.17 907.37 214.88 905.73 212.33 904.76 C 207.86 902.98 203.46 901.06 199.28 898.70 C 197.94 895.32 196.92 891.68 197.90 888.06 C 199.47 885.61 201.52 883.50 203.96 881.93 C 220.52 871.26 236.55 859.79 253.03 848.98 C 270.27 837.63 287.18 825.78 304.47 814.49 Z"/> + <path fill-opacity="0.7844" stroke-opacity="0.7844" d=" M 219.75 907.36 C 225.49 906.94 231.21 907.71 236.94 907.87 C 243.30 908.12 249.68 907.96 256.04 908.19 C 263.17 908.36 270.37 909.81 277.41 908.05 C 279.98 912.58 284.54 915.31 288.41 918.60 C 295.15 924.19 301.91 929.75 308.65 935.35 C 313.06 939.14 318.10 942.31 321.57 947.09 C 318.07 952.97 314.74 958.95 311.43 964.94 C 302.10 970.37 292.91 976.03 283.57 981.44 C 281.17 982.96 278.31 984.13 276.66 986.54 C 275.16 990.86 275.11 995.50 274.48 1000 L 234.74 1000 C 236.68 992.94 238.03 985.74 239.87 978.66 C 240.44 976.14 241.25 973.62 241.15 971.02 C 240.62 967.82 239.21 964.87 238.11 961.86 C 231.55 944.50 225.30 927.02 218.69 909.68 C 218.96 909.10 219.49 907.94 219.75 907.36 Z"/> + <path fill-opacity="0.7687" stroke-opacity="0.7687" d=" M 375.50 0 L 548.99 0 C 548.07 11.56 546.25 23.02 544.95 34.54 C 525.98 45.47 506.58 55.63 487.69 66.69 C 479.58 65.38 471.41 64.56 463.25 63.61 C 456.77 58.38 449.83 53.79 443.14 48.85 C 420.67 32.46 397.90 16.47 375.50 0 Z"/> + <path fill-opacity="0.7569" stroke-opacity="0.7569" d=" M 352.48 177.57 C 352.67 177.23 353.07 176.54 353.27 176.19 C 355.78 178.93 358.62 181.38 361.89 183.17 C 373.79 190.05 384.67 198.48 396.38 205.65 C 405.55 211.85 415.12 217.43 424.07 223.95 C 435.96 231.69 447.97 239.23 459.67 247.26 C 464.57 250.45 469.33 253.97 474.82 256.12 C 481.80 259.13 489.74 260.31 495.64 265.43 C 491.08 270.99 486.53 276.57 481.84 282.02 C 453.09 297.13 423.63 310.91 394.85 325.96 C 391.59 298.89 387.81 271.89 384.44 244.84 C 384.06 241.61 383.12 238.45 381.52 235.62 C 373.30 220.10 365.30 204.47 357.10 188.94 C 355.26 185.30 352.77 181.76 352.48 177.57 Z"/> + <path fill-opacity="0.753" stroke-opacity="0.753" d=" M 369.61 140.56 C 400.82 114.91 431.93 89.13 463.25 63.61 C 471.41 64.56 479.58 65.38 487.69 66.69 C 486.82 82.73 485.05 98.72 483.75 114.73 C 483.15 119.05 483.64 123.99 480.54 127.48 C 469.52 141.36 458.63 155.35 447.54 169.17 C 426.29 167.96 405.18 164.93 383.98 162.95 C 376.44 162.39 368.97 160.61 361.37 161.13 C 361.64 157.34 361.24 153.54 360.61 149.80 C 362.37 145.67 366.28 143.28 369.61 140.56 Z"/> + <path fill-opacity="0.7491" stroke-opacity="0.7491" d=" M 344.71 645.70 C 347.58 642.48 350.68 639.43 353.05 635.80 C 353.70 641.86 356.06 647.52 357.70 653.34 C 367.82 686.89 378.38 720.31 388.25 753.93 C 381.61 761.08 375.26 768.49 368.57 775.58 C 353.73 777.09 338.83 777.79 323.99 779.25 C 314.30 753.06 304.80 726.80 294.93 700.68 C 311.35 682.20 328.13 664.04 344.71 645.70 Z"/> + <path fill-opacity="0.7491" stroke-opacity="0.7491" d=" M 367.37 364.41 C 368.87 366.30 370.70 367.89 372.63 369.33 C 379.75 374.55 386.90 379.73 394 384.98 C 396.46 386.66 397.68 389.46 398.65 392.18 C 409.39 422.55 420.71 452.72 431.53 483.07 C 430.70 484.02 429.91 485 429.06 485.94 C 421.71 492.88 414.29 499.73 407.01 506.74 C 393.67 507.87 380.29 508.51 366.96 509.77 C 364.79 509.76 362.96 510.89 361.97 512.80 C 361.90 508.29 357.03 506.62 354.23 503.90 C 354.57 497.91 354.49 491.91 354.82 485.93 C 355.77 474.29 355.30 462.60 356.32 450.97 C 356.35 437.61 357.58 424.29 357.61 410.93 C 358 402.41 358.79 393.90 358.35 385.36 C 360.53 380.54 362.81 375.78 365.20 371.06 C 366.28 368.98 367.21 366.77 367.37 364.41 Z"/> + <path fill-opacity="0.7451" stroke-opacity="0.7451" d=" M 361.37 161.13 C 368.97 160.61 376.44 162.39 383.98 162.95 C 405.18 164.93 426.29 167.96 447.54 169.17 C 456.58 182.09 466.70 194.20 476.10 206.86 C 488.03 222.59 500.24 238.11 512.07 253.92 C 506.49 257.58 500.73 261.09 495.64 265.43 C 489.74 260.31 481.80 259.13 474.82 256.12 C 469.33 253.97 464.57 250.45 459.67 247.26 C 447.97 239.23 435.96 231.69 424.07 223.95 C 415.12 217.43 405.55 211.85 396.38 205.65 C 384.67 198.48 373.79 190.05 361.89 183.17 C 358.62 181.38 355.78 178.93 353.27 176.19 C 356.04 171.21 358.55 166.08 361.37 161.13 Z"/> + <path fill-opacity="0.7334" stroke-opacity="0.7334" d=" M 283.57 981.44 C 292.91 976.03 302.10 970.37 311.43 964.94 C 311.57 976.62 311.48 988.31 311.52 1000 L 274.48 1000 C 275.11 995.50 275.16 990.86 276.66 986.54 C 278.31 984.13 281.17 982.96 283.57 981.44 Z"/> + <path fill-opacity="0.702" stroke-opacity="0.702" d=" M 366.96 509.77 C 380.29 508.51 393.67 507.87 407.01 506.74 C 415.89 532.41 425.55 557.83 433.99 583.64 C 427.09 595.62 420.28 607.64 413.32 619.59 C 395.24 621.90 377.04 623.19 358.94 625.21 C 356.73 625.22 355.69 627.25 354.72 628.90 C 355 626.71 354.67 624.51 353.74 622.52 C 352.13 618.98 350.70 615.38 349.22 611.79 C 347.90 607.21 349.44 602.54 349.99 597.97 C 353.99 569.58 358.05 541.20 361.97 512.80 C 362.96 510.89 364.79 509.76 366.96 509.77 Z"/> + <path fill-opacity="0.6942" stroke-opacity="0.6942" d=" M 312.50 859.01 C 318.79 860.71 324.36 864.19 330.34 866.66 C 340.54 871.48 351.13 875.47 361.11 880.75 C 368.34 888.78 374.93 897.37 382.12 905.45 C 382.47 918.41 383.24 931.35 383.76 944.30 C 383.10 944.93 382.45 945.58 381.81 946.23 C 365.22 945.99 348.63 946.36 332.05 946.01 C 328.52 945.92 325.03 946.45 321.57 947.09 C 318.10 942.31 313.06 939.14 308.65 935.35 C 301.91 929.75 295.15 924.19 288.41 918.60 C 284.54 915.31 279.98 912.58 277.41 908.05 C 289.35 891.88 300.69 875.28 312.50 859.01 Z"/> + <path fill-opacity="0.6746" stroke-opacity="0.6746" d=" M 323.99 779.25 C 338.83 777.79 353.73 777.09 368.57 775.58 C 370.03 778.30 371.42 781.07 373.10 783.67 C 370.01 804.70 367.76 825.84 365.06 846.93 C 363.76 858.20 362.03 869.43 361.11 880.75 C 351.13 875.47 340.54 871.48 330.34 866.66 C 324.36 864.19 318.79 860.71 312.50 859.01 C 312.51 848.02 312.47 837.02 311.72 826.05 C 311.73 819.70 310.99 813.29 312.11 807 C 313.84 799.40 315.73 791.84 317.43 784.23 C 319.57 782.51 321.69 780.75 323.99 779.25 Z"/> + <path fill-opacity="0.6589" stroke-opacity="0.6589" d=" M 321.57 947.09 C 325.03 946.45 328.52 945.92 332.05 946.01 C 348.63 946.36 365.22 945.99 381.81 946.23 C 381.69 964.15 381.80 982.08 381.76 1000 L 311.52 1000 C 311.48 988.31 311.57 976.62 311.43 964.94 C 314.74 958.95 318.07 952.97 321.57 947.09 Z"/> + <path fill-opacity="0.6314" stroke-opacity="0.6314" d=" M 358.94 625.21 C 377.04 623.19 395.24 621.90 413.32 619.59 C 425.37 632.53 438.16 644.78 450.52 657.44 C 451.82 658.56 451.93 660.27 451.97 661.90 C 447.59 684.96 442.57 707.90 437.80 730.89 C 437.35 732.71 436.78 734.49 436.25 736.30 C 420.39 742.54 404.13 747.73 388.25 753.93 C 378.38 720.31 367.82 686.89 357.70 653.34 C 356.06 647.52 353.70 641.86 353.05 635.80 C 353.60 633.50 354.14 631.20 354.72 628.90 C 355.69 627.25 356.73 625.22 358.94 625.21 Z"/> + <path fill-opacity="0.6314" stroke-opacity="0.6314" d=" M 394.85 325.96 C 423.63 310.91 453.09 297.13 481.84 282.02 C 482.68 291.99 484.20 301.89 485.40 311.82 C 488.58 336.52 491.67 361.24 494.97 385.93 C 495.24 388.17 495.36 390.43 495.27 392.70 C 494.98 393.29 494.40 394.47 494.11 395.06 C 462.25 392.21 430.37 389.52 398.47 387.18 C 398.50 388.85 398.54 390.51 398.65 392.18 C 397.68 389.46 396.46 386.66 394 384.98 C 386.90 379.73 379.75 374.55 372.63 369.33 C 370.70 367.89 368.87 366.30 367.37 364.41 C 366.86 363.12 366.36 361.84 365.86 360.56 C 375.36 348.89 385.10 337.41 394.85 325.96 Z"/> + <path fill-opacity="0.6314" stroke-opacity="0.6314" d=" M 480.54 127.48 C 483.64 123.99 483.15 119.05 483.75 114.73 C 483.90 118.96 482.75 124.41 486.59 127.38 C 511.90 148.19 537.31 168.90 562.41 189.96 C 550.38 210.51 538.52 231.18 526.52 251.76 C 521.72 252.59 516.86 253.04 512.07 253.92 C 500.24 238.11 488.03 222.59 476.10 206.86 C 466.70 194.20 456.58 182.09 447.54 169.17 C 458.63 155.35 469.52 141.36 480.54 127.48 Z"/> + <path fill-opacity="0.6197" stroke-opacity="0.6197" d=" M 373.10 783.67 C 390.18 802.89 407.31 822.08 424.17 841.49 C 410.02 862.72 396.01 884.05 382.12 905.45 C 374.93 897.37 368.34 888.78 361.11 880.75 C 362.03 869.43 363.76 858.20 365.06 846.93 C 367.76 825.84 370.01 804.70 373.10 783.67 Z"/> + <path fill-opacity="0.6157" stroke-opacity="0.6157" d=" M 398.47 387.18 C 430.37 389.52 462.25 392.21 494.11 395.06 C 507.28 424.63 520.52 454.18 533.57 483.80 C 528.28 485.95 522.52 485.07 516.98 485.08 C 504.66 484.88 492.32 485.08 480.02 484.26 C 467.69 483.86 455.35 484.30 443.02 483.80 C 438.32 483.76 433.07 482.84 429.06 485.94 C 429.91 485 430.70 484.02 431.53 483.07 C 420.71 452.72 409.39 422.55 398.65 392.18 C 398.54 390.51 398.50 388.85 398.47 387.18 Z"/> + <path fill-opacity="0.5844" stroke-opacity="0.5844" d=" M 429.06 485.94 C 433.07 482.84 438.32 483.76 443.02 483.80 C 455.35 484.30 467.69 483.86 480.02 484.26 C 492.32 485.08 504.66 484.88 516.98 485.08 C 522.52 485.07 528.28 485.95 533.57 483.80 C 539.79 490.34 548.27 494.09 555.36 499.59 C 547.53 515.61 539.53 531.54 531.63 547.53 C 524.45 551.24 516.61 553.33 509.10 556.22 C 484.10 565.46 458.83 573.99 433.99 583.64 C 425.55 557.83 415.89 532.41 407.01 506.74 C 414.29 499.73 421.71 492.88 429.06 485.94 Z"/> + <path fill-opacity="0.5844" stroke-opacity="0.5844" d=" M 487.69 66.69 C 506.58 55.63 525.98 45.47 544.95 34.54 C 550.76 41.24 556.83 47.69 562.76 54.28 C 565.32 56.80 565.60 60.52 566.26 63.85 C 573.05 98.77 580.17 133.62 586.97 168.53 C 578.90 175.81 570.40 182.60 562.41 189.96 C 537.31 168.90 511.90 148.19 486.59 127.38 C 482.75 124.41 483.90 118.96 483.75 114.73 C 485.05 98.72 486.82 82.73 487.69 66.69 Z"/> + <path fill-opacity="0.5216" stroke-opacity="0.5216" d=" M 512.07 253.92 C 516.86 253.04 521.72 252.59 526.52 251.76 C 537.09 261.81 548.06 271.42 558.82 281.26 C 560.14 282.51 561.34 283.91 562.33 285.44 C 569.52 301.98 576.13 318.78 583.48 335.24 C 569.63 344.96 555.01 353.54 540.85 362.81 C 530.10 369.71 519.35 376.60 508.59 383.48 C 504.06 386.41 499.26 389.01 495.27 392.70 C 495.36 390.43 495.24 388.17 494.97 385.93 C 491.67 361.24 488.58 336.52 485.40 311.82 C 484.20 301.89 482.68 291.99 481.84 282.02 C 486.53 276.57 491.08 270.99 495.64 265.43 C 500.73 261.09 506.49 257.58 512.07 253.92 Z"/> + <path fill-opacity="0.5138" stroke-opacity="0.5138" d=" M 436.25 736.30 C 436.78 734.49 437.35 732.71 437.80 730.89 C 437.78 732.79 437.53 734.80 438.22 736.64 C 441.14 739 444.70 740.31 448.01 742.02 C 462.68 749.32 477.27 756.77 491.94 764.07 C 498.79 767.56 505.82 770.74 512.43 774.71 C 501.34 792.40 490.14 810.02 479.01 827.69 C 463.85 832.35 448.92 837.79 433.68 842.17 C 430.49 842.09 427.33 841.75 424.17 841.49 C 407.31 822.08 390.18 802.89 373.10 783.67 C 371.42 781.07 370.03 778.30 368.57 775.58 C 375.26 768.49 381.61 761.08 388.25 753.93 C 404.13 747.73 420.39 742.54 436.25 736.30 Z"/> + <path fill-opacity="0.502" stroke-opacity="0.502" d=" M 424.17 841.49 C 427.33 841.75 430.49 842.09 433.68 842.17 C 443.79 868.94 454.79 895.37 465.16 922.04 C 460.56 929.15 456.37 936.52 451.83 943.68 C 429.14 944.14 406.45 944.27 383.76 944.30 C 383.24 931.35 382.47 918.41 382.12 905.45 C 396.01 884.05 410.02 862.72 424.17 841.49 Z"/> + <path fill-opacity="0.502" stroke-opacity="0.502" d=" M 509.10 556.22 C 516.61 553.33 524.45 551.24 531.63 547.53 C 531.09 554.71 532.47 561.85 532.51 569.03 C 533.82 590.96 534.99 612.90 536.37 634.83 C 536.49 638.03 536.17 641.23 535.71 644.41 C 511.02 648.82 486.33 653.26 461.60 657.44 C 458.13 658.12 453.60 658.08 451.97 661.90 C 451.93 660.27 451.82 658.56 450.52 657.44 C 438.16 644.78 425.37 632.53 413.32 619.59 C 420.28 607.64 427.09 595.62 433.99 583.64 C 458.83 573.99 484.10 565.46 509.10 556.22 Z"/> + <path fill-opacity="0.4589" stroke-opacity="0.4589" d=" M 383.76 944.30 C 406.45 944.27 429.14 944.14 451.83 943.68 C 458.08 952.20 465.10 960.12 471.58 968.46 C 473.14 970.27 472.78 972.79 472.87 975.02 C 472.77 983.34 472.82 991.67 472.82 1000 L 381.76 1000 C 381.80 982.08 381.69 964.15 381.81 946.23 C 382.45 945.58 383.10 944.93 383.76 944.30 Z"/> + <path fill-opacity="0.451" stroke-opacity="0.451" d=" M 536.37 634.83 C 536.58 638.08 536.48 641.43 537.46 644.58 C 539.62 647.76 543.06 649.85 545.15 653.11 C 545.66 658.17 544.69 663.26 544.85 668.34 C 544.21 689.37 543.11 710.37 542.39 731.40 C 534.92 744.44 528.94 758.25 522.46 771.80 C 519.13 772.81 515.79 773.78 512.43 774.71 C 505.82 770.74 498.79 767.56 491.94 764.07 C 477.27 756.77 462.68 749.32 448.01 742.02 C 444.70 740.31 441.14 739 438.22 736.64 C 437.53 734.80 437.78 732.79 437.80 730.89 C 442.57 707.90 447.59 684.96 451.97 661.90 C 453.60 658.08 458.13 658.12 461.60 657.44 C 486.33 653.26 511.02 648.82 535.71 644.41 C 536.17 641.23 536.49 638.03 536.37 634.83 Z"/> + <path fill-opacity="0.4471" stroke-opacity="0.4471" d=" M 583.48 335.24 C 584.46 336.34 585.53 337.35 586.52 338.44 C 588.74 340.41 587.58 343.67 587.71 346.25 C 584.34 395.33 580.99 444.42 577.57 493.49 C 574.88 494.46 572.34 495.77 569.64 496.68 C 564.91 497.79 560.10 498.51 555.36 499.59 C 548.27 494.09 539.79 490.34 533.57 483.80 C 520.52 454.18 507.28 424.63 494.11 395.06 C 494.40 394.47 494.98 393.29 495.27 392.70 C 499.26 389.01 504.06 386.41 508.59 383.48 C 519.35 376.60 530.10 369.71 540.85 362.81 C 555.01 353.54 569.63 344.96 583.48 335.24 Z"/> + <path fill-opacity="0.4393" stroke-opacity="0.4393" d=" M 433.68 842.17 C 448.92 837.79 463.85 832.35 479.01 827.69 C 488.83 848.96 499.05 870.04 508.51 891.47 C 493.97 901.52 479.45 911.63 465.16 922.04 C 454.79 895.37 443.79 868.94 433.68 842.17 Z"/> + <path fill-opacity="0.3961" stroke-opacity="0.3961" d=" M 548.99 0 L 752.49 0 C 751.57 1.16 751.04 2.54 750.61 3.94 C 750.16 5.19 749.66 6.42 749.13 7.64 C 719.08 25.92 689.52 45.01 659.60 63.50 C 656.73 65.18 653.97 67.02 651.37 69.08 C 655.42 91.72 659.79 114.31 664 136.92 C 664.77 141.83 666.66 146.76 665.62 151.78 C 651.11 157.78 637.30 165.39 622.97 171.81 C 610.97 170.72 598.96 169.67 586.97 168.53 C 580.17 133.62 573.05 98.77 566.26 63.85 C 565.60 60.52 565.32 56.80 562.76 54.28 C 556.83 47.69 550.76 41.24 544.95 34.54 C 546.25 23.02 548.07 11.56 548.99 0 Z"/> + <path fill-opacity="0.3687" stroke-opacity="0.3687" d=" M 586.97 168.53 C 598.96 169.67 610.97 170.72 622.97 171.81 C 633.32 193.14 643.74 214.44 653.61 235.98 C 648.65 244.69 642.86 252.90 637.62 261.44 C 617.19 268.02 596.43 273.61 575.89 279.86 C 571.29 281.46 565.79 281.59 562.33 285.44 C 561.34 283.91 560.14 282.51 558.82 281.26 C 548.06 271.42 537.09 261.81 526.52 251.76 C 538.52 231.18 550.38 210.51 562.41 189.96 C 570.40 182.60 578.90 175.81 586.97 168.53 Z"/> + <path fill-opacity="0.3412" stroke-opacity="0.3412" d=" M 512.43 774.71 C 515.79 773.78 519.13 772.81 522.46 771.80 C 527.25 776.63 532.88 780.51 538.16 784.78 C 551.94 795.69 565.68 806.65 579.53 817.48 C 583.79 820.92 588.31 824.07 592.20 827.94 C 592.18 829.33 592.15 830.72 592.12 832.13 C 590.98 839.36 589.97 846.61 588.75 853.84 C 575.55 867.75 562.90 882.18 549.54 895.94 C 535.74 896.31 522.21 892.68 508.51 891.47 C 499.05 870.04 488.83 848.96 479.01 827.69 C 490.14 810.02 501.34 792.40 512.43 774.71 Z"/> + <path fill-opacity="0.3334" stroke-opacity="0.3334" d=" M 508.51 891.47 C 522.21 892.68 535.74 896.31 549.54 895.94 C 550.96 909.71 554.66 923.17 556.88 936.84 C 557.08 938.56 557.22 940.29 557.38 942.04 C 547.38 951.07 536.31 958.85 526.01 967.53 C 508.78 968.54 491.54 969.34 474.31 970.32 C 473.64 980.19 474.22 990.10 474 1000 L 472.82 1000 C 472.82 991.67 472.77 983.34 472.87 975.02 C 472.78 972.79 473.14 970.27 471.58 968.46 C 465.10 960.12 458.08 952.20 451.83 943.68 C 456.37 936.52 460.56 929.15 465.16 922.04 C 479.45 911.63 493.97 901.52 508.51 891.47 Z"/> + <path fill-opacity="0.3216" stroke-opacity="0.3216" d=" M 575.89 279.86 C 596.43 273.61 617.19 268.02 637.62 261.44 C 649.11 279.16 662.99 295.22 674.57 312.89 C 669.49 320.50 664.96 328.47 659.86 336.06 C 653.09 339.62 646.32 343.23 639.31 346.27 C 631.42 347.71 623.67 344.91 615.87 344.16 C 607.08 343.27 598.47 341.13 589.67 340.37 C 588.99 342.32 588.24 344.25 587.71 346.25 C 587.58 343.67 588.74 340.41 586.52 338.44 C 585.53 337.35 584.46 336.34 583.48 335.24 C 576.13 318.78 569.52 301.98 562.33 285.44 C 565.79 281.59 571.29 281.46 575.89 279.86 Z"/> + <path fill-opacity="0.3138" stroke-opacity="0.3138" d=" M 589.67 340.37 C 598.47 341.13 607.08 343.27 615.87 344.16 C 623.67 344.91 631.42 347.71 639.31 346.27 C 639.01 352.18 641.28 357.74 642.65 363.39 C 651.70 398.56 660.94 433.68 670.10 468.83 C 671.32 473.15 672.40 477.53 673.10 481.98 C 671.85 483.92 670.76 485.95 669.63 487.95 C 638.97 490.28 608.24 491.42 577.57 493.49 C 580.99 444.42 584.34 395.33 587.71 346.25 C 588.24 344.25 588.99 342.32 589.67 340.37 Z"/> + <path fill-opacity="0.3059" stroke-opacity="0.3059" d=" M 474.31 970.32 C 491.54 969.34 508.78 968.54 526.01 967.53 C 528.79 978.42 531.84 989.24 535.09 1000 L 474 1000 C 474.22 990.10 473.64 980.19 474.31 970.32 Z"/> + <path fill-opacity="0.302" stroke-opacity="0.302" d=" M 555.36 499.59 C 560.10 498.51 564.91 497.79 569.64 496.68 C 591.15 547.16 611.72 598.03 633.23 648.51 C 632.96 649.01 632.42 650.02 632.14 650.52 C 628.14 651.22 624.08 651.24 620.05 651.15 C 608.68 650.98 597.35 652.06 585.99 652.11 C 572.75 652 559.51 652.48 546.31 653.29 C 546.11 658.33 545.82 663.38 544.85 668.34 C 544.69 663.26 545.66 658.17 545.15 653.11 C 543.06 649.85 539.62 647.76 537.46 644.58 C 536.48 641.43 536.58 638.08 536.37 634.83 C 534.99 612.90 533.82 590.96 532.51 569.03 C 532.47 561.85 531.09 554.71 531.63 547.53 C 539.53 531.54 547.53 515.61 555.36 499.59 Z"/> + <path fill-opacity="0.2902" stroke-opacity="0.2902" d=" M 659.60 63.50 C 689.52 45.01 719.08 25.92 749.13 7.64 C 746.17 14.12 744.09 20.95 741.61 27.61 C 726.43 69.59 711.39 111.61 696.08 153.54 C 685.90 153.39 675.80 150.55 665.62 151.78 C 666.66 146.76 664.77 141.83 664 136.92 C 659.79 114.31 655.42 91.72 651.37 69.08 C 653.97 67.02 656.73 65.18 659.60 63.50 Z"/> + <path fill-opacity="0.2746" stroke-opacity="0.2746" d=" M 665.62 151.78 C 675.80 150.55 685.90 153.39 696.08 153.54 C 702.53 158.23 709.03 162.85 715.68 167.28 C 717.91 168.86 720.74 170.41 720.95 173.49 C 716.99 189.35 712.80 205.17 708.55 220.96 C 702.71 227.74 695.30 233.01 689.72 240.03 C 694.43 258.79 700.76 277.13 705.65 295.85 C 695.53 301.97 684.56 306.57 674.57 312.89 C 662.99 295.22 649.11 279.16 637.62 261.44 C 642.86 252.90 648.65 244.69 653.61 235.98 C 643.74 214.44 633.32 193.14 622.97 171.81 C 637.30 165.39 651.11 157.78 665.62 151.78 Z"/> + <path fill-opacity="0.2667" stroke-opacity="0.2667" d=" M 633.23 648.51 C 636.96 652.72 642.83 653.38 647.86 655.15 C 655.21 657.70 662.83 659.66 669.81 663.16 L 670.43 664.19 C 665.52 670.04 659.35 674.61 653.88 679.89 C 637.25 694.84 621.03 710.27 604.11 724.89 C 602.47 726.05 600.74 727.07 598.95 727.97 C 580.06 728.51 561.27 730.89 542.39 731.40 C 543.11 710.37 544.21 689.37 544.85 668.34 C 545.82 663.38 546.11 658.33 546.31 653.29 C 559.51 652.48 572.75 652 585.99 652.11 C 597.35 652.06 608.68 650.98 620.05 651.15 C 624.08 651.24 628.14 651.22 632.14 650.52 C 632.42 650.02 632.96 649.01 633.23 648.51 Z"/> + <path fill-opacity="0.2471" stroke-opacity="0.2471" d=" M 542.39 731.40 C 561.27 730.89 580.06 728.51 598.95 727.97 C 602.54 748.12 605.51 768.37 609.47 788.45 C 611.30 797.84 612.25 807.43 615.07 816.61 C 608.49 819.78 601.98 823.09 595.50 826.47 C 593.13 827.36 592.63 829.94 592.12 832.13 C 592.15 830.72 592.18 829.33 592.20 827.94 C 588.31 824.07 583.79 820.92 579.53 817.48 C 565.68 806.65 551.94 795.69 538.16 784.78 C 532.88 780.51 527.25 776.63 522.46 771.80 C 528.94 758.25 534.92 744.44 542.39 731.40 Z"/> + <path fill-opacity="0.2471" stroke-opacity="0.2471" d=" M 556.88 936.84 C 557.66 939.47 558.49 942.39 560.93 944 C 571.58 951.44 582.47 958.56 593.27 965.78 C 596.97 967.84 596.04 972.66 596.15 976.20 C 595.57 984.13 594.99 992.06 594.47 1000 L 535.09 1000 C 531.84 989.24 528.79 978.42 526.01 967.53 C 536.31 958.85 547.38 951.07 557.38 942.04 C 557.22 940.29 557.08 938.56 556.88 936.84 Z"/> + <path fill-opacity="0.2393" stroke-opacity="0.2393" d=" M 577.57 493.49 C 608.24 491.42 638.97 490.28 669.63 487.95 C 672.64 492.67 676.16 497.03 679.42 501.58 C 681.82 504.89 682.08 509.10 682.98 512.96 C 686.01 527.26 689.06 541.56 692.18 555.85 C 694.79 566.71 694.12 577.96 695.28 589 C 695.40 597.90 696.86 606.75 696.49 615.66 C 687.62 631.50 678.62 647.28 669.81 663.16 C 662.83 659.66 655.21 657.70 647.86 655.15 C 642.83 653.38 636.96 652.72 633.23 648.51 C 611.72 598.03 591.15 547.16 569.64 496.68 C 572.34 495.77 574.88 494.46 577.57 493.49 Z"/> + <path fill-opacity="0.2236" stroke-opacity="0.2236" d=" M 598.95 727.97 C 600.74 727.07 602.47 726.05 604.11 724.89 C 605.28 730.81 609.93 734.93 613.55 739.44 C 619.31 746.36 624.56 753.68 630.34 760.59 C 639.19 771.33 647.40 782.57 656.31 793.26 C 651.21 797.42 646.65 802.22 641.58 806.42 C 632.98 810.38 623.89 813.17 615.07 816.61 C 612.25 807.43 611.30 797.84 609.47 788.45 C 605.51 768.37 602.54 748.12 598.95 727.97 Z"/> + <path fill-opacity="0.2236" stroke-opacity="0.2236" d=" M 639.31 346.27 C 646.32 343.23 653.09 339.62 659.86 336.06 C 686.51 356.31 713.55 376.05 740.33 396.14 C 737.83 405.13 735.79 414.24 733.43 423.26 C 726.43 430.99 718.38 437.67 711.03 445.06 C 698.51 457.49 685.27 469.21 673.10 481.98 C 672.40 477.53 671.32 473.15 670.10 468.83 C 660.94 433.68 651.70 398.56 642.65 363.39 C 641.28 357.74 639.01 352.18 639.31 346.27 Z"/> + <path fill-opacity="0.204" stroke-opacity="0.204" d=" M 670.43 664.19 C 673.37 669.51 676.64 674.69 680.28 679.57 C 680.07 685.74 678.68 691.78 677.73 697.87 C 672.88 727.26 667.93 756.63 663.09 786.02 C 663.02 789.97 658.96 791.26 656.31 793.26 C 647.40 782.57 639.19 771.33 630.34 760.59 C 624.56 753.68 619.31 746.36 613.55 739.44 C 609.93 734.93 605.28 730.81 604.11 724.89 C 621.03 710.27 637.25 694.84 653.88 679.89 C 659.35 674.61 665.52 670.04 670.43 664.19 Z"/> + <path fill-opacity="0.204" stroke-opacity="0.204" d=" M 749.13 7.64 C 749.66 6.42 750.16 5.19 750.61 3.94 C 750.67 6.58 751.26 9.18 752.36 11.59 C 755.89 19.76 759.32 27.98 762.75 36.20 C 764.72 42.32 765.62 48.72 766.93 55.01 C 773.01 86.59 779.53 118.10 785.40 149.72 C 778.91 155.99 772.99 162.83 766.44 169.04 L 765.86 169.66 C 753.56 169.96 741.28 171.12 728.96 170.89 C 726.04 170.77 722.99 171.20 720.95 173.49 C 720.74 170.41 717.91 168.86 715.68 167.28 C 709.03 162.85 702.53 158.23 696.08 153.54 C 711.39 111.61 726.43 69.59 741.61 27.61 C 744.09 20.95 746.17 14.12 749.13 7.64 Z"/> + <path fill-opacity="0.1961" stroke-opacity="0.1961" d=" M 549.54 895.94 C 562.90 882.18 575.55 867.75 588.75 853.84 C 611.64 877.83 634.46 901.89 657.15 926.06 C 656.36 929.33 655.59 932.60 654.83 935.87 C 654.19 938.27 652.78 940.46 650.40 941.42 C 633.66 949.65 616.96 957.96 600.28 966.30 C 596.10 967.73 596.74 972.66 596.15 976.20 C 596.04 972.66 596.97 967.84 593.27 965.78 C 582.47 958.56 571.58 951.44 560.93 944 C 558.49 942.39 557.66 939.47 556.88 936.84 C 554.66 923.17 550.96 909.71 549.54 895.94 Z"/> + <path fill-opacity="0.1922" stroke-opacity="0.1922" d=" M 689.72 240.03 C 695.30 233.01 702.71 227.74 708.55 220.96 C 729.63 237.23 751.13 252.97 772.39 269.02 C 774.53 273.76 776.69 278.50 778.34 283.45 C 772.10 290.31 765.48 296.90 759.75 304.18 C 758.77 315.38 760.52 326.70 760.51 337.95 C 760.45 347.13 761.52 356.26 761.54 365.43 C 761.72 367.63 760.46 369.50 759.20 371.16 C 752.89 379.47 746.40 387.65 740.33 396.14 C 713.55 376.05 686.51 356.31 659.86 336.06 C 664.96 328.47 669.49 320.50 674.57 312.89 C 684.56 306.57 695.53 301.97 705.65 295.85 C 700.76 277.13 694.43 258.79 689.72 240.03 Z"/> + <path fill-opacity="0.1726" stroke-opacity="0.1726" d=" M 728.96 170.89 C 741.28 171.12 753.56 169.96 765.86 169.66 C 767.88 202.79 770.11 235.91 772.39 269.02 C 751.13 252.97 729.63 237.23 708.55 220.96 C 712.80 205.17 716.99 189.35 720.95 173.49 C 722.99 171.20 726.04 170.77 728.96 170.89 Z"/> + <path fill-opacity="0.1373" stroke-opacity="0.1373" d=" M 615.07 816.61 C 623.89 813.17 632.98 810.38 641.58 806.42 C 645.25 814.64 651.10 821.57 655.80 829.20 C 662.57 839.43 669.51 849.54 676.01 859.95 C 683.53 871.53 691.70 882.72 698.41 894.81 C 684.54 905.07 670.88 915.62 657.15 926.06 C 634.46 901.89 611.64 877.83 588.75 853.84 C 589.97 846.61 590.98 839.36 592.12 832.13 C 592.63 829.94 593.13 827.36 595.50 826.47 C 601.98 823.09 608.49 819.78 615.07 816.61 Z"/> + <path fill-opacity="0.1295" stroke-opacity="0.1295" d=" M 650.40 941.42 C 652.78 940.46 654.19 938.27 654.83 935.87 C 654.11 940.20 656.63 943.95 659.34 947.04 C 659.81 955.51 657.31 963.73 656.19 972.06 C 654.57 981.35 653.10 990.68 651.63 1000 L 594.47 1000 C 594.99 992.06 595.57 984.13 596.15 976.20 C 596.74 972.66 596.10 967.73 600.28 966.30 C 616.96 957.96 633.66 949.65 650.40 941.42 Z"/> + <path fill-opacity="0.1099" stroke-opacity="0.1099" d=" M 762.75 36.20 C 766.71 41.26 771.97 45.04 776.93 49.06 C 798.92 67.11 821.26 84.72 843.22 102.80 C 851.79 109.79 860.76 116.35 868.75 124.02 C 863.32 131.42 858.08 138.97 852.75 146.45 C 840.17 147.38 827.57 148.12 814.96 148.25 C 805.13 149.30 795.23 148.69 785.40 149.72 C 779.53 118.10 773.01 86.59 766.93 55.01 C 765.62 48.72 764.72 42.32 762.75 36.20 Z"/> + <path fill-opacity="0.1099" stroke-opacity="0.1099" d=" M 765.86 169.66 L 766.44 169.04 C 772.86 175.47 779.26 181.93 786.19 187.83 C 793.68 195.35 801.97 202.02 809.24 209.77 C 815.06 215.97 821.92 221.08 827.75 227.28 C 832.77 232.60 838.67 236.99 843.78 242.23 C 851.02 249.65 858.99 256.30 866.37 263.58 C 867.88 265.06 868.96 266.92 869.91 268.80 C 847.35 272.31 824.78 275.77 802.23 279.32 C 794.26 280.71 786.20 281.51 778.34 283.45 C 776.69 278.50 774.53 273.76 772.39 269.02 C 770.11 235.91 767.88 202.79 765.86 169.66 Z"/> + <path fill-opacity="0.0981" stroke-opacity="0.0981" d=" M 659.34 947.04 C 666.64 954.72 675.44 960.72 683.61 967.40 C 686.99 969.43 686.98 973.49 686.86 976.98 C 686.69 984.65 686.91 992.33 686.56 1000 L 651.63 1000 C 653.10 990.68 654.57 981.35 656.19 972.06 C 657.31 963.73 659.81 955.51 659.34 947.04 Z"/> + <path fill-opacity="0.0981" stroke-opacity="0.0981" d=" M 680.28 679.57 C 687.62 684.43 696.11 687.13 703.96 691.05 C 722.31 699.32 740.63 707.71 759 715.95 C 762.03 718.58 764.89 721.40 767.81 724.15 C 770.49 726.35 772.43 729.42 771.89 733.04 C 769.33 746.88 766.91 760.75 764.61 774.64 C 764.05 778.01 763.04 781.33 761.34 784.31 C 757.72 790.74 754.18 797.21 750.52 803.62 C 749.47 805.68 747.92 807.89 748.63 810.32 C 750.24 817.07 752.40 823.68 754.30 830.36 C 749.73 838.49 743.41 845.43 738.03 853.02 C 728.16 866.13 718.43 879.35 708.50 892.42 C 705.14 893.21 701.73 893.85 698.41 894.81 C 691.70 882.72 683.53 871.53 676.01 859.95 C 669.51 849.54 662.57 839.43 655.80 829.20 C 651.10 821.57 645.25 814.64 641.58 806.42 C 646.65 802.22 651.21 797.42 656.31 793.26 C 658.96 791.26 663.02 789.97 663.09 786.02 C 667.93 756.63 672.88 727.26 677.73 697.87 C 678.68 691.78 680.07 685.74 680.28 679.57 Z"/> + <path fill-opacity="0.0942" stroke-opacity="0.0942" d=" M 752.49 0 L 873.98 0 C 876.68 6.74 879 13.64 881.62 20.41 C 884.17 26.93 884.36 34.01 885.38 40.86 C 888.28 61.72 890.87 82.62 893.89 103.47 C 886.04 110.94 876.82 116.79 868.75 124.02 C 860.76 116.35 851.79 109.79 843.22 102.80 C 821.26 84.72 798.92 67.11 776.93 49.06 C 771.97 45.04 766.71 41.26 762.75 36.20 C 759.32 27.98 755.89 19.76 752.36 11.59 C 751.26 9.18 750.67 6.58 750.61 3.94 C 751.04 2.54 751.57 1.16 752.49 0 Z"/> + <path fill-opacity="0.0902" stroke-opacity="0.0902" d=" M 814.96 148.25 C 827.57 148.12 840.17 147.38 852.75 146.45 C 858.94 167.78 866.25 188.79 873.07 209.93 C 878.63 227.75 884.77 245.39 890.20 263.25 C 889.15 265.06 888.17 266.92 887.29 268.81 C 881.49 268.88 875.70 268.56 869.91 268.80 C 868.96 266.92 867.88 265.06 866.37 263.58 C 858.99 256.30 851.02 249.65 843.78 242.23 C 838.67 236.99 832.77 232.60 827.75 227.28 C 821.92 221.08 815.06 215.97 809.24 209.77 C 801.97 202.02 793.68 195.35 786.19 187.83 C 779.26 181.93 772.86 175.47 766.44 169.04 C 772.99 162.83 778.91 155.99 785.40 149.72 C 795.23 148.69 805.13 149.30 814.96 148.25 Z"/> + <path fill-opacity="0.0863" stroke-opacity="0.0863" d=" M 711.03 445.06 C 718.38 437.67 726.43 430.99 733.43 423.26 C 738.41 425.93 743.61 428.13 748.88 430.14 C 768.70 438.32 788.46 446.63 808.31 454.74 C 812.63 456.62 817.39 457.76 821.21 460.63 C 822.11 462.68 822.15 464.98 822.32 467.19 C 820.49 484.05 818.56 500.89 816.77 517.75 C 817 524.38 810.75 528.04 808.89 533.89 C 806.01 541.30 802.91 548.62 799.98 556.01 C 797.54 562.18 794.18 568.14 793.58 574.87 C 792.35 587.55 790.89 600.21 789.56 612.88 C 788.95 614.74 788.18 616.55 787.51 618.40 C 777.69 617.60 767.85 616.72 757.99 616.99 C 745.96 617.26 733.99 615.75 721.96 615.93 C 713.46 616.06 704.97 614.27 696.49 615.66 C 696.86 606.75 695.40 597.90 695.28 589 C 694.12 577.96 694.79 566.71 692.18 555.85 C 689.06 541.56 686.01 527.26 682.98 512.96 C 682.08 509.10 681.82 504.89 679.42 501.58 C 676.16 497.03 672.64 492.67 669.63 487.95 C 670.76 485.95 671.85 483.92 673.10 481.98 C 685.27 469.21 698.51 457.49 711.03 445.06 Z"/> + <path fill-opacity="0.0746" stroke-opacity="0.0746" d=" M 696.49 615.66 C 704.97 614.27 713.46 616.06 721.96 615.93 C 733.99 615.75 745.96 617.26 757.99 616.99 C 767.85 616.72 777.69 617.60 787.51 618.40 C 777.55 650.78 768.67 683.48 759 715.95 C 740.63 707.71 722.31 699.32 703.96 691.05 C 696.11 687.13 687.62 684.43 680.28 679.57 C 676.64 674.69 673.37 669.51 670.43 664.19 L 669.81 663.16 C 678.62 647.28 687.62 631.50 696.49 615.66 Z"/> + <path fill-opacity="0.0746" stroke-opacity="0.0746" d=" M 869.91 268.80 C 875.70 268.56 881.49 268.88 887.29 268.81 C 886.50 273.37 886.89 278.07 885.72 282.57 C 876.65 314.58 867.66 346.61 858.72 378.65 C 857.40 387.68 864.96 395.07 865.78 403.83 C 865.33 406.05 864.08 407.99 863.01 409.95 C 856.26 421.20 850.06 432.78 843.28 444.01 C 837.58 449.10 831.44 453.68 825.64 458.64 C 822.98 460.65 822.73 464.15 822.32 467.19 C 822.15 464.98 822.11 462.68 821.21 460.63 C 817.39 457.76 812.63 456.62 808.31 454.74 C 788.46 446.63 768.70 438.32 748.88 430.14 C 743.61 428.13 738.41 425.93 733.43 423.26 C 735.79 414.24 737.83 405.13 740.33 396.14 C 746.40 387.65 752.89 379.47 759.20 371.16 C 760.46 369.50 761.72 367.63 761.54 365.43 C 761.52 356.26 760.45 347.13 760.51 337.95 C 760.52 326.70 758.77 315.38 759.75 304.18 C 765.48 296.90 772.10 290.31 778.34 283.45 C 786.20 281.51 794.26 280.71 802.23 279.32 C 824.78 275.77 847.35 272.31 869.91 268.80 Z"/> + <path fill-opacity="0.0667" stroke-opacity="0.0667" d=" M 698.41 894.81 C 701.73 893.85 705.14 893.21 708.50 892.42 C 713.85 898.11 719.92 903.07 725.25 908.79 C 732.04 916.01 739.89 922.12 746.75 929.26 C 752.61 935.29 758.94 940.86 764.30 947.36 C 758.51 952.88 752.97 958.67 746.93 963.92 C 743.30 967.28 739.36 970.38 736.29 974.28 C 734.56 976.45 734.77 979.39 734.68 982.01 C 734.75 988 734.87 994 734.71 1000 L 686.56 1000 C 686.91 992.33 686.69 984.65 686.86 976.98 C 686.98 973.49 686.99 969.43 683.61 967.40 C 675.44 960.72 666.64 954.72 659.34 947.04 C 656.63 943.95 654.11 940.20 654.83 935.87 C 655.59 932.60 656.36 929.33 657.15 926.06 C 670.88 915.62 684.54 905.07 698.41 894.81 Z"/> + <path fill-opacity="0.0471" stroke-opacity="0.0471" d=" M 787.51 618.40 C 788.18 616.55 788.95 614.74 789.56 612.88 C 789.88 614.38 790.15 615.94 790.82 617.36 C 794.07 619.90 798.13 621.09 801.67 623.19 C 805.40 628.31 808.55 633.82 811.83 639.23 C 817.87 649.15 824.12 658.93 830.19 668.84 C 833.45 674.34 837.55 679.47 839.28 685.74 C 836.01 694.64 832.64 703.52 829.63 712.52 C 825.16 716.10 819.26 716.46 813.95 717.96 C 801.60 721.33 789.17 724.40 776.82 727.73 C 774 728.09 772.74 730.65 771.89 733.04 C 772.43 729.42 770.49 726.35 767.81 724.15 C 764.89 721.40 762.03 718.58 759 715.95 C 768.67 683.48 777.55 650.78 787.51 618.40 Z"/> + <path fill-opacity="0.0432" stroke-opacity="0.0432" d=" M 754.30 830.36 C 760.41 835.62 767.69 839.19 774.38 843.62 C 793.35 855.31 812.26 867.09 831.20 878.84 C 834.71 881.16 839.88 882.84 840.16 887.80 C 835.77 902.44 832.15 917.30 828.05 932.03 C 826.65 937.67 821.99 941.47 818.08 945.42 C 808.76 946.55 799.37 945.61 790.03 946.14 C 781.47 946.93 772.87 946.89 764.30 947.36 C 758.94 940.86 752.61 935.29 746.75 929.26 C 739.89 922.12 732.04 916.01 725.25 908.79 C 719.92 903.07 713.85 898.11 708.50 892.42 C 718.43 879.35 728.16 866.13 738.03 853.02 C 743.41 845.43 749.73 838.49 754.30 830.36 Z"/> + <path fill-opacity="0.0353" stroke-opacity="0.0353" d=" M 808.89 533.89 C 810.75 528.04 817 524.38 816.77 517.75 C 816.73 520.32 817.11 522.87 817.56 525.40 C 832.54 532.40 848.09 538.17 863.22 544.85 C 865.98 545.63 865.90 548.79 866.30 551.10 C 862.94 566.99 860.24 583 856.85 598.88 C 856.09 601.52 854.54 604.04 851.66 604.67 C 838.22 609.05 824.97 613.99 811.60 618.56 C 808.12 619.72 804.84 621.37 801.67 623.19 C 798.13 621.09 794.07 619.90 790.82 617.36 C 790.15 615.94 789.88 614.38 789.56 612.88 C 790.89 600.21 792.35 587.55 793.58 574.87 C 794.18 568.14 797.54 562.18 799.98 556.01 C 802.91 548.62 806.01 541.30 808.89 533.89 Z"/> + <path fill-opacity="0.0314" stroke-opacity="0.0314" d=" M 893.89 103.47 C 906.72 109.97 920.98 112.62 934.39 117.61 C 947.25 122.33 960.45 126.10 973.36 130.67 C 974.09 136.90 973.52 143.23 974.75 149.42 C 975.16 156.15 978.35 164.36 973.07 169.95 C 950.88 194.15 929.29 218.90 907.14 243.13 C 901.51 249.85 894.98 255.86 890.20 263.25 C 884.77 245.39 878.63 227.75 873.07 209.93 C 866.25 188.79 858.94 167.78 852.75 146.45 C 858.08 138.97 863.32 131.42 868.75 124.02 C 876.82 116.79 886.04 110.94 893.89 103.47 Z"/> + <path fill-opacity="0.0275" stroke-opacity="0.0275" d=" M 790.03 946.14 C 799.37 945.61 808.76 946.55 818.08 945.42 C 817.60 963.61 818.21 981.81 817.75 1000 L 734.71 1000 C 734.87 994 734.75 988 734.68 982.01 C 734.77 979.39 734.56 976.45 736.29 974.28 C 739.36 970.38 743.30 967.28 746.93 963.92 C 752.97 958.67 758.51 952.88 764.30 947.36 C 772.87 946.89 781.47 946.93 790.03 946.14 Z"/> + <path fill-opacity="0.0236" stroke-opacity="0.0236" d=" M 873.98 0 L 1000 0 L 1000 103.37 C 993.93 110.15 987.92 117.01 981.22 123.19 C 978.82 125.72 975.31 128.07 975.22 131.91 C 975.04 137.75 975.28 143.60 974.75 149.42 C 973.52 143.23 974.09 136.90 973.36 130.67 C 960.45 126.10 947.25 122.33 934.39 117.61 C 920.98 112.62 906.72 109.97 893.89 103.47 C 890.87 82.62 888.28 61.72 885.38 40.86 C 884.36 34.01 884.17 26.93 881.62 20.41 C 879 13.64 876.68 6.74 873.98 0 Z"/> + <path fill-opacity="0.0197" stroke-opacity="0.0197" d=" M 813.95 717.96 C 819.26 716.46 825.16 716.10 829.63 712.52 C 832.23 717.98 837.20 721.57 841.62 725.46 C 855.50 738.57 869.89 751.14 883.88 764.14 C 887.48 767.46 892.20 770.22 893.70 775.19 C 895.08 779.49 895.87 783.95 896.79 788.37 C 897.04 790.36 897.79 792.67 896.47 794.46 C 894.23 797.83 891.15 800.52 888.69 803.72 C 885.29 807.93 883.06 812.88 880.64 817.67 C 871.47 834.90 862.59 852.27 853.59 869.60 C 851.55 873.40 849.91 877.61 846.52 880.46 C 844.06 882.58 841.54 884.78 840.16 887.80 C 839.88 882.84 834.71 881.16 831.20 878.84 C 812.26 867.09 793.35 855.31 774.38 843.62 C 767.69 839.19 760.41 835.62 754.30 830.36 C 752.40 823.68 750.24 817.07 748.63 810.32 C 747.92 807.89 749.47 805.68 750.52 803.62 C 754.18 797.21 757.72 790.74 761.34 784.31 C 763.04 781.33 764.05 778.01 764.61 774.64 C 766.91 760.75 769.33 746.88 771.89 733.04 C 772.74 730.65 774 728.09 776.82 727.73 C 789.17 724.40 801.60 721.33 813.95 717.96 Z"/> + <path fill-opacity="0.0197" stroke-opacity="0.0197" d=" M 825.64 458.64 C 831.44 453.68 837.58 449.10 843.28 444.01 C 848.20 449.37 853.71 454.12 859.06 459.03 C 878.31 476.08 896.94 493.83 916.28 510.78 C 920.39 514.58 920.49 520.85 919.86 526.02 C 918.54 530.85 915.41 536.24 910.06 537.19 C 896.89 539.99 883.68 542.68 870.57 545.70 C 867.74 546 866.93 548.78 866.30 551.10 C 865.90 548.79 865.98 545.63 863.22 544.85 C 848.09 538.17 832.54 532.40 817.56 525.40 C 817.11 522.87 816.73 520.32 816.77 517.75 C 818.56 500.89 820.49 484.05 822.32 467.19 C 822.73 464.15 822.98 460.65 825.64 458.64 Z"/> + <path fill-opacity="0.0157" stroke-opacity="0.0157" d=" M 851.66 604.67 C 854.54 604.04 856.09 601.52 856.85 598.88 C 856.82 602.45 857.75 606.09 860.32 608.70 C 865.38 614.29 870.41 619.92 875.17 625.79 C 881.34 633.49 888.28 640.56 894.26 648.42 C 892.01 651.58 888.48 653.35 885.26 655.34 C 874.38 662.07 863.58 668.92 852.86 675.89 C 848.21 678.98 842.80 681.24 839.28 685.74 C 837.55 679.47 833.45 674.34 830.19 668.84 C 824.12 658.93 817.87 649.15 811.83 639.23 C 808.55 633.82 805.40 628.31 801.67 623.19 C 804.84 621.37 808.12 619.72 811.60 618.56 C 824.97 613.99 838.22 609.05 851.66 604.67 Z"/> + </g> +</svg> diff --git a/third_party/webkit/PerformanceTests/MotionMark/resources/runner/lines.svg b/third_party/webkit/PerformanceTests/MotionMark/resources/runner/lines.svg new file mode 100644 index 0000000000..83458b8095 --- /dev/null +++ b/third_party/webkit/PerformanceTests/MotionMark/resources/runner/lines.svg @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright © 2016 Apple Inc. All rights reserved. --> +<svg viewBox="0 0 1052 1251" version="1.1" xmlns="http://www.w3.org/2000/svg"> + <g fill-opacity="0.5" fill="white"> + <polygon points="221.761719 0 223.761719 0 2.12833345 1250.36328 0.128333454 1250.36328"/> + <polygon points="261.761719 0 265.761719 0 44.1283335 1250.36328 40.1283335 1250.36328"/> + <polygon points="301.761719 0 307.761719 0 86.1283335 1250.36328 80.1283335 1250.36328"/> + <polygon points="341.761719 0 349.761719 0 128.128333 1250.36328 120.128333 1250.36328"/> + <polygon points="381.761719 0 391.761719 0 170.128333 1250.36328 160.128333 1250.36328"/> + <polygon points="421.761719 0 433.761719 0 212.128333 1250.36328 200.128333 1250.36328"/> + <polygon points="461.761719 0 475.761719 0 254.128333 1250.36328 240.128333 1250.36328"/> + <polygon points="501.761719 0 517.761719 0 296.128333 1250.36328 280.128333 1250.36328"/> + <polygon points="541.761719 0 559.761719 0 338.128333 1250.36328 320.128333 1250.36328"/> + <polygon points="581.761719 0 601.761719 0 380.128333 1250.36328 360.128333 1250.36328"/> + <polygon points="621.761719 0 643.761719 0 422.128333 1250.36328 400.128333 1250.36328"/> + <polygon points="661.761719 0 685.761719 0 464.128333 1250.36328 440.128333 1250.36328"/> + <polygon points="701.761719 0 727.761719 0 506.128333 1250.36328 480.128333 1250.36328"/> + <polygon points="741.761719 0 769.761719 0 548.128333 1250.36328 520.128333 1250.36328"/> + <polygon points="781.761719 0 811.761719 0 590.128333 1250.36328 560.128333 1250.36328"/> + <polygon points="821.761719 0 853.761719 0 632.128333 1250.36328 600.128333 1250.36328"/> + <polygon points="861.761719 0 895.761719 0 674.128333 1250.36328 640.128333 1250.36328"/> + <polygon points="901.761719 0 937.761719 0 716.128333 1250.36328 680.128333 1250.36328"/> + <polygon points="941.761719 0 979.76172 0 758.128333 1250.36328 720.128333 1250.36328"/> + <polygon points="981.76172 0 1021.76172 0 800.128333 1250.36328 760.128333 1250.36328"/> + </g> +</svg> diff --git a/third_party/webkit/PerformanceTests/MotionMark/resources/runner/logo.svg b/third_party/webkit/PerformanceTests/MotionMark/resources/runner/logo.svg new file mode 100644 index 0000000000..a7d0eaf375 --- /dev/null +++ b/third_party/webkit/PerformanceTests/MotionMark/resources/runner/logo.svg @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright © 2016 Apple Inc. All rights reserved. --> +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <symbol id="root" viewBox="0 0 6882 1698"> + <path d="M 1314 1681 L 1466 1681 L 1549 1282 C 1555 1254 1566 1229 1582 1205 C 1598 1181 1614 1162 1629 1147 C 1644 1132 1662 1119 1683 1108 C 1704 1097 1729 1092 1758 1092 C 1790 1092 1812 1100 1824 1117 C 1836 1134 1842 1154 1842 1177 C 1842 1197 1840 1219 1835 1241 C 1830 1263 1826 1283 1822 1301 L 1743 1680 L 1895 1680 L 1979 1277 C 1983 1257 1989 1237 2000 1215 C 2010 1193 2024 1173 2040 1155 C 2056 1137 2076 1122 2099 1110 C 2122 1098 2148 1092 2177 1092 C 2197 1092 2213 1095 2225 1101 C 2237 1107 2247 1114 2254 1124 C 2261 1133 2266 1144 2268 1156 C 2270 1168 2271 1180 2271 1191 C 2270 1208 2268 1224 2265 1238 C 2262 1253 2259 1264 2258 1272 L 2173 1680 L 2325 1680 L 2413 1240 C 2416 1228 2418 1213 2420 1197 C 2422 1181 2423 1167 2423 1154 C 2423 1098 2407 1054 2375 1021 C 2343 988 2294 972 2227 972 C 2179 972 2136 984 2098 1007 C 2060 1030 2025 1059 1994 1095 C 1984 1050 1963 1018 1931 1000 C 1899 982 1862 973 1819 973 C 1771 973 1727 983 1686 1004 C 1646 1025 1611 1054 1583 1091 L 1580 1088 L 1600 991 L 1456 991 L 1313 1680 L 1314 1681 Z" fill-opacity="0.6" fill="black"/> + <path d="M 2673 1426 C 2690 1410 2711 1399 2736 1391 C 2760 1383 2787 1379 2815 1377 C 2843 1375 2868 1373 2889 1372 C 2906 1370 2923 1367 2941 1363 C 2959 1359 2973 1351 2984 1340 L 2987 1343 C 2982 1376 2974 1407 2965 1436 C 2956 1465 2943 1490 2926 1511 C 2910 1532 2889 1549 2863 1562 C 2838 1574 2806 1581 2769 1581 C 2755 1581 2741 1579 2726 1576 C 2712 1573 2699 1568 2687 1561 C 2675 1554 2666 1545 2658 1534 C 2650 1523 2647 1509 2647 1492 C 2647 1464 2656 1442 2673 1426 L 2673 1426 Z M 3155 1237 L 3155 1237 C 3164 1198 3168 1163 3168 1133 C 3168 1121 3166 1105 3163 1087 C 3159 1069 3149 1051 3133 1034 C 3117 1017 3091 1003 3056 991 C 3021 979 2972 973 2910 973 C 2869 973 2831 977 2795 984 C 2759 992 2727 1004 2698 1023 C 2670 1041 2646 1065 2626 1094 C 2606 1123 2593 1159 2585 1201 L 2729 1201 C 2740 1158 2760 1130 2791 1115 C 2822 1100 2858 1093 2901 1093 C 2932 1093 2959 1099 2982 1110 C 3005 1121 3017 1143 3017 1176 C 3017 1202 3011 1223 2998 1239 C 2985 1255 2965 1265 2937 1266 C 2887 1270 2837 1274 2785 1278 C 2747 1281 2710 1286 2676 1295 C 2641 1304 2611 1318 2584 1336 C 2557 1355 2536 1378 2520 1407 C 2504 1436 2496 1472 2496 1514 C 2496 1544 2502 1571 2513 1594 C 2525 1617 2540 1636 2560 1651 C 2580 1666 2603 1678 2629 1686 C 2655 1694 2682 1698 2710 1698 C 2753 1698 2794 1691 2835 1677 C 2876 1663 2911 1641 2942 1610 C 2944 1637 2953 1658 2970 1674 C 2987 1690 3008 1698 3034 1698 C 3054 1698 3074 1696 3094 1692 C 3114 1688 3133 1684 3153 1679 L 3177 1570 C 3168 1571 3159 1572 3150 1575 C 3141 1577 3132 1578 3123 1578 C 3111 1578 3102 1575 3098 1570 C 3094 1565 3091 1557 3091 1547 C 3091 1537 3093 1527 3096 1515 L 3105 1479 L 3156 1235 L 3155 1237 Z" fill-opacity="0.6" fill="black"/> + <path d="M 3232 1681 L 3384 1681 L 3448 1376 C 3455 1341 3465 1308 3477 1277 C 3489 1246 3506 1218 3526 1194 C 3546 1170 3570 1151 3599 1137 C 3628 1123 3662 1116 3701 1116 C 3710 1116 3719 1116 3728 1117 C 3737 1118 3746 1119 3755 1121 L 3787 976 C 3775 974 3762 973 3750 973 C 3738 973 3726 972 3713 972 C 3689 972 3666 977 3644 986 C 3622 995 3602 1007 3583 1022 C 3564 1037 3547 1053 3532 1072 C 3516 1091 3503 1109 3493 1128 L 3490 1125 L 3518 990 L 3374 990 L 3231 1679 L 3232 1681 Z" fill-opacity="0.6" fill="black"/> + + <polygon fill-opacity="0.6" fill="black" points="3726 1681 3878 1681 3927 1446 4044 1346 4166 1681 4334 1681 4166 1245 4470 992 4278 992 3966 1270 3963 1268 4075 729 3923 729"/> + <polygon fill-opacity="0.1" fill="black" points="4915 1368 4961 1118 1429 1118 1457 986 6867 986"/> + + <polygon fill="black" points="4930 1298 4976 1048 1444 1048 1472 916 6882 916"/> + + <polygon fill="currentColor" points="1403 263 1257 263 965 1679 1118 1679"/> + <polygon fill-opacity="0.8" fill="currentColor" points="1007 263 930 263 639 1679 722 1679"/> + <polygon fill-opacity="0.6" fill="currentColor" points="653 263 618 263 326 1679 368 1679"/> + <polygon fill-opacity="0.4" fill="currentColor" points="305 263 291 263 0 1679 21 1679"/> + + <path d="M 1466 952 L 1618 952 L 1701 553 C 1707 525 1718 500 1734 476 C 1750 452 1766 433 1781 418 C 1796 403 1814 390 1835 379 C 1856 368 1881 363 1910 363 C 1942 363 1964 371 1976 388 C 1988 405 1994 425 1994 448 C 1994 468 1992 490 1987 512 C 1982 534 1978 554 1974 572 L 1895 951 L 2047 951 L 2131 548 C 2135 528 2141 508 2152 486 C 2162 464 2176 444 2192 426 C 2208 408 2228 393 2251 381 C 2274 369 2300 363 2329 363 C 2349 363 2365 366 2377 372 C 2389 378 2399 385 2406 395 C 2413 404 2418 415 2420 427 C 2422 439 2423 451 2423 462 C 2422 479 2420 495 2417 509 C 2414 524 2411 535 2410 543 L 2325 951 L 2477 951 L 2565 511 C 2568 499 2570 484 2572 468 C 2574 452 2575 438 2575 425 C 2575 369 2559 325 2527 292 C 2495 259 2446 243 2379 243 C 2331 243 2288 255 2250 278 C 2212 301 2177 330 2146 366 C 2136 321 2115 289 2083 271 C 2051 253 2014 244 1971 244 C 1923 244 1879 254 1838 275 C 1798 296 1763 325 1735 362 L 1732 359 L 1752 262 L 1608 262 L 1465 951 L 1466 952 Z" fill="black"/> + <path d="M 3180 415 C 3205 449 3218 491 3218 542 C 3218 577 3213 612 3204 649 C 3195 686 3180 719 3161 749 C 3141 779 3117 803 3088 822 C 3059 841 3025 851 2986 851 C 2931 851 2891 834 2865 800 C 2840 766 2827 724 2827 673 C 2827 638 2832 603 2841 566 C 2850 530 2865 496 2884 467 C 2904 437 2928 413 2957 393 C 2986 373 3020 364 3059 364 C 3114 364 3154 381 3180 415 L 3180 415 Z M 3141 938 L 3141 938 C 3189 916 3231 885 3265 847 C 3299 808 3325 763 3343 710 C 3361 658 3370 601 3370 541 C 3370 444 3344 371 3291 320 C 3239 270 3164 245 3068 245 C 3008 245 2954 257 2906 280 C 2858 303 2816 334 2782 373 C 2748 412 2721 457 2703 508 C 2684 559 2675 613 2675 670 C 2675 767 2701 841 2754 893 C 2806 945 2881 971 2977 971 C 3038 971 3093 960 3142 938 L 3141 938 Z" fill="black"/> + <path d="M 3620 263 L 3500 263 L 3476 376 L 3596 376 L 3517 753 C 3515 759 3513 770 3511 786 C 3509 802 3508 817 3508 830 C 3508 846 3510 862 3514 877 C 3518 893 3525 906 3535 918 C 3545 930 3559 940 3577 947 C 3595 954 3617 958 3645 958 C 3665 958 3685 957 3708 954 C 3730 951 3751 948 3771 943 L 3796 831 C 3781 835 3766 837 3753 837 C 3739 837 3727 838 3715 838 C 3692 838 3677 833 3670 824 C 3663 815 3660 802 3660 787 C 3660 779 3661 768 3664 755 C 3667 742 3670 727 3673 712 L 3744 375 L 3881 375 L 3905 262 L 3768 262 L 3811 55 L 3663 55 L 3620 262 L 3620 263 Z" fill="black"/> + <path d="M 4046 144 L 4197 144 L 4226 0 L 4075 0 L 4046 144 L 4046 144 Z M 3878 952 L 3878 952 L 4030 952 L 4173 263 L 4021 263 L 3878 952 L 3878 952 Z" fill="black"/> + <path d="M 4736 415 C 4761 449 4774 491 4774 542 C 4774 577 4769 612 4760 649 C 4751 686 4736 719 4717 749 C 4697 779 4673 803 4644 822 C 4615 841 4581 851 4542 851 C 4487 851 4447 834 4421 800 C 4396 766 4383 724 4383 673 C 4383 638 4388 603 4397 566 C 4406 530 4421 496 4440 467 C 4460 437 4484 413 4513 393 C 4542 373 4576 364 4615 364 C 4670 364 4710 381 4736 415 L 4736 415 Z M 4697 938 L 4697 938 C 4745 916 4787 885 4821 847 C 4855 808 4881 763 4899 710 C 4917 658 4926 601 4926 541 C 4926 444 4900 371 4847 320 C 4795 270 4720 245 4624 245 C 4564 245 4510 257 4462 280 C 4414 303 4372 334 4338 373 C 4304 412 4277 457 4259 508 C 4240 559 4231 613 4231 670 C 4231 767 4257 841 4310 893 C 4362 945 4437 971 4533 971 C 4594 971 4649 960 4698 938 L 4697 938 Z" fill="black"/> + <path d="M 4990 952 L 5142 952 L 5219 579 C 5225 551 5235 523 5248 497 C 5261 471 5276 449 5294 431 C 5313 412 5334 397 5357 384 C 5381 371 5407 365 5438 365 C 5466 365 5487 369 5501 377 C 5516 385 5526 395 5532 406 C 5538 417 5542 428 5542 439 C 5542 450 5543 458 5543 464 C 5543 474 5542 484 5540 495 C 5538 506 5535 517 5533 528 L 5445 953 L 5597 953 L 5689 513 C 5692 501 5693 486 5694 470 C 5695 454 5695 440 5695 427 C 5695 371 5679 327 5646 294 C 5614 261 5563 245 5493 245 C 5445 245 5400 256 5359 277 C 5318 298 5283 328 5256 366 L 5253 363 L 5274 263 L 5131 263 L 4988 952 L 4990 952 Z" fill="black"/> + </symbol> +</svg> diff --git a/third_party/webkit/PerformanceTests/MotionMark/resources/runner/tests.js b/third_party/webkit/PerformanceTests/MotionMark/resources/runner/tests.js new file mode 100644 index 0000000000..aa938c5189 --- /dev/null +++ b/third_party/webkit/PerformanceTests/MotionMark/resources/runner/tests.js @@ -0,0 +1,81 @@ +var Headers = { + testName: [ + { + title: "<span onclick='benchmarkController.showDebugInfo()'>" + Strings.text.testName + "</span>", + text: Strings.text.testName + } + ], + score: [ + { + title: Strings.text.score, + text: Strings.json.score + } + ], + details: [ + { + title: " ", + text: function(data) { + var bootstrap = data[Strings.json.complexity][Strings.json.bootstrap]; + return "<span>±" + (Statistics.largestDeviationPercentage(bootstrap.confidenceLow, bootstrap.median, bootstrap.confidenceHigh) * 100).toFixed(2) + "%</span>"; + } + } + ] +}; + +var Suite = function(name, tests) { + this.name = name; + this.tests = tests; +}; + +var Suites = []; + +Suites.push(new Suite("Animometer", + [ + { + url: "master/multiply.html", + name: "Multiply" + }, + { + url: "master/canvas-stage.html?pathType=arcs", + name: "Canvas Arcs" + }, + { + url: "master/leaves.html", + name: "Leaves" + }, + { + url: "master/canvas-stage.html?pathType=linePath", + name: "Paths" + }, + { + url: "master/canvas-stage.html?pathType=line&lineCap=square", + name: "Canvas Lines" + }, + { + url: "master/focus.html", + name: "Focus" + }, + { + url: "master/image-data.html", + name: "Images" + }, + { + url: "master/text.html", + name: "Design" + }, + { + url: "master/svg-particles.html", + name: "Suits" + }, + ] +)); + +function suiteFromName(name) +{ + return Suites.find(function(suite) { return suite.name == name; }); +} + +function testFromName(suite, name) +{ + return suite.tests.find(function(test) { return test.name == name; }); +} diff --git a/third_party/webkit/PerformanceTests/MotionMark/resources/statistics.js b/third_party/webkit/PerformanceTests/MotionMark/resources/statistics.js new file mode 100644 index 0000000000..9322a797b6 --- /dev/null +++ b/third_party/webkit/PerformanceTests/MotionMark/resources/statistics.js @@ -0,0 +1,397 @@ +Pseudo = +{ + initialRandomSeed: 49734321, + randomSeed: 49734321, + + resetRandomSeed: function() + { + Pseudo.randomSeed = Pseudo.initialRandomSeed; + }, + + random: function() + { + var randomSeed = Pseudo.randomSeed; + randomSeed = ((randomSeed + 0x7ed55d16) + (randomSeed << 12)) & 0xffffffff; + randomSeed = ((randomSeed ^ 0xc761c23c) ^ (randomSeed >>> 19)) & 0xffffffff; + randomSeed = ((randomSeed + 0x165667b1) + (randomSeed << 5)) & 0xffffffff; + randomSeed = ((randomSeed + 0xd3a2646c) ^ (randomSeed << 9)) & 0xffffffff; + randomSeed = ((randomSeed + 0xfd7046c5) + (randomSeed << 3)) & 0xffffffff; + randomSeed = ((randomSeed ^ 0xb55a4f09) ^ (randomSeed >>> 16)) & 0xffffffff; + Pseudo.randomSeed = randomSeed; + return (randomSeed & 0xfffffff) / 0x10000000; + } +}; + +Statistics = +{ + sampleMean: function(numberOfSamples, sum) + { + if (numberOfSamples < 1) + return 0; + return sum / numberOfSamples; + }, + + // With sum and sum of squares, we can compute the sample standard deviation in O(1). + // See https://rniwa.com/2012-11-10/sample-standard-deviation-in-terms-of-sum-and-square-sum-of-samples/ + unbiasedSampleStandardDeviation: function(numberOfSamples, sum, squareSum) + { + if (numberOfSamples < 2) + return 0; + return Math.sqrt((squareSum - sum * sum / numberOfSamples) / (numberOfSamples - 1)); + }, + + geometricMean: function(values) + { + if (!values.length) + return 0; + var roots = values.map(function(value) { return Math.pow(value, 1 / values.length); }) + return roots.reduce(function(a, b) { return a * b; }); + }, + + // Cumulative distribution function + cdf: function(value, mean, standardDeviation) + { + return 0.5 * (1 + Statistics.erf((value - mean) / (Math.sqrt(2 * standardDeviation * standardDeviation)))); + }, + + // Approximation of Gauss error function, Abramowitz and Stegun 7.1.26 + erf: function(value) + { + var sign = (value >= 0) ? 1 : -1; + value = Math.abs(value); + + var a1 = 0.254829592; + var a2 = -0.284496736; + var a3 = 1.421413741; + var a4 = -1.453152027; + var a5 = 1.061405429; + var p = 0.3275911; + + var t = 1.0 / (1.0 + p * value); + var y = 1.0 - (((((a5 * t + a4) * t) + a3) * t + a2) * t + a1) * t * Math.exp(-value * value); + return sign * y; + }, + + largestDeviationPercentage: function(low, mean, high) + { + return Math.max(Math.abs(low / mean - 1), (high / mean - 1)); + } +}; + +Experiment = Utilities.createClass( + function(includeConcern) + { + if (includeConcern) + this._maxHeap = Heap.createMaxHeap(Experiment.defaults.CONCERN_SIZE); + this.reset(); + }, { + + reset: function() + { + this._sum = 0; + this._squareSum = 0; + this._numberOfSamples = 0; + if (this._maxHeap) + this._maxHeap.init(); + }, + + get sampleCount() + { + return this._numberOfSamples; + }, + + sample: function(value) + { + this._sum += value; + this._squareSum += value * value; + if (this._maxHeap) + this._maxHeap.push(value); + ++this._numberOfSamples; + }, + + mean: function() + { + return Statistics.sampleMean(this._numberOfSamples, this._sum); + }, + + standardDeviation: function() + { + return Statistics.unbiasedSampleStandardDeviation(this._numberOfSamples, this._sum, this._squareSum); + }, + + cdf: function(value) + { + return Statistics.cdf(value, this.mean(), this.standardDeviation()); + }, + + percentage: function() + { + var mean = this.mean(); + return mean ? this.standardDeviation() * 100 / mean : 0; + }, + + concern: function(percentage) + { + if (!this._maxHeap) + return this.mean(); + + var size = Math.ceil(this._numberOfSamples * percentage / 100); + var values = this._maxHeap.values(size); + return values.length ? values.reduce(function(a, b) { return a + b; }) / values.length : 0; + }, + + score: function(percentage) + { + return Statistics.geometricMean([this.mean(), Math.max(this.concern(percentage), 1)]); + } +}); + +Experiment.defaults = +{ + CONCERN: 5, + CONCERN_SIZE: 100, +}; + +Regression = Utilities.createClass( + function(samples, getComplexity, getFrameLength, startIndex, endIndex, options) + { + var desiredFrameLength = options.desiredFrameLength || 1000/60; + var bestProfile; + + if (!options.preferredProfile || options.preferredProfile == Strings.json.profiles.slope) { + var slope = this._calculateRegression(samples, getComplexity, getFrameLength, startIndex, endIndex, { + shouldClip: true, + s1: desiredFrameLength, + t1: 0 + }); + if (!bestProfile || slope.error < bestProfile.error) { + bestProfile = slope; + this.profile = Strings.json.profiles.slope; + } + } + if (!options.preferredProfile || options.preferredProfile == Strings.json.profiles.flat) { + var flat = this._calculateRegression(samples, getComplexity, getFrameLength, startIndex, endIndex, { + shouldClip: true, + s1: desiredFrameLength, + t1: 0, + t2: 0 + }); + + if (!bestProfile || flat.error < bestProfile.error) { + bestProfile = flat; + this.profile = Strings.json.profiles.flat; + } + } + + this.startIndex = Math.min(startIndex, endIndex); + this.endIndex = Math.max(startIndex, endIndex); + + this.complexity = bestProfile.complexity; + this.s1 = bestProfile.s1; + this.t1 = bestProfile.t1; + this.s2 = bestProfile.s2; + this.t2 = bestProfile.t2; + this.stdev1 = bestProfile.stdev1; + this.stdev2 = bestProfile.stdev2; + this.n1 = bestProfile.n1; + this.n2 = bestProfile.n2; + this.error = bestProfile.error; + }, { + + valueAt: function(complexity) + { + if (this.n1 == 1 || complexity > this.complexity) + return this.s2 + this.t2 * complexity; + return this.s1 + this.t1 * complexity; + }, + + // A generic two-segment piecewise regression calculator. Based on Kundu/Ubhaya + // + // Minimize sum of (y - y')^2 + // where y = s1 + t1*x + // y = s2 + t2*x + // y' = s1 + t1*x' = s2 + t2*x' if x_0 <= x' <= x_n + // + // Allows for fixing s1, t1, s2, t2 + // + // x is assumed to be complexity, y is frame length. Can be used for pure complexity-FPS + // analysis or for ramp controllers since complexity monotonically decreases with time. + _calculateRegression: function(samples, getComplexity, getFrameLength, startIndex, endIndex, options) + { + if (startIndex == endIndex) { + // Only one sample point; we can't calculate any regression. + var x = getComplexity(samples, startIndex); + return { + complexity: x, + s1: x, + t1: 0, + s2: x, + t2: 0, + error1: 0, + error2: 0 + }; + } + + // x is expected to increase in complexity + var iterationDirection = endIndex > startIndex ? 1 : -1; + var lowComplexity = getComplexity(samples, startIndex); + var highComplexity = getComplexity(samples, endIndex); + var a1 = 0, b1 = 0, c1 = 0, d1 = 0, h1 = 0, k1 = 0; + var a2 = 0, b2 = 0, c2 = 0, d2 = 0, h2 = 0, k2 = 0; + + // Iterate from low to high complexity + for (var i = startIndex; iterationDirection * (endIndex - i) > -1; i += iterationDirection) { + var x = getComplexity(samples, i); + var y = getFrameLength(samples, i); + a2 += 1; + b2 += x; + c2 += x * x; + d2 += y; + h2 += y * x; + k2 += y * y; + } + + var s1_best, t1_best, s2_best, t2_best, n1_best, n2_best, error1_best, error2_best, x_best, x_prime; + + function setBest(s1, t1, error1, s2, t2, error2, splitIndex, x_prime, x) + { + s1_best = s1; + t1_best = t1; + error1_best = error1; + s2_best = s2; + t2_best = t2; + error2_best = error2; + // Number of samples included in the first segment, inclusive of splitIndex + n1_best = iterationDirection * (splitIndex - startIndex) + 1; + // Number of samples included in the second segment + n2_best = iterationDirection * (endIndex - splitIndex); + if (!options.shouldClip || (x_prime >= lowComplexity && x_prime <= highComplexity)) + x_best = x_prime; + else { + // Discontinuous piecewise regression + x_best = x; + } + } + + // Iterate from startIndex to endIndex - 1, inclusive + for (var i = startIndex; iterationDirection * (endIndex - i) > 0; i += iterationDirection) { + var x = getComplexity(samples, i); + var y = getFrameLength(samples, i); + var xx = x * x; + var yx = y * x; + var yy = y * y; + // a1, b1, etc. is sum from startIndex to i, inclusive + a1 += 1; + b1 += x; + c1 += xx; + d1 += y; + h1 += yx; + k1 += yy; + // a2, b2, etc. is sum from i+1 to endIndex, inclusive + a2 -= 1; + b2 -= x; + c2 -= xx; + d2 -= y; + h2 -= yx; + k2 -= yy; + + var A = c1*d1 - b1*h1; + var B = a1*h1 - b1*d1; + var C = a1*c1 - b1*b1; + var D = c2*d2 - b2*h2; + var E = a2*h2 - b2*d2; + var F = a2*c2 - b2*b2; + var s1 = options.s1 !== undefined ? options.s1 : (A / C); + var t1 = options.t1 !== undefined ? options.t1 : (B / C); + var s2 = options.s2 !== undefined ? options.s2 : (D / F); + var t2 = options.t2 !== undefined ? options.t2 : (E / F); + // Assumes that the two segments meet + var x_prime = (s1 - s2) / (t2 - t1); + + var error1 = (k1 + a1*s1*s1 + c1*t1*t1 - 2*d1*s1 - 2*h1*t1 + 2*b1*s1*t1) || Number.MAX_VALUE; + var error2 = (k2 + a2*s2*s2 + c2*t2*t2 - 2*d2*s2 - 2*h2*t2 + 2*b2*s2*t2) || Number.MAX_VALUE; + + if (i == startIndex) { + setBest(s1, t1, error1, s2, t2, error2, i, x_prime, x); + continue; + } + + if (C == 0 || F == 0) + continue; + + // Projected point is not between this and the next sample + if (x_prime > getComplexity(samples, i + iterationDirection) || x_prime < x) { + // Calculate lambda, which divides the weight of this sample between the two lines + + // These values remove the influence of this sample + var I = c1 - 2*b1*x + a1*xx; + var H = C - I; + var G = A + B*x - C*y; + + var J = D + E*x - F*y; + var K = c2 - 2*b2*x + a2*xx; + + var lambda = (G*F + G*K - H*J) / (I*J + G*K); + if (lambda > 0 && lambda < 1) { + var lambda1 = 1 - lambda; + s1 = options.s1 !== undefined ? options.s1 : ((A - lambda1*(-h1*x + d1*xx + c1*y - b1*yx)) / (C - lambda1*I)); + t1 = options.t1 !== undefined ? options.t1 : ((B - lambda1*(h1 - d1*x - b1*y + a1*yx)) / (C - lambda1*I)); + s2 = options.s2 !== undefined ? options.s2 : ((D + lambda1*(-h2*x + d2*xx + c2*y - b2*yx)) / (F + lambda1*K)); + t2 = options.t2 !== undefined ? options.t2 : ((E + lambda1*(h2 - d2*x - b2*y + a2*yx)) / (F + lambda1*K)); + x_prime = (s1 - s2) / (t2 - t1); + + error1 = ((k1 + a1*s1*s1 + c1*t1*t1 - 2*d1*s1 - 2*h1*t1 + 2*b1*s1*t1) - lambda1 * Math.pow(y - (s1 + t1*x), 2)) || Number.MAX_VALUE; + error2 = ((k2 + a2*s2*s2 + c2*t2*t2 - 2*d2*s2 - 2*h2*t2 + 2*b2*s2*t2) + lambda1 * Math.pow(y - (s2 + t2*x), 2)) || Number.MAX_VALUE; + } else if (t1 != t2) + continue; + } + + if (error1 + error2 < error1_best + error2_best) + setBest(s1, t1, error1, s2, t2, error2, i, x_prime, x); + } + + return { + complexity: x_best, + s1: s1_best, + t1: t1_best, + stdev1: Math.sqrt(error1_best / n1_best), + s2: s2_best, + t2: t2_best, + stdev2: Math.sqrt(error2_best / n2_best), + error: error1_best + error2_best, + n1: n1_best, + n2: n2_best + }; + } +}); + +Utilities.extendObject(Regression, { + bootstrap: function(samples, iterationCount, processResample, confidencePercentage) + { + var sampleLength = samples.length; + var resample = new Array(sampleLength); + + var bootstrapEstimator = new Experiment; + var bootstrapData = new Array(iterationCount); + + Pseudo.resetRandomSeed(); + for (var i = 0; i < iterationCount; ++i) { + for (var j = 0; j < sampleLength; ++j) + resample[j] = samples[Math.floor(Pseudo.random() * sampleLength)]; + + var resampleResult = processResample(resample); + bootstrapEstimator.sample(resampleResult); + bootstrapData[i] = resampleResult; + } + + bootstrapData.sort(function(a, b) { return a - b; }); + return { + confidenceLow: bootstrapData[Math.round((iterationCount - 1) * (1 - confidencePercentage) / 2)], + confidenceHigh: bootstrapData[Math.round((iterationCount - 1) * (1 + confidencePercentage) / 2)], + median: bootstrapData[Math.round(iterationCount / 2)], + mean: bootstrapEstimator.mean(), + data: bootstrapData, + confidencePercentage: confidencePercentage + }; + } +}); diff --git a/third_party/webkit/PerformanceTests/MotionMark/resources/strings.js b/third_party/webkit/PerformanceTests/MotionMark/resources/strings.js new file mode 100644 index 0000000000..b58f67e991 --- /dev/null +++ b/third_party/webkit/PerformanceTests/MotionMark/resources/strings.js @@ -0,0 +1,51 @@ +var Strings = { + text: { + testName: "Test Name", + score: "Score" + }, + json: { + marks: "marks", + samplingStartTimeOffset: "Start sampling", + samplingEndTimeOffset: "End sampling", + + samples: "samples", + dataFieldMap: "dataFieldMap", + controller: "controller", + time: "time", + complexity: "complexity", + complexityAverage: "complexityAverage", + frameLength: "frameLength", + smoothedFrameLength: "smoothedFrameLength", + + result: "result", + configuration: "configuration", + score: "score", + scoreLowerBound: "scoreLowerBound", + scoreUpperBound: "scoreUpperBound", + bootstrap: "bootstrap", + measurements: { + average: "average", + concern: "concern", + stdev: "stdev", + percent: "percent" + }, + + regressions: { + startIndex: "startIndex", + endIndex: "endIndex", + segment1: "segment1", + segment2: "segment2", + profile: "profile" + }, + + profiles: { + slope: "slope", + flat: "flat" + }, + + results: { + iterations: "iterationsResults", + tests: "testsResults" + } + } +}; |